From a93f0a8d3d70df20c54fec0f1da8c944d582f04e Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Tue, 6 Dec 2022 11:37:19 +0000 Subject: [PATCH 1/9] removed zf --- lib/Zend/Acl.php | 1242 --- lib/Zend/Acl/Assert/Interface.php | 64 - lib/Zend/Acl/Exception.php | 36 - lib/Zend/Acl/Resource.php | 74 - lib/Zend/Acl/Resource/Interface.php | 37 - lib/Zend/Acl/Role.php | 74 - lib/Zend/Acl/Role/Interface.php | 37 - lib/Zend/Acl/Role/Registry.php | 271 - lib/Zend/Acl/Role/Registry/Exception.php | 36 - lib/Zend/Amf/Adobe/Auth.php | 136 - lib/Zend/Amf/Adobe/DbInspector.php | 103 - lib/Zend/Amf/Adobe/Introspector.php | 318 - lib/Zend/Amf/Auth/Abstract.php | 42 - lib/Zend/Amf/Constants.php | 87 - lib/Zend/Amf/Exception.php | 34 - lib/Zend/Amf/Parse/Amf0/Deserializer.php | 309 - lib/Zend/Amf/Parse/Amf0/Serializer.php | 362 - lib/Zend/Amf/Parse/Amf3/Deserializer.php | 425 - lib/Zend/Amf/Parse/Amf3/Serializer.php | 534 -- lib/Zend/Amf/Parse/Deserializer.php | 65 - lib/Zend/Amf/Parse/InputStream.php | 39 - lib/Zend/Amf/Parse/OutputStream.php | 49 - lib/Zend/Amf/Parse/Resource/MysqlResult.php | 70 - lib/Zend/Amf/Parse/Resource/MysqliResult.php | 128 - lib/Zend/Amf/Parse/Resource/Stream.php | 42 - lib/Zend/Amf/Parse/Serializer.php | 68 - lib/Zend/Amf/Parse/TypeLoader.php | 231 - lib/Zend/Amf/Request.php | 251 - lib/Zend/Amf/Request/Http.php | 80 - lib/Zend/Amf/Response.php | 205 - lib/Zend/Amf/Response/Http.php | 73 - lib/Zend/Amf/Server.php | 1048 --- lib/Zend/Amf/Server/Exception.php | 37 - lib/Zend/Amf/Util/BinaryStream.php | 297 - lib/Zend/Amf/Value/ByteArray.php | 58 - lib/Zend/Amf/Value/MessageBody.php | 182 - lib/Zend/Amf/Value/MessageHeader.php | 81 - .../Amf/Value/Messaging/AbstractMessage.php | 92 - .../Value/Messaging/AcknowledgeMessage.php | 60 - .../Amf/Value/Messaging/ArrayCollection.php | 35 - lib/Zend/Amf/Value/Messaging/AsyncMessage.php | 43 - .../Amf/Value/Messaging/CommandMessage.php | 119 - lib/Zend/Amf/Value/Messaging/ErrorMessage.php | 67 - .../Amf/Value/Messaging/RemotingMessage.php | 73 - lib/Zend/Amf/Value/TraitsInfo.php | 154 - lib/Zend/Application.php | 440 - lib/Zend/Application/Bootstrap/Bootstrap.php | 168 - .../Bootstrap/BootstrapAbstract.php | 784 -- .../Application/Bootstrap/Bootstrapper.php | 93 - lib/Zend/Application/Bootstrap/Exception.php | 38 - .../Bootstrap/ResourceBootstrapper.php | 95 - lib/Zend/Application/Exception.php | 38 - lib/Zend/Application/Module/Autoloader.php | 95 - lib/Zend/Application/Module/Bootstrap.php | 127 - .../Application/Resource/Cachemanager.php | 82 - lib/Zend/Application/Resource/Db.php | 198 - lib/Zend/Application/Resource/Dojo.php | 76 - lib/Zend/Application/Resource/Exception.php | 40 - .../Application/Resource/Frontcontroller.php | 179 - lib/Zend/Application/Resource/Layout.php | 70 - lib/Zend/Application/Resource/Locale.php | 117 - lib/Zend/Application/Resource/Log.php | 83 - lib/Zend/Application/Resource/Mail.php | 151 - lib/Zend/Application/Resource/Modules.php | 158 - lib/Zend/Application/Resource/Multidb.php | 210 - lib/Zend/Application/Resource/Navigation.php | 131 - lib/Zend/Application/Resource/Resource.php | 79 - .../Application/Resource/ResourceAbstract.php | 161 - lib/Zend/Application/Resource/Router.php | 87 - lib/Zend/Application/Resource/Session.php | 119 - lib/Zend/Application/Resource/Translate.php | 142 - lib/Zend/Application/Resource/Useragent.php | 72 - lib/Zend/Application/Resource/View.php | 86 - lib/Zend/Auth.php | 169 - lib/Zend/Auth/Adapter/DbTable.php | 560 -- lib/Zend/Auth/Adapter/Digest.php | 251 - lib/Zend/Auth/Adapter/Exception.php | 38 - lib/Zend/Auth/Adapter/Http.php | 868 -- .../Auth/Adapter/Http/Resolver/Exception.php | 40 - lib/Zend/Auth/Adapter/Http/Resolver/File.php | 166 - .../Auth/Adapter/Http/Resolver/Interface.php | 47 - lib/Zend/Auth/Adapter/Interface.php | 46 - lib/Zend/Auth/Adapter/Ldap.php | 531 -- lib/Zend/Auth/Adapter/OpenId.php | 283 - lib/Zend/Auth/Exception.php | 36 - lib/Zend/Auth/Result.php | 147 - lib/Zend/Auth/Storage/Exception.php | 38 - lib/Zend/Auth/Storage/Interface.php | 66 - lib/Zend/Auth/Storage/NonPersistent.php | 95 - lib/Zend/Auth/Storage/Session.php | 149 - lib/Zend/Barcode.php | 352 - lib/Zend/Barcode/Exception.php | 63 - lib/Zend/Barcode/Object/Code128.php | 395 - lib/Zend/Barcode/Object/Code25.php | 143 - lib/Zend/Barcode/Object/Code25interleaved.php | 179 - lib/Zend/Barcode/Object/Code39.php | 188 - lib/Zend/Barcode/Object/Ean13.php | 225 - lib/Zend/Barcode/Object/Ean2.php | 65 - lib/Zend/Barcode/Object/Ean5.php | 147 - lib/Zend/Barcode/Object/Ean8.php | 177 - lib/Zend/Barcode/Object/Error.php | 104 - lib/Zend/Barcode/Object/Exception.php | 35 - lib/Zend/Barcode/Object/Identcode.php | 95 - lib/Zend/Barcode/Object/Itf14.php | 49 - lib/Zend/Barcode/Object/Leitcode.php | 64 - lib/Zend/Barcode/Object/ObjectAbstract.php | 1440 --- lib/Zend/Barcode/Object/Planet.php | 62 - lib/Zend/Barcode/Object/Postnet.php | 136 - lib/Zend/Barcode/Object/Royalmail.php | 163 - lib/Zend/Barcode/Object/Upca.php | 172 - lib/Zend/Barcode/Object/Upce.php | 230 - lib/Zend/Barcode/Renderer/Exception.php | 35 - lib/Zend/Barcode/Renderer/Image.php | 475 - lib/Zend/Barcode/Renderer/Pdf.php | 245 - .../Barcode/Renderer/RendererAbstract.php | 551 -- lib/Zend/Barcode/Renderer/Svg.php | 385 - lib/Zend/Cache.php | 250 - lib/Zend/Cache/Backend.php | 288 - lib/Zend/Cache/Backend/Apc.php | 355 - lib/Zend/Cache/Backend/BlackHole.php | 250 - lib/Zend/Cache/Backend/ExtendedInterface.php | 126 - lib/Zend/Cache/Backend/File.php | 1037 --- lib/Zend/Cache/Backend/Interface.php | 99 - lib/Zend/Cache/Backend/Libmemcached.php | 484 - lib/Zend/Cache/Backend/Memcached.php | 509 -- lib/Zend/Cache/Backend/Sqlite.php | 678 -- lib/Zend/Cache/Backend/Static.php | 579 -- lib/Zend/Cache/Backend/Test.php | 416 - lib/Zend/Cache/Backend/TwoLevels.php | 548 -- lib/Zend/Cache/Backend/WinCache.php | 349 - lib/Zend/Cache/Backend/Xcache.php | 221 - lib/Zend/Cache/Backend/ZendPlatform.php | 317 - lib/Zend/Cache/Backend/ZendServer.php | 207 - lib/Zend/Cache/Backend/ZendServer/Disk.php | 101 - lib/Zend/Cache/Backend/ZendServer/ShMem.php | 101 - lib/Zend/Cache/Core.php | 765 -- lib/Zend/Cache/Exception.php | 32 - lib/Zend/Cache/Frontend/Capture.php | 88 - lib/Zend/Cache/Frontend/Class.php | 275 - lib/Zend/Cache/Frontend/File.php | 222 - lib/Zend/Cache/Frontend/Function.php | 179 - lib/Zend/Cache/Frontend/Output.php | 105 - lib/Zend/Cache/Frontend/Page.php | 404 - lib/Zend/Cache/Manager.php | 308 - lib/Zend/Captcha/Adapter.php | 76 - lib/Zend/Captcha/Base.php | 176 - lib/Zend/Captcha/Dumb.php | 75 - lib/Zend/Captcha/Exception.php | 37 - lib/Zend/Captcha/Figlet.php | 84 - lib/Zend/Captcha/Image.php | 625 -- lib/Zend/Captcha/ReCaptcha.php | 280 - lib/Zend/Captcha/Word.php | 419 - lib/Zend/Cloud/AbstractFactory.php | 67 - lib/Zend/Cloud/DocumentService/Adapter.php | 155 - .../Adapter/AbstractAdapter.php | 130 - .../DocumentService/Adapter/SimpleDb.php | 468 - .../Adapter/SimpleDb/Query.php | 175 - .../DocumentService/Adapter/WindowsAzure.php | 628 -- .../Adapter/WindowsAzure/Query.php | 171 - lib/Zend/Cloud/DocumentService/Document.php | 248 - .../Cloud/DocumentService/DocumentSet.php | 68 - lib/Zend/Cloud/DocumentService/Exception.php | 38 - lib/Zend/Cloud/DocumentService/Factory.php | 77 - lib/Zend/Cloud/DocumentService/Query.php | 191 - .../Cloud/DocumentService/QueryAdapter.php | 102 - lib/Zend/Cloud/Exception.php | 53 - lib/Zend/Cloud/Infrastructure/Adapter.php | 167 - .../Adapter/AbstractAdapter.php | 175 - lib/Zend/Cloud/Infrastructure/Adapter/Ec2.php | 496 -- .../Infrastructure/Adapter/Rackspace.php | 483 - lib/Zend/Cloud/Infrastructure/Exception.php | 25 - lib/Zend/Cloud/Infrastructure/Factory.php | 65 - lib/Zend/Cloud/Infrastructure/Image.php | 176 - lib/Zend/Cloud/Infrastructure/ImageList.php | 218 - lib/Zend/Cloud/Infrastructure/Instance.php | 320 - .../Cloud/Infrastructure/InstanceList.php | 219 - .../Cloud/OperationNotAvailableException.php | 34 - lib/Zend/Cloud/QueueService/Adapter.php | 146 - .../QueueService/Adapter/AbstractAdapter.php | 92 - lib/Zend/Cloud/QueueService/Adapter/Sqs.php | 278 - .../QueueService/Adapter/WindowsAzure.php | 343 - .../Cloud/QueueService/Adapter/ZendQueue.php | 301 - lib/Zend/Cloud/QueueService/Exception.php | 37 - lib/Zend/Cloud/QueueService/Factory.php | 71 - lib/Zend/Cloud/QueueService/Message.php | 60 - lib/Zend/Cloud/QueueService/MessageSet.php | 68 - lib/Zend/Cloud/StorageService/Adapter.php | 145 - .../StorageService/Adapter/FileSystem.php | 267 - .../StorageService/Adapter/Rackspace.php | 332 - lib/Zend/Cloud/StorageService/Adapter/S3.php | 332 - .../StorageService/Adapter/WindowsAzure.php | 443 - lib/Zend/Cloud/StorageService/Exception.php | 38 - lib/Zend/Cloud/StorageService/Factory.php | 70 - lib/Zend/CodeGenerator/Abstract.php | 147 - lib/Zend/CodeGenerator/Exception.php | 35 - lib/Zend/CodeGenerator/Php/Abstract.php | 97 - lib/Zend/CodeGenerator/Php/Body.php | 73 - lib/Zend/CodeGenerator/Php/Class.php | 618 -- lib/Zend/CodeGenerator/Php/Docblock.php | 227 - lib/Zend/CodeGenerator/Php/Docblock/Tag.php | 178 - .../Php/Docblock/Tag/License.php | 98 - .../CodeGenerator/Php/Docblock/Tag/Param.php | 128 - .../CodeGenerator/Php/Docblock/Tag/Return.php | 98 - lib/Zend/CodeGenerator/Php/Exception.php | 37 - lib/Zend/CodeGenerator/Php/File.php | 468 - .../CodeGenerator/Php/Member/Abstract.php | 222 - .../CodeGenerator/Php/Member/Container.php | 55 - lib/Zend/CodeGenerator/Php/Method.php | 236 - lib/Zend/CodeGenerator/Php/Parameter.php | 250 - .../Php/Parameter/DefaultValue.php | 60 - lib/Zend/CodeGenerator/Php/Property.php | 179 - .../Php/Property/DefaultValue.php | 325 - lib/Zend/Config.php | 484 - lib/Zend/Config/Exception.php | 33 - lib/Zend/Config/Ini.php | 309 - lib/Zend/Config/Json.php | 242 - lib/Zend/Config/Writer.php | 101 - lib/Zend/Config/Writer/Array.php | 55 - lib/Zend/Config/Writer/FileAbstract.php | 134 - lib/Zend/Config/Writer/Ini.php | 193 - lib/Zend/Config/Writer/Json.php | 106 - lib/Zend/Config/Writer/Xml.php | 127 - lib/Zend/Config/Writer/Yaml.php | 144 - lib/Zend/Config/Xml.php | 314 - lib/Zend/Config/Yaml.php | 415 - lib/Zend/Console/Getopt.php | 992 --- lib/Zend/Console/Getopt/Exception.php | 66 - lib/Zend/Controller/Action.php | 798 -- lib/Zend/Controller/Action/Exception.php | 38 - .../Controller/Action/Helper/Abstract.php | 156 - .../Controller/Action/Helper/ActionStack.php | 138 - .../Controller/Action/Helper/AjaxContext.php | 80 - .../Action/Helper/AutoComplete/Abstract.php | 149 - .../Action/Helper/AutoCompleteDojo.php | 87 - .../Helper/AutoCompleteScriptaculous.php | 82 - lib/Zend/Controller/Action/Helper/Cache.php | 289 - .../Action/Helper/ContextSwitch.php | 1394 --- .../Action/Helper/FlashMessenger.php | 313 - lib/Zend/Controller/Action/Helper/Json.php | 133 - .../Controller/Action/Helper/Redirector.php | 534 -- lib/Zend/Controller/Action/Helper/Url.php | 117 - .../Controller/Action/Helper/ViewRenderer.php | 1004 --- lib/Zend/Controller/Action/HelperBroker.php | 381 - .../Action/HelperBroker/PriorityStack.php | 280 - lib/Zend/Controller/Action/Interface.php | 69 - lib/Zend/Controller/Dispatcher/Abstract.php | 440 - lib/Zend/Controller/Dispatcher/Exception.php | 37 - lib/Zend/Controller/Dispatcher/Interface.php | 206 - lib/Zend/Controller/Dispatcher/Standard.php | 512 -- lib/Zend/Controller/Exception.php | 35 - lib/Zend/Controller/Front.php | 994 --- lib/Zend/Controller/Plugin/Abstract.php | 151 - lib/Zend/Controller/Plugin/ActionStack.php | 280 - lib/Zend/Controller/Plugin/Broker.php | 365 - lib/Zend/Controller/Plugin/ErrorHandler.php | 300 - lib/Zend/Controller/Plugin/PutHandler.php | 60 - lib/Zend/Controller/Request/Abstract.php | 356 - lib/Zend/Controller/Request/Apache404.php | 82 - lib/Zend/Controller/Request/Exception.php | 37 - lib/Zend/Controller/Request/Http.php | 1094 --- lib/Zend/Controller/Request/HttpTestCase.php | 277 - lib/Zend/Controller/Request/Simple.php | 55 - lib/Zend/Controller/Response/Abstract.php | 796 -- lib/Zend/Controller/Response/Cli.php | 68 - lib/Zend/Controller/Response/Exception.php | 36 - lib/Zend/Controller/Response/Http.php | 38 - lib/Zend/Controller/Response/HttpTestCase.php | 130 - lib/Zend/Controller/Router/Abstract.php | 178 - lib/Zend/Controller/Router/Exception.php | 35 - lib/Zend/Controller/Router/Interface.php | 123 - lib/Zend/Controller/Router/Rewrite.php | 555 -- lib/Zend/Controller/Router/Route.php | 605 -- lib/Zend/Controller/Router/Route/Abstract.php | 121 - lib/Zend/Controller/Router/Route/Chain.php | 229 - lib/Zend/Controller/Router/Route/Hostname.php | 380 - .../Controller/Router/Route/Interface.php | 39 - lib/Zend/Controller/Router/Route/Module.php | 323 - lib/Zend/Controller/Router/Route/Regex.php | 319 - lib/Zend/Controller/Router/Route/Static.php | 149 - lib/Zend/Crypt.php | 168 - lib/Zend/Crypt/DiffieHellman.php | 388 - lib/Zend/Crypt/DiffieHellman/Exception.php | 36 - lib/Zend/Crypt/Exception.php | 35 - lib/Zend/Crypt/Hmac.php | 182 - lib/Zend/Crypt/Hmac/Exception.php | 36 - lib/Zend/Crypt/Math.php | 102 - lib/Zend/Crypt/Math/BigInteger.php | 118 - lib/Zend/Crypt/Math/BigInteger/Bcmath.php | 227 - lib/Zend/Crypt/Math/BigInteger/Exception.php | 36 - lib/Zend/Crypt/Math/BigInteger/Gmp.php | 220 - lib/Zend/Crypt/Math/BigInteger/Interface.php | 51 - lib/Zend/Crypt/Math/Exception.php | 36 - lib/Zend/Crypt/Rsa.php | 338 - lib/Zend/Crypt/Rsa/Exception.php | 36 - lib/Zend/Crypt/Rsa/Key.php | 95 - lib/Zend/Crypt/Rsa/Key/Private.php | 75 - lib/Zend/Crypt/Rsa/Key/Public.php | 74 - lib/Zend/Currency.php | 902 -- lib/Zend/Currency/CurrencyInterface.php | 39 - lib/Zend/Currency/Exception.php | 37 - lib/Zend/Date.php | 4978 ----------- lib/Zend/Date/Cities.php | 322 - lib/Zend/Date/DateObject.php | 1096 --- lib/Zend/Date/Exception.php | 49 - lib/Zend/Db.php | 286 - lib/Zend/Db/Adapter/Abstract.php | 1280 --- lib/Zend/Db/Adapter/Db2.php | 840 -- lib/Zend/Db/Adapter/Db2/Exception.php | 45 - lib/Zend/Db/Adapter/Exception.php | 57 - lib/Zend/Db/Adapter/Mysqli.php | 556 -- lib/Zend/Db/Adapter/Mysqli/Exception.php | 40 - lib/Zend/Db/Adapter/Oracle.php | 643 -- lib/Zend/Db/Adapter/Oracle/Exception.php | 60 - lib/Zend/Db/Adapter/Pdo/Abstract.php | 402 - lib/Zend/Db/Adapter/Pdo/Ibm.php | 360 - lib/Zend/Db/Adapter/Pdo/Ibm/Db2.php | 228 - lib/Zend/Db/Adapter/Pdo/Ibm/Ids.php | 301 - lib/Zend/Db/Adapter/Pdo/Mssql.php | 423 - lib/Zend/Db/Adapter/Pdo/Mysql.php | 272 - lib/Zend/Db/Adapter/Pdo/Oci.php | 378 - lib/Zend/Db/Adapter/Pdo/Pgsql.php | 336 - lib/Zend/Db/Adapter/Pdo/Sqlite.php | 297 - lib/Zend/Db/Adapter/Sqlsrv.php | 679 -- lib/Zend/Db/Adapter/Sqlsrv/Exception.php | 63 - lib/Zend/Db/Exception.php | 35 - lib/Zend/Db/Expr.php | 77 - lib/Zend/Db/Profiler.php | 473 - lib/Zend/Db/Profiler/Exception.php | 40 - lib/Zend/Db/Profiler/Firebug.php | 161 - lib/Zend/Db/Profiler/Query.php | 213 - lib/Zend/Db/Select.php | 1358 --- lib/Zend/Db/Select/Exception.php | 39 - lib/Zend/Db/Statement.php | 488 - lib/Zend/Db/Statement/Db2.php | 360 - lib/Zend/Db/Statement/Db2/Exception.php | 58 - lib/Zend/Db/Statement/Exception.php | 56 - lib/Zend/Db/Statement/Interface.php | 203 - lib/Zend/Db/Statement/Mysqli.php | 362 - lib/Zend/Db/Statement/Mysqli/Exception.php | 38 - lib/Zend/Db/Statement/Oracle.php | 577 -- lib/Zend/Db/Statement/Oracle/Exception.php | 59 - lib/Zend/Db/Statement/Pdo.php | 440 - lib/Zend/Db/Statement/Pdo/Ibm.php | 94 - lib/Zend/Db/Statement/Pdo/Oci.php | 91 - lib/Zend/Db/Statement/Sqlsrv.php | 440 - lib/Zend/Db/Statement/Sqlsrv/Exception.php | 61 - lib/Zend/Db/Table.php | 79 - lib/Zend/Db/Table/Abstract.php | 1624 ---- lib/Zend/Db/Table/Definition.php | 131 - lib/Zend/Db/Table/Exception.php | 38 - lib/Zend/Db/Table/Row.php | 42 - lib/Zend/Db/Table/Row/Abstract.php | 1184 --- lib/Zend/Db/Table/Row/Exception.php | 38 - lib/Zend/Db/Table/Rowset.php | 43 - lib/Zend/Db/Table/Rowset/Abstract.php | 448 - lib/Zend/Db/Table/Rowset/Exception.php | 37 - lib/Zend/Db/Table/Select.php | 224 - lib/Zend/Db/Table/Select/Exception.php | 39 - lib/Zend/Debug.php | 113 - lib/Zend/Dojo.php | 87 - lib/Zend/Dojo/BuildLayer.php | 536 -- lib/Zend/Dojo/Data.php | 563 -- lib/Zend/Dojo/Exception.php | 35 - lib/Zend/Dojo/Form.php | 89 - .../Form/Decorator/AccordionContainer.php | 43 - .../Dojo/Form/Decorator/AccordionPane.php | 43 - .../Dojo/Form/Decorator/BorderContainer.php | 43 - lib/Zend/Dojo/Form/Decorator/ContentPane.php | 43 - .../Dojo/Form/Decorator/DijitContainer.php | 200 - lib/Zend/Dojo/Form/Decorator/DijitElement.php | 193 - lib/Zend/Dojo/Form/Decorator/DijitForm.php | 66 - .../Dojo/Form/Decorator/SplitContainer.php | 43 - .../Dojo/Form/Decorator/StackContainer.php | 44 - lib/Zend/Dojo/Form/Decorator/TabContainer.php | 43 - lib/Zend/Dojo/Form/DisplayGroup.php | 68 - lib/Zend/Dojo/Form/Element/Button.php | 121 - lib/Zend/Dojo/Form/Element/CheckBox.php | 206 - lib/Zend/Dojo/Form/Element/ComboBox.php | 186 - .../Dojo/Form/Element/CurrencyTextBox.php | 120 - lib/Zend/Dojo/Form/Element/DateTextBox.php | 214 - lib/Zend/Dojo/Form/Element/Dijit.php | 189 - lib/Zend/Dojo/Form/Element/DijitMulti.php | 303 - lib/Zend/Dojo/Form/Element/Editor.php | 697 -- .../Dojo/Form/Element/FilteringSelect.php | 48 - .../Dojo/Form/Element/HorizontalSlider.php | 208 - lib/Zend/Dojo/Form/Element/NumberSpinner.php | 245 - lib/Zend/Dojo/Form/Element/NumberTextBox.php | 173 - .../Dojo/Form/Element/PasswordTextBox.php | 42 - lib/Zend/Dojo/Form/Element/RadioButton.php | 42 - lib/Zend/Dojo/Form/Element/SimpleTextarea.php | 43 - lib/Zend/Dojo/Form/Element/Slider.php | 199 - lib/Zend/Dojo/Form/Element/SubmitButton.php | 42 - lib/Zend/Dojo/Form/Element/TextBox.php | 164 - lib/Zend/Dojo/Form/Element/Textarea.php | 42 - lib/Zend/Dojo/Form/Element/TimeTextBox.php | 152 - .../Dojo/Form/Element/ValidationTextBox.php | 220 - lib/Zend/Dojo/Form/Element/VerticalSlider.php | 208 - lib/Zend/Dojo/Form/SubForm.php | 94 - lib/Zend/Dojo/View/Exception.php | 37 - .../Dojo/View/Helper/AccordionContainer.php | 66 - lib/Zend/Dojo/View/Helper/AccordionPane.php | 66 - lib/Zend/Dojo/View/Helper/BorderContainer.php | 79 - lib/Zend/Dojo/View/Helper/Button.php | 68 - lib/Zend/Dojo/View/Helper/CheckBox.php | 100 - lib/Zend/Dojo/View/Helper/ComboBox.php | 155 - lib/Zend/Dojo/View/Helper/ContentPane.php | 66 - lib/Zend/Dojo/View/Helper/CurrencyTextBox.php | 68 - lib/Zend/Dojo/View/Helper/CustomDijit.php | 112 - lib/Zend/Dojo/View/Helper/DateTextBox.php | 68 - lib/Zend/Dojo/View/Helper/Dijit.php | 344 - lib/Zend/Dojo/View/Helper/DijitContainer.php | 92 - lib/Zend/Dojo/View/Helper/Dojo.php | 176 - lib/Zend/Dojo/View/Helper/Dojo/Container.php | 1205 --- lib/Zend/Dojo/View/Helper/Editor.php | 199 - lib/Zend/Dojo/View/Helper/FilteringSelect.php | 63 - lib/Zend/Dojo/View/Helper/Form.php | 92 - .../Dojo/View/Helper/HorizontalSlider.php | 62 - lib/Zend/Dojo/View/Helper/NumberSpinner.php | 90 - lib/Zend/Dojo/View/Helper/NumberTextBox.php | 68 - lib/Zend/Dojo/View/Helper/PasswordTextBox.php | 56 - lib/Zend/Dojo/View/Helper/RadioButton.php | 89 - lib/Zend/Dojo/View/Helper/SimpleTextarea.php | 77 - lib/Zend/Dojo/View/Helper/Slider.php | 251 - lib/Zend/Dojo/View/Helper/SplitContainer.php | 66 - lib/Zend/Dojo/View/Helper/StackContainer.php | 66 - lib/Zend/Dojo/View/Helper/SubmitButton.php | 67 - lib/Zend/Dojo/View/Helper/TabContainer.php | 66 - lib/Zend/Dojo/View/Helper/TextBox.php | 68 - lib/Zend/Dojo/View/Helper/Textarea.php | 79 - lib/Zend/Dojo/View/Helper/TimeTextBox.php | 68 - .../Dojo/View/Helper/ValidationTextBox.php | 68 - lib/Zend/Dojo/View/Helper/VerticalSlider.php | 62 - lib/Zend/Dom/Exception.php | 35 - lib/Zend/Dom/Query.php | 356 - lib/Zend/Dom/Query/Css2Xpath.php | 169 - lib/Zend/Dom/Query/Result.php | 182 - lib/Zend/EventManager/Event.php | 225 - lib/Zend/EventManager/EventCollection.php | 109 - lib/Zend/EventManager/EventDescription.php | 108 - lib/Zend/EventManager/EventManager.php | 551 -- lib/Zend/EventManager/EventManagerAware.php | 40 - lib/Zend/EventManager/Exception.php | 31 - .../Exception/InvalidArgumentException.php | 42 - lib/Zend/EventManager/Filter.php | 78 - .../EventManager/Filter/FilterIterator.php | 113 - lib/Zend/EventManager/FilterChain.php | 139 - lib/Zend/EventManager/GlobalEventManager.php | 149 - lib/Zend/EventManager/ListenerAggregate.php | 53 - lib/Zend/EventManager/ResponseCollection.php | 424 - .../EventManager/SharedEventCollection.php | 32 - .../SharedEventCollectionAware.php | 42 - lib/Zend/EventManager/SharedEventManager.php | 148 - lib/Zend/EventManager/StaticEventManager.php | 80 - lib/Zend/Exception.php | 96 - lib/Zend/Feed.php | 409 - lib/Zend/Feed/Abstract.php | 301 - lib/Zend/Feed/Atom.php | 390 - lib/Zend/Feed/Builder.php | 398 - lib/Zend/Feed/Builder/Entry.php | 297 - lib/Zend/Feed/Builder/Exception.php | 40 - lib/Zend/Feed/Builder/Header.php | 423 - lib/Zend/Feed/Builder/Header/Itunes.php | 288 - lib/Zend/Feed/Builder/Interface.php | 52 - lib/Zend/Feed/Element.php | 437 - lib/Zend/Feed/Entry/Abstract.php | 126 - lib/Zend/Feed/Entry/Atom.php | 282 - lib/Zend/Feed/Entry/Rss.php | 122 - lib/Zend/Feed/Exception.php | 42 - lib/Zend/Feed/Pubsubhubbub.php | 153 - .../Feed/Pubsubhubbub/CallbackAbstract.php | 315 - .../Feed/Pubsubhubbub/CallbackInterface.php | 69 - lib/Zend/Feed/Pubsubhubbub/Exception.php | 34 - lib/Zend/Feed/Pubsubhubbub/HttpResponse.php | 235 - .../Feed/Pubsubhubbub/Model/ModelAbstract.php | 63 - .../Feed/Pubsubhubbub/Model/Subscription.php | 141 - .../Model/SubscriptionInterface.php | 65 - lib/Zend/Feed/Pubsubhubbub/Publisher.php | 425 - lib/Zend/Feed/Pubsubhubbub/Subscriber.php | 869 -- .../Feed/Pubsubhubbub/Subscriber/Callback.php | 330 - lib/Zend/Feed/Reader.php | 757 -- lib/Zend/Feed/Reader/Collection.php | 33 - lib/Zend/Feed/Reader/Collection/Author.php | 51 - lib/Zend/Feed/Reader/Collection/Category.php | 57 - .../Reader/Collection/CollectionAbstract.php | 41 - lib/Zend/Feed/Reader/Entry/Atom.php | 400 - lib/Zend/Feed/Reader/Entry/Rss.php | 668 -- lib/Zend/Feed/Reader/EntryAbstract.php | 242 - lib/Zend/Feed/Reader/EntryInterface.php | 143 - lib/Zend/Feed/Reader/Extension/Atom/Entry.php | 659 -- lib/Zend/Feed/Reader/Extension/Atom/Feed.php | 590 -- .../Feed/Reader/Extension/Content/Entry.php | 61 - .../Extension/CreativeCommons/Entry.php | 97 - .../Reader/Extension/CreativeCommons/Feed.php | 89 - .../Reader/Extension/DublinCore/Entry.php | 266 - .../Feed/Reader/Extension/DublinCore/Feed.php | 309 - .../Feed/Reader/Extension/EntryAbstract.php | 200 - .../Feed/Reader/Extension/FeedAbstract.php | 189 - .../Feed/Reader/Extension/Podcast/Entry.php | 202 - .../Feed/Reader/Extension/Podcast/Feed.php | 293 - .../Feed/Reader/Extension/Slash/Entry.php | 144 - .../Reader/Extension/Syndication/Feed.php | 168 - .../Feed/Reader/Extension/Thread/Entry.php | 91 - .../Reader/Extension/WellFormedWeb/Entry.php | 73 - lib/Zend/Feed/Reader/Feed/Atom.php | 421 - lib/Zend/Feed/Reader/Feed/Atom/Source.php | 102 - lib/Zend/Feed/Reader/Feed/Rss.php | 733 -- lib/Zend/Feed/Reader/FeedAbstract.php | 321 - lib/Zend/Feed/Reader/FeedInterface.php | 122 - lib/Zend/Feed/Reader/FeedSet.php | 149 - lib/Zend/Feed/Rss.php | 530 -- lib/Zend/Feed/Writer.php | 267 - lib/Zend/Feed/Writer/Deleted.php | 202 - lib/Zend/Feed/Writer/Entry.php | 761 -- .../Exception/InvalidMethodException.php | 41 - .../Writer/Extension/Atom/Renderer/Feed.php | 123 - .../Extension/Content/Renderer/Entry.php | 92 - .../Extension/DublinCore/Renderer/Entry.php | 96 - .../Extension/DublinCore/Renderer/Feed.php | 96 - .../Feed/Writer/Extension/ITunes/Entry.php | 242 - .../Feed/Writer/Extension/ITunes/Feed.php | 361 - .../Extension/ITunes/Renderer/Entry.php | 216 - .../Writer/Extension/ITunes/Renderer/Feed.php | 320 - .../Writer/Extension/RendererAbstract.php | 180 - .../Writer/Extension/RendererInterface.php | 60 - .../Writer/Extension/Slash/Renderer/Entry.php | 91 - .../Extension/Threading/Renderer/Entry.php | 145 - .../WellFormedWeb/Renderer/Entry.php | 96 - lib/Zend/Feed/Writer/Feed.php | 282 - lib/Zend/Feed/Writer/Feed/FeedAbstract.php | 872 -- lib/Zend/Feed/Writer/Renderer/Entry/Atom.php | 448 - .../Writer/Renderer/Entry/Atom/Deleted.php | 121 - lib/Zend/Feed/Writer/Renderer/Entry/Rss.php | 346 - lib/Zend/Feed/Writer/Renderer/Feed/Atom.php | 131 - .../Renderer/Feed/Atom/AtomAbstract.php | 446 - .../Feed/Writer/Renderer/Feed/Atom/Source.php | 110 - lib/Zend/Feed/Writer/Renderer/Feed/Rss.php | 505 -- .../Feed/Writer/Renderer/RendererAbstract.php | 250 - .../Writer/Renderer/RendererInterface.php | 111 - lib/Zend/Feed/Writer/Source.php | 33 - lib/Zend/File/ClassFileLocator.php | 179 - lib/Zend/File/PhpClassFile.php | 56 - lib/Zend/File/Transfer.php | 125 - lib/Zend/File/Transfer/Adapter/Abstract.php | 1571 ---- lib/Zend/File/Transfer/Adapter/Http.php | 487 - lib/Zend/File/Transfer/Exception.php | 55 - lib/Zend/Filter.php | 239 - lib/Zend/Filter/Alnum.php | 146 - lib/Zend/Filter/Alpha.php | 146 - lib/Zend/Filter/BaseName.php | 50 - lib/Zend/Filter/Boolean.php | 375 - lib/Zend/Filter/Callback.php | 152 - lib/Zend/Filter/Compress.php | 197 - lib/Zend/Filter/Compress/Bz2.php | 188 - lib/Zend/Filter/Compress/CompressAbstract.php | 89 - .../Filter/Compress/CompressInterface.php | 54 - lib/Zend/Filter/Compress/Gz.php | 228 - lib/Zend/Filter/Compress/Lzf.php | 91 - lib/Zend/Filter/Compress/Rar.php | 252 - lib/Zend/Filter/Compress/Tar.php | 245 - lib/Zend/Filter/Compress/Zip.php | 355 - lib/Zend/Filter/Decompress.php | 49 - lib/Zend/Filter/Decrypt.php | 49 - lib/Zend/Filter/Digits.php | 82 - lib/Zend/Filter/Dir.php | 50 - lib/Zend/Filter/Encrypt.php | 138 - lib/Zend/Filter/Encrypt/Interface.php | 47 - lib/Zend/Filter/Encrypt/Mcrypt.php | 364 - lib/Zend/Filter/Encrypt/Openssl.php | 492 - lib/Zend/Filter/Exception.php | 37 - lib/Zend/Filter/File/Decrypt.php | 106 - lib/Zend/Filter/File/Encrypt.php | 106 - lib/Zend/Filter/File/LowerCase.php | 84 - lib/Zend/Filter/File/Rename.php | 309 - lib/Zend/Filter/File/UpperCase.php | 84 - lib/Zend/Filter/HtmlEntities.php | 216 - lib/Zend/Filter/Inflector.php | 527 -- lib/Zend/Filter/Input.php | 1209 --- lib/Zend/Filter/Int.php | 50 - lib/Zend/Filter/Interface.php | 40 - lib/Zend/Filter/LocalizedToNormalized.php | 112 - lib/Zend/Filter/NormalizedToLocalized.php | 111 - lib/Zend/Filter/Null.php | 183 - lib/Zend/Filter/PregReplace.php | 174 - lib/Zend/Filter/RealPath.php | 134 - lib/Zend/Filter/StringToLower.php | 121 - lib/Zend/Filter/StringToUpper.php | 121 - lib/Zend/Filter/StringTrim.php | 124 - lib/Zend/Filter/StripNewlines.php | 48 - lib/Zend/Filter/StripTags.php | 352 - lib/Zend/Filter/Word/CamelCaseToDash.php | 44 - lib/Zend/Filter/Word/CamelCaseToSeparator.php | 49 - .../Filter/Word/CamelCaseToUnderscore.php | 44 - lib/Zend/Filter/Word/DashToCamelCase.php | 44 - lib/Zend/Filter/Word/DashToSeparator.php | 42 - lib/Zend/Filter/Word/DashToUnderscore.php | 45 - lib/Zend/Filter/Word/Separator/Abstract.php | 76 - lib/Zend/Filter/Word/SeparatorToCamelCase.php | 64 - lib/Zend/Filter/Word/SeparatorToDash.php | 46 - lib/Zend/Filter/Word/SeparatorToSeparator.php | 129 - .../Filter/Word/UnderscoreToCamelCase.php | 44 - lib/Zend/Filter/Word/UnderscoreToDash.php | 45 - .../Filter/Word/UnderscoreToSeparator.php | 45 - lib/Zend/Form.php | 3498 -------- lib/Zend/Form/Decorator/Abstract.php | 254 - lib/Zend/Form/Decorator/Callback.php | 128 - lib/Zend/Form/Decorator/Captcha.php | 72 - lib/Zend/Form/Decorator/Captcha/ReCaptcha.php | 128 - lib/Zend/Form/Decorator/Captcha/Word.php | 78 - lib/Zend/Form/Decorator/Description.php | 199 - lib/Zend/Form/Decorator/DtDdWrapper.php | 70 - lib/Zend/Form/Decorator/Errors.php | 77 - lib/Zend/Form/Decorator/Exception.php | 37 - lib/Zend/Form/Decorator/Fieldset.php | 157 - lib/Zend/Form/Decorator/File.php | 143 - lib/Zend/Form/Decorator/Form.php | 134 - lib/Zend/Form/Decorator/FormElements.php | 141 - lib/Zend/Form/Decorator/FormErrors.php | 515 -- lib/Zend/Form/Decorator/HtmlTag.php | 257 - lib/Zend/Form/Decorator/Image.php | 154 - lib/Zend/Form/Decorator/Interface.php | 123 - lib/Zend/Form/Decorator/Label.php | 466 - .../Form/Decorator/Marker/File/Interface.php | 33 - lib/Zend/Form/Decorator/PrepareElements.php | 90 - lib/Zend/Form/Decorator/Tooltip.php | 58 - lib/Zend/Form/Decorator/ViewHelper.php | 268 - lib/Zend/Form/Decorator/ViewScript.php | 192 - lib/Zend/Form/DisplayGroup.php | 1182 --- lib/Zend/Form/Element.php | 2303 ----- lib/Zend/Form/Element/Button.php | 56 - lib/Zend/Form/Element/Captcha.php | 302 - lib/Zend/Form/Element/Checkbox.php | 203 - lib/Zend/Form/Element/Exception.php | 37 - lib/Zend/Form/Element/File.php | 915 -- lib/Zend/Form/Element/Hash.php | 259 - lib/Zend/Form/Element/Hidden.php | 42 - lib/Zend/Form/Element/Image.php | 132 - lib/Zend/Form/Element/Multi.php | 317 - lib/Zend/Form/Element/MultiCheckbox.php | 73 - lib/Zend/Form/Element/Multiselect.php | 54 - lib/Zend/Form/Element/Note.php | 64 - lib/Zend/Form/Element/Password.php | 88 - lib/Zend/Form/Element/Radio.php | 66 - lib/Zend/Form/Element/Reset.php | 42 - lib/Zend/Form/Element/Select.php | 48 - lib/Zend/Form/Element/Submit.php | 127 - lib/Zend/Form/Element/Text.php | 42 - lib/Zend/Form/Element/Textarea.php | 42 - lib/Zend/Form/Element/Xhtml.php | 37 - lib/Zend/Form/Exception.php | 35 - lib/Zend/Form/SubForm.php | 61 - lib/Zend/Gdata.php | 241 - lib/Zend/Gdata/Analytics.php | 137 - lib/Zend/Gdata/Analytics/AccountEntry.php | 102 - lib/Zend/Gdata/Analytics/AccountFeed.php | 57 - lib/Zend/Gdata/Analytics/AccountQuery.php | 190 - lib/Zend/Gdata/Analytics/DataEntry.php | 116 - lib/Zend/Gdata/Analytics/DataFeed.php | 64 - lib/Zend/Gdata/Analytics/DataQuery.php | 403 - .../Gdata/Analytics/Extension/Dimension.php | 40 - lib/Zend/Gdata/Analytics/Extension/Goal.php | 52 - lib/Zend/Gdata/Analytics/Extension/Metric.php | 54 - .../Gdata/Analytics/Extension/Property.php | 122 - .../Gdata/Analytics/Extension/TableId.php | 112 - lib/Zend/Gdata/App.php | 1246 --- lib/Zend/Gdata/App/AuthException.php | 41 - lib/Zend/Gdata/App/BadMethodCallException.php | 42 - lib/Zend/Gdata/App/Base.php | 575 -- lib/Zend/Gdata/App/BaseMediaSource.php | 179 - .../Gdata/App/CaptchaRequiredException.php | 94 - lib/Zend/Gdata/App/Entry.php | 389 - lib/Zend/Gdata/App/Exception.php | 43 - lib/Zend/Gdata/App/Extension.php | 40 - lib/Zend/Gdata/App/Extension/Author.php | 43 - lib/Zend/Gdata/App/Extension/Category.php | 140 - lib/Zend/Gdata/App/Extension/Content.php | 88 - lib/Zend/Gdata/App/Extension/Contributor.php | 43 - lib/Zend/Gdata/App/Extension/Control.php | 98 - lib/Zend/Gdata/App/Extension/Draft.php | 50 - lib/Zend/Gdata/App/Extension/Edited.php | 49 - lib/Zend/Gdata/App/Extension/Element.php | 58 - lib/Zend/Gdata/App/Extension/Email.php | 49 - lib/Zend/Gdata/App/Extension/Generator.php | 115 - lib/Zend/Gdata/App/Extension/Icon.php | 49 - lib/Zend/Gdata/App/Extension/Id.php | 49 - lib/Zend/Gdata/App/Extension/Link.php | 219 - lib/Zend/Gdata/App/Extension/Logo.php | 49 - lib/Zend/Gdata/App/Extension/Name.php | 48 - lib/Zend/Gdata/App/Extension/Person.php | 163 - lib/Zend/Gdata/App/Extension/Published.php | 49 - lib/Zend/Gdata/App/Extension/Rights.php | 49 - lib/Zend/Gdata/App/Extension/Source.php | 46 - lib/Zend/Gdata/App/Extension/Subtitle.php | 43 - lib/Zend/Gdata/App/Extension/Summary.php | 43 - lib/Zend/Gdata/App/Extension/Text.php | 90 - lib/Zend/Gdata/App/Extension/Title.php | 43 - lib/Zend/Gdata/App/Extension/Updated.php | 49 - lib/Zend/Gdata/App/Extension/Uri.php | 49 - lib/Zend/Gdata/App/Feed.php | 352 - lib/Zend/Gdata/App/FeedEntryParent.php | 681 -- lib/Zend/Gdata/App/FeedSourceParent.php | 267 - lib/Zend/Gdata/App/HttpException.php | 121 - lib/Zend/Gdata/App/IOException.php | 43 - .../Gdata/App/InvalidArgumentException.php | 42 - .../App/LoggingHttpClientAdapterSocket.php | 119 - lib/Zend/Gdata/App/MediaEntry.php | 119 - lib/Zend/Gdata/App/MediaFileSource.php | 146 - lib/Zend/Gdata/App/MediaSource.php | 73 - lib/Zend/Gdata/App/Util.php | 112 - lib/Zend/Gdata/App/VersionException.php | 42 - lib/Zend/Gdata/AuthSub.php | 248 - lib/Zend/Gdata/Books.php | 204 - lib/Zend/Gdata/Books/CollectionEntry.php | 56 - lib/Zend/Gdata/Books/CollectionFeed.php | 62 - .../Gdata/Books/Extension/AnnotationLink.php | 63 - .../Gdata/Books/Extension/BooksCategory.php | 59 - lib/Zend/Gdata/Books/Extension/BooksLink.php | 61 - .../Gdata/Books/Extension/Embeddability.php | 122 - lib/Zend/Gdata/Books/Extension/InfoLink.php | 59 - .../Gdata/Books/Extension/PreviewLink.php | 60 - lib/Zend/Gdata/Books/Extension/Review.php | 152 - .../Gdata/Books/Extension/ThumbnailLink.php | 60 - .../Gdata/Books/Extension/Viewability.php | 123 - lib/Zend/Gdata/Books/VolumeEntry.php | 687 -- lib/Zend/Gdata/Books/VolumeFeed.php | 62 - lib/Zend/Gdata/Books/VolumeQuery.php | 112 - lib/Zend/Gdata/Calendar.php | 169 - lib/Zend/Gdata/Calendar/EventEntry.php | 164 - lib/Zend/Gdata/Calendar/EventFeed.php | 106 - lib/Zend/Gdata/Calendar/EventQuery.php | 491 - .../Gdata/Calendar/Extension/AccessLevel.php | 125 - lib/Zend/Gdata/Calendar/Extension/Color.php | 125 - lib/Zend/Gdata/Calendar/Extension/Hidden.php | 134 - lib/Zend/Gdata/Calendar/Extension/Link.php | 125 - .../Gdata/Calendar/Extension/QuickAdd.php | 132 - .../Gdata/Calendar/Extension/Selected.php | 133 - .../Extension/SendEventNotifications.php | 132 - .../Gdata/Calendar/Extension/Timezone.php | 124 - .../Gdata/Calendar/Extension/WebContent.php | 177 - lib/Zend/Gdata/Calendar/ListEntry.php | 246 - lib/Zend/Gdata/Calendar/ListFeed.php | 106 - lib/Zend/Gdata/ClientLogin.php | 182 - lib/Zend/Gdata/Docs.php | 321 - lib/Zend/Gdata/Docs/DocumentListEntry.php | 54 - lib/Zend/Gdata/Docs/DocumentListFeed.php | 68 - lib/Zend/Gdata/Docs/Query.php | 222 - lib/Zend/Gdata/DublinCore.php | 65 - .../Gdata/DublinCore/Extension/Creator.php | 58 - lib/Zend/Gdata/DublinCore/Extension/Date.php | 60 - .../DublinCore/Extension/Description.php | 58 - .../Gdata/DublinCore/Extension/Format.php | 58 - .../Gdata/DublinCore/Extension/Identifier.php | 58 - .../Gdata/DublinCore/Extension/Language.php | 58 - .../Gdata/DublinCore/Extension/Publisher.php | 58 - .../Gdata/DublinCore/Extension/Rights.php | 58 - .../Gdata/DublinCore/Extension/Subject.php | 58 - lib/Zend/Gdata/DublinCore/Extension/Title.php | 58 - lib/Zend/Gdata/Entry.php | 132 - lib/Zend/Gdata/Exif.php | 65 - lib/Zend/Gdata/Exif/Entry.php | 145 - lib/Zend/Gdata/Exif/Extension/Distance.php | 61 - lib/Zend/Gdata/Exif/Extension/Exposure.php | 61 - lib/Zend/Gdata/Exif/Extension/FStop.php | 61 - lib/Zend/Gdata/Exif/Extension/Flash.php | 61 - lib/Zend/Gdata/Exif/Extension/FocalLength.php | 61 - .../Gdata/Exif/Extension/ImageUniqueId.php | 61 - lib/Zend/Gdata/Exif/Extension/Iso.php | 61 - lib/Zend/Gdata/Exif/Extension/Make.php | 61 - lib/Zend/Gdata/Exif/Extension/Model.php | 61 - lib/Zend/Gdata/Exif/Extension/Tags.php | 549 -- lib/Zend/Gdata/Exif/Extension/Time.php | 61 - lib/Zend/Gdata/Exif/Feed.php | 70 - lib/Zend/Gdata/Extension.php | 58 - lib/Zend/Gdata/Extension/AttendeeStatus.php | 123 - lib/Zend/Gdata/Extension/AttendeeType.php | 123 - lib/Zend/Gdata/Extension/Comments.php | 117 - lib/Zend/Gdata/Extension/EntryLink.php | 167 - lib/Zend/Gdata/Extension/EventStatus.php | 101 - lib/Zend/Gdata/Extension/ExtendedProperty.php | 106 - lib/Zend/Gdata/Extension/FeedLink.php | 175 - .../Extension/OpenSearchItemsPerPage.php | 50 - .../Gdata/Extension/OpenSearchStartIndex.php | 50 - .../Extension/OpenSearchTotalResults.php | 50 - lib/Zend/Gdata/Extension/OriginalEvent.php | 142 - lib/Zend/Gdata/Extension/Rating.php | 240 - lib/Zend/Gdata/Extension/Recurrence.php | 49 - .../Gdata/Extension/RecurrenceException.php | 215 - lib/Zend/Gdata/Extension/Reminder.php | 171 - lib/Zend/Gdata/Extension/Transparency.php | 123 - lib/Zend/Gdata/Extension/Visibility.php | 123 - lib/Zend/Gdata/Extension/When.php | 169 - lib/Zend/Gdata/Extension/Where.php | 171 - lib/Zend/Gdata/Extension/Who.php | 299 - lib/Zend/Gdata/Feed.php | 251 - lib/Zend/Gdata/Gapps.php | 1683 ---- lib/Zend/Gdata/Gapps/EmailListEntry.php | 214 - lib/Zend/Gdata/Gapps/EmailListFeed.php | 53 - lib/Zend/Gdata/Gapps/EmailListQuery.php | 187 - .../Gdata/Gapps/EmailListRecipientEntry.php | 146 - .../Gdata/Gapps/EmailListRecipientFeed.php | 53 - .../Gdata/Gapps/EmailListRecipientQuery.php | 153 - lib/Zend/Gdata/Gapps/Error.php | 233 - lib/Zend/Gdata/Gapps/Extension/EmailList.php | 144 - lib/Zend/Gdata/Gapps/Extension/Login.php | 485 - lib/Zend/Gdata/Gapps/Extension/Name.php | 181 - lib/Zend/Gdata/Gapps/Extension/Nickname.php | 142 - lib/Zend/Gdata/Gapps/Extension/Property.php | 179 - lib/Zend/Gdata/Gapps/Extension/Quota.php | 142 - lib/Zend/Gdata/Gapps/GroupEntry.php | 158 - lib/Zend/Gdata/Gapps/GroupFeed.php | 53 - lib/Zend/Gdata/Gapps/GroupQuery.php | 226 - lib/Zend/Gdata/Gapps/MemberEntry.php | 159 - lib/Zend/Gdata/Gapps/MemberFeed.php | 53 - lib/Zend/Gdata/Gapps/MemberQuery.php | 194 - lib/Zend/Gdata/Gapps/NicknameEntry.php | 189 - lib/Zend/Gdata/Gapps/NicknameFeed.php | 53 - lib/Zend/Gdata/Gapps/NicknameQuery.php | 186 - lib/Zend/Gdata/Gapps/OwnerEntry.php | 158 - lib/Zend/Gdata/Gapps/OwnerFeed.php | 53 - lib/Zend/Gdata/Gapps/OwnerQuery.php | 147 - lib/Zend/Gdata/Gapps/Query.php | 123 - lib/Zend/Gdata/Gapps/ServiceException.php | 211 - lib/Zend/Gdata/Gapps/UserEntry.php | 295 - lib/Zend/Gdata/Gapps/UserFeed.php | 53 - lib/Zend/Gdata/Gapps/UserQuery.php | 147 - lib/Zend/Gdata/Gbase.php | 78 - lib/Zend/Gdata/Gbase/Entry.php | 59 - .../Gdata/Gbase/Extension/BaseAttribute.php | 54 - lib/Zend/Gdata/Gbase/Feed.php | 61 - lib/Zend/Gdata/Gbase/ItemEntry.php | 42 - lib/Zend/Gdata/Gbase/ItemFeed.php | 42 - lib/Zend/Gdata/Gbase/ItemQuery.php | 52 - lib/Zend/Gdata/Gbase/Query.php | 69 - lib/Zend/Gdata/Gbase/SnippetEntry.php | 42 - lib/Zend/Gdata/Gbase/SnippetFeed.php | 47 - lib/Zend/Gdata/Gbase/SnippetQuery.php | 46 - lib/Zend/Gdata/Geo.php | 70 - lib/Zend/Gdata/Geo/Entry.php | 97 - lib/Zend/Gdata/Geo/Extension/GeoRssWhere.php | 135 - lib/Zend/Gdata/Geo/Extension/GmlPoint.php | 136 - lib/Zend/Gdata/Geo/Extension/GmlPos.php | 61 - lib/Zend/Gdata/Geo/Feed.php | 64 - lib/Zend/Gdata/Health.php | 89 - lib/Zend/Gdata/Health/Extension/Ccr.php | 58 - lib/Zend/Gdata/Health/ProfileEntry.php | 59 - lib/Zend/Gdata/Health/ProfileFeed.php | 61 - lib/Zend/Gdata/Health/ProfileListEntry.php | 59 - lib/Zend/Gdata/Health/ProfileListFeed.php | 55 - lib/Zend/Gdata/Health/Query.php | 75 - lib/Zend/Gdata/HttpAdapterStreamingProxy.php | 132 - lib/Zend/Gdata/HttpAdapterStreamingSocket.php | 111 - lib/Zend/Gdata/HttpClient.php | 352 - lib/Zend/Gdata/Kind/EventEntry.php | 428 - lib/Zend/Gdata/Media.php | 65 - lib/Zend/Gdata/Media/Entry.php | 134 - .../Gdata/Media/Extension/MediaCategory.php | 148 - .../Gdata/Media/Extension/MediaContent.php | 522 -- .../Gdata/Media/Extension/MediaCopyright.php | 116 - .../Gdata/Media/Extension/MediaCredit.php | 149 - .../Media/Extension/MediaDescription.php | 116 - lib/Zend/Gdata/Media/Extension/MediaGroup.php | 566 -- lib/Zend/Gdata/Media/Extension/MediaHash.php | 115 - .../Gdata/Media/Extension/MediaKeywords.php | 52 - .../Gdata/Media/Extension/MediaPlayer.php | 178 - .../Gdata/Media/Extension/MediaRating.php | 118 - .../Media/Extension/MediaRestriction.php | 149 - lib/Zend/Gdata/Media/Extension/MediaText.php | 211 - .../Gdata/Media/Extension/MediaThumbnail.php | 210 - lib/Zend/Gdata/Media/Extension/MediaTitle.php | 118 - lib/Zend/Gdata/Media/Feed.php | 70 - lib/Zend/Gdata/MediaMimeStream.php | 190 - lib/Zend/Gdata/MimeBodyString.php | 92 - lib/Zend/Gdata/MimeFile.php | 66 - lib/Zend/Gdata/Photos.php | 576 -- lib/Zend/Gdata/Photos/AlbumEntry.php | 610 -- lib/Zend/Gdata/Photos/AlbumFeed.php | 509 -- lib/Zend/Gdata/Photos/AlbumQuery.php | 149 - lib/Zend/Gdata/Photos/CommentEntry.php | 195 - lib/Zend/Gdata/Photos/Extension/Access.php | 63 - lib/Zend/Gdata/Photos/Extension/AlbumId.php | 63 - lib/Zend/Gdata/Photos/Extension/BytesUsed.php | 62 - lib/Zend/Gdata/Photos/Extension/Checksum.php | 63 - lib/Zend/Gdata/Photos/Extension/Client.php | 63 - .../Gdata/Photos/Extension/CommentCount.php | 63 - .../Photos/Extension/CommentingEnabled.php | 64 - lib/Zend/Gdata/Photos/Extension/Height.php | 62 - lib/Zend/Gdata/Photos/Extension/Id.php | 62 - lib/Zend/Gdata/Photos/Extension/Location.php | 62 - .../Photos/Extension/MaxPhotosPerAlbum.php | 63 - lib/Zend/Gdata/Photos/Extension/Name.php | 62 - lib/Zend/Gdata/Photos/Extension/Nickname.php | 62 - lib/Zend/Gdata/Photos/Extension/NumPhotos.php | 62 - .../Photos/Extension/NumPhotosRemaining.php | 62 - lib/Zend/Gdata/Photos/Extension/PhotoId.php | 61 - lib/Zend/Gdata/Photos/Extension/Position.php | 62 - .../Gdata/Photos/Extension/QuotaCurrent.php | 62 - .../Gdata/Photos/Extension/QuotaLimit.php | 63 - lib/Zend/Gdata/Photos/Extension/Rotation.php | 63 - lib/Zend/Gdata/Photos/Extension/Size.php | 62 - lib/Zend/Gdata/Photos/Extension/Thumbnail.php | 62 - lib/Zend/Gdata/Photos/Extension/Timestamp.php | 63 - lib/Zend/Gdata/Photos/Extension/User.php | 62 - lib/Zend/Gdata/Photos/Extension/Version.php | 63 - lib/Zend/Gdata/Photos/Extension/Weight.php | 63 - lib/Zend/Gdata/Photos/Extension/Width.php | 62 - lib/Zend/Gdata/Photos/PhotoEntry.php | 691 -- lib/Zend/Gdata/Photos/PhotoFeed.php | 559 -- lib/Zend/Gdata/Photos/PhotoQuery.php | 98 - lib/Zend/Gdata/Photos/TagEntry.php | 140 - lib/Zend/Gdata/Photos/UserEntry.php | 366 - lib/Zend/Gdata/Photos/UserFeed.php | 247 - lib/Zend/Gdata/Photos/UserQuery.php | 355 - lib/Zend/Gdata/Query.php | 418 - lib/Zend/Gdata/Spreadsheets.php | 445 - lib/Zend/Gdata/Spreadsheets/CellEntry.php | 104 - lib/Zend/Gdata/Spreadsheets/CellFeed.php | 158 - lib/Zend/Gdata/Spreadsheets/CellQuery.php | 417 - lib/Zend/Gdata/Spreadsheets/DocumentQuery.php | 288 - .../Gdata/Spreadsheets/Extension/Cell.php | 201 - .../Gdata/Spreadsheets/Extension/ColCount.php | 59 - .../Gdata/Spreadsheets/Extension/Custom.php | 100 - .../Gdata/Spreadsheets/Extension/RowCount.php | 60 - lib/Zend/Gdata/Spreadsheets/ListEntry.php | 208 - lib/Zend/Gdata/Spreadsheets/ListFeed.php | 64 - lib/Zend/Gdata/Spreadsheets/ListQuery.php | 305 - .../Gdata/Spreadsheets/SpreadsheetEntry.php | 64 - .../Gdata/Spreadsheets/SpreadsheetFeed.php | 64 - .../Gdata/Spreadsheets/WorksheetEntry.php | 187 - lib/Zend/Gdata/Spreadsheets/WorksheetFeed.php | 64 - lib/Zend/Gdata/YouTube.php | 876 -- lib/Zend/Gdata/YouTube/ActivityEntry.php | 232 - lib/Zend/Gdata/YouTube/ActivityFeed.php | 66 - lib/Zend/Gdata/YouTube/CommentEntry.php | 59 - lib/Zend/Gdata/YouTube/CommentFeed.php | 66 - lib/Zend/Gdata/YouTube/ContactEntry.php | 136 - lib/Zend/Gdata/YouTube/ContactFeed.php | 68 - lib/Zend/Gdata/YouTube/Extension/AboutMe.php | 51 - lib/Zend/Gdata/YouTube/Extension/Age.php | 51 - lib/Zend/Gdata/YouTube/Extension/Books.php | 51 - lib/Zend/Gdata/YouTube/Extension/Company.php | 51 - lib/Zend/Gdata/YouTube/Extension/Control.php | 133 - .../Gdata/YouTube/Extension/CountHint.php | 51 - .../Gdata/YouTube/Extension/Description.php | 51 - lib/Zend/Gdata/YouTube/Extension/Duration.php | 126 - .../Gdata/YouTube/Extension/FirstName.php | 51 - lib/Zend/Gdata/YouTube/Extension/Gender.php | 51 - lib/Zend/Gdata/YouTube/Extension/Hobbies.php | 51 - lib/Zend/Gdata/YouTube/Extension/Hometown.php | 51 - lib/Zend/Gdata/YouTube/Extension/LastName.php | 51 - lib/Zend/Gdata/YouTube/Extension/Link.php | 133 - lib/Zend/Gdata/YouTube/Extension/Location.php | 51 - .../Gdata/YouTube/Extension/MediaContent.php | 120 - .../Gdata/YouTube/Extension/MediaCredit.php | 189 - .../Gdata/YouTube/Extension/MediaGroup.php | 336 - .../Gdata/YouTube/Extension/MediaRating.php | 150 - lib/Zend/Gdata/YouTube/Extension/Movies.php | 51 - lib/Zend/Gdata/YouTube/Extension/Music.php | 51 - lib/Zend/Gdata/YouTube/Extension/NoEmbed.php | 54 - .../Gdata/YouTube/Extension/Occupation.php | 51 - .../Gdata/YouTube/Extension/PlaylistId.php | 51 - .../Gdata/YouTube/Extension/PlaylistTitle.php | 51 - lib/Zend/Gdata/YouTube/Extension/Position.php | 90 - lib/Zend/Gdata/YouTube/Extension/Private.php | 81 - .../Gdata/YouTube/Extension/QueryString.php | 51 - lib/Zend/Gdata/YouTube/Extension/Racy.php | 124 - lib/Zend/Gdata/YouTube/Extension/Recorded.php | 51 - .../Gdata/YouTube/Extension/Relationship.php | 51 - .../Gdata/YouTube/Extension/ReleaseDate.php | 51 - lib/Zend/Gdata/YouTube/Extension/School.php | 51 - lib/Zend/Gdata/YouTube/Extension/State.php | 193 - .../Gdata/YouTube/Extension/Statistics.php | 309 - lib/Zend/Gdata/YouTube/Extension/Status.php | 51 - lib/Zend/Gdata/YouTube/Extension/Token.php | 70 - lib/Zend/Gdata/YouTube/Extension/Uploaded.php | 51 - lib/Zend/Gdata/YouTube/Extension/Username.php | 51 - lib/Zend/Gdata/YouTube/Extension/VideoId.php | 51 - lib/Zend/Gdata/YouTube/InboxEntry.php | 281 - lib/Zend/Gdata/YouTube/InboxFeed.php | 68 - lib/Zend/Gdata/YouTube/MediaEntry.php | 81 - lib/Zend/Gdata/YouTube/PlaylistListEntry.php | 300 - lib/Zend/Gdata/YouTube/PlaylistListFeed.php | 68 - lib/Zend/Gdata/YouTube/PlaylistVideoEntry.php | 132 - lib/Zend/Gdata/YouTube/PlaylistVideoFeed.php | 68 - lib/Zend/Gdata/YouTube/SubscriptionEntry.php | 446 - lib/Zend/Gdata/YouTube/SubscriptionFeed.php | 68 - lib/Zend/Gdata/YouTube/UserProfileEntry.php | 1041 --- lib/Zend/Gdata/YouTube/VideoEntry.php | 1095 --- lib/Zend/Gdata/YouTube/VideoFeed.php | 65 - lib/Zend/Gdata/YouTube/VideoQuery.php | 540 -- lib/Zend/Http/Client.php | 1607 ---- lib/Zend/Http/Client/Adapter/Curl.php | 539 -- lib/Zend/Http/Client/Adapter/Exception.php | 38 - lib/Zend/Http/Client/Adapter/Interface.php | 78 - lib/Zend/Http/Client/Adapter/Proxy.php | 343 - lib/Zend/Http/Client/Adapter/Socket.php | 543 -- lib/Zend/Http/Client/Adapter/Stream.php | 46 - lib/Zend/Http/Client/Adapter/Test.php | 248 - lib/Zend/Http/Client/Exception.php | 36 - lib/Zend/Http/Cookie.php | 424 - lib/Zend/Http/CookieJar.php | 428 - lib/Zend/Http/Exception.php | 36 - .../Exception/InvalidArgumentException.php | 36 - .../Header/Exception/RuntimeException.php | 36 - lib/Zend/Http/Header/HeaderValue.php | 127 - lib/Zend/Http/Header/SetCookie.php | 554 -- lib/Zend/Http/Response.php | 703 -- lib/Zend/Http/Response/Stream.php | 235 - lib/Zend/Http/UserAgent.php | 853 -- lib/Zend/Http/UserAgent/AbstractDevice.php | 997 --- lib/Zend/Http/UserAgent/Bot.php | 129 - lib/Zend/Http/UserAgent/Checker.php | 76 - lib/Zend/Http/UserAgent/Console.php | 67 - lib/Zend/Http/UserAgent/Desktop.php | 56 - lib/Zend/Http/UserAgent/Device.php | 200 - lib/Zend/Http/UserAgent/Email.php | 65 - lib/Zend/Http/UserAgent/Exception.php | 36 - lib/Zend/Http/UserAgent/Features/Adapter.php | 39 - .../UserAgent/Features/Adapter/Browscap.php | 97 - .../Features/Adapter/DeviceAtlas.php | 78 - .../UserAgent/Features/Adapter/TeraWurfl.php | 102 - .../Http/UserAgent/Features/Exception.php | 36 - lib/Zend/Http/UserAgent/Feed.php | 81 - lib/Zend/Http/UserAgent/Mobile.php | 536 -- lib/Zend/Http/UserAgent/Offline.php | 70 - lib/Zend/Http/UserAgent/Probe.php | 81 - lib/Zend/Http/UserAgent/Spam.php | 79 - lib/Zend/Http/UserAgent/Storage.php | 65 - lib/Zend/Http/UserAgent/Storage/Exception.php | 37 - .../Http/UserAgent/Storage/NonPersistent.php | 97 - lib/Zend/Http/UserAgent/Storage/Session.php | 166 - lib/Zend/Http/UserAgent/Text.php | 132 - lib/Zend/Http/UserAgent/Validator.php | 73 - lib/Zend/Json.php | 442 - lib/Zend/Json/Decoder.php | 581 -- lib/Zend/Json/Encoder.php | 578 -- lib/Zend/Json/Exception.php | 37 - lib/Zend/Json/Expr.php | 80 - lib/Zend/Json/Server.php | 568 -- lib/Zend/Json/Server/Cache.php | 102 - lib/Zend/Json/Server/Error.php | 198 - lib/Zend/Json/Server/Exception.php | 36 - lib/Zend/Json/Server/Request.php | 289 - lib/Zend/Json/Server/Request/Http.php | 66 - lib/Zend/Json/Server/Response.php | 249 - lib/Zend/Json/Server/Response/Http.php | 81 - lib/Zend/Json/Server/Smd.php | 480 - lib/Zend/Json/Server/Smd/Service.php | 473 - lib/Zend/Layout.php | 798 -- .../Controller/Action/Helper/Layout.php | 186 - lib/Zend/Layout/Controller/Plugin/Layout.php | 156 - lib/Zend/Layout/Exception.php | 35 - lib/Zend/Ldap.php | 1598 ---- lib/Zend/Ldap/Attribute.php | 417 - lib/Zend/Ldap/Collection.php | 239 - lib/Zend/Ldap/Collection/Iterator/Default.php | 312 - lib/Zend/Ldap/Converter.php | 410 - lib/Zend/Ldap/Converter/Exception.php | 35 - lib/Zend/Ldap/Dn.php | 794 -- lib/Zend/Ldap/Exception.php | 172 - lib/Zend/Ldap/Filter.php | 265 - lib/Zend/Ldap/Filter/Abstract.php | 157 - lib/Zend/Ldap/Filter/And.php | 48 - lib/Zend/Ldap/Filter/Exception.php | 37 - lib/Zend/Ldap/Filter/Logical.php | 107 - lib/Zend/Ldap/Filter/Mask.php | 66 - lib/Zend/Ldap/Filter/Not.php | 75 - lib/Zend/Ldap/Filter/Or.php | 48 - lib/Zend/Ldap/Filter/String.php | 65 - lib/Zend/Ldap/Ldif/Encoder.php | 304 - lib/Zend/Ldap/Node.php | 1185 --- lib/Zend/Ldap/Node/Abstract.php | 485 - lib/Zend/Ldap/Node/ChildrenIterator.php | 209 - lib/Zend/Ldap/Node/Collection.php | 67 - lib/Zend/Ldap/Node/RootDse.php | 158 - .../Ldap/Node/RootDse/ActiveDirectory.php | 247 - lib/Zend/Ldap/Node/RootDse/OpenLdap.php | 102 - lib/Zend/Ldap/Node/RootDse/eDirectory.php | 160 - lib/Zend/Ldap/Node/Schema.php | 120 - lib/Zend/Ldap/Node/Schema/ActiveDirectory.php | 103 - .../Schema/AttributeType/ActiveDirectory.php | 104 - .../Node/Schema/AttributeType/Interface.php | 75 - .../Node/Schema/AttributeType/OpenLdap.php | 129 - lib/Zend/Ldap/Node/Schema/Item.php | 163 - .../Schema/ObjectClass/ActiveDirectory.php | 115 - .../Node/Schema/ObjectClass/Interface.php | 83 - .../Ldap/Node/Schema/ObjectClass/OpenLdap.php | 175 - lib/Zend/Ldap/Node/Schema/OpenLdap.php | 502 -- lib/Zend/Loader.php | 343 - lib/Zend/Loader/Autoloader.php | 589 -- lib/Zend/Loader/Autoloader/Interface.php | 43 - lib/Zend/Loader/Autoloader/Resource.php | 472 - lib/Zend/Loader/AutoloaderFactory.php | 225 - lib/Zend/Loader/ClassMapAutoloader.php | 248 - lib/Zend/Loader/Exception.php | 35 - .../Exception/InvalidArgumentException.php | 34 - lib/Zend/Loader/PluginLoader.php | 506 -- lib/Zend/Loader/PluginLoader/Exception.php | 39 - lib/Zend/Loader/PluginLoader/Interface.php | 75 - lib/Zend/Loader/SplAutoloader.php | 75 - lib/Zend/Loader/StandardAutoloader.php | 368 - lib/Zend/Locale.php | 2012 ----- lib/Zend/Locale/Data.php | 1642 ---- lib/Zend/Locale/Data/Translation.php | 285 - lib/Zend/Locale/Data/aa.xml | 212 - lib/Zend/Locale/Data/aa_DJ.xml | 34 - lib/Zend/Locale/Data/aa_ER.xml | 21 - lib/Zend/Locale/Data/aa_ET.xml | 14 - lib/Zend/Locale/Data/af.xml | 3879 -------- lib/Zend/Locale/Data/af_NA.xml | 125 - lib/Zend/Locale/Data/af_ZA.xml | 14 - lib/Zend/Locale/Data/agq.xml | 774 -- lib/Zend/Locale/Data/agq_CM.xml | 14 - lib/Zend/Locale/Data/ak.xml | 734 -- lib/Zend/Locale/Data/ak_GH.xml | 14 - lib/Zend/Locale/Data/am.xml | 5280 ----------- lib/Zend/Locale/Data/am_ET.xml | 14 - lib/Zend/Locale/Data/ar.xml | 7884 ----------------- lib/Zend/Locale/Data/ar_001.xml | 14 - lib/Zend/Locale/Data/ar_AE.xml | 15 - lib/Zend/Locale/Data/ar_BH.xml | 15 - lib/Zend/Locale/Data/ar_DJ.xml | 21 - lib/Zend/Locale/Data/ar_DZ.xml | 193 - lib/Zend/Locale/Data/ar_EG.xml | 228 - lib/Zend/Locale/Data/ar_EH.xml | 17 - lib/Zend/Locale/Data/ar_ER.xml | 21 - lib/Zend/Locale/Data/ar_IL.xml | 14 - lib/Zend/Locale/Data/ar_IQ.xml | 111 - lib/Zend/Locale/Data/ar_JO.xml | 111 - lib/Zend/Locale/Data/ar_KM.xml | 14 - lib/Zend/Locale/Data/ar_KW.xml | 15 - lib/Zend/Locale/Data/ar_LB.xml | 142 - lib/Zend/Locale/Data/ar_LY.xml | 21 - lib/Zend/Locale/Data/ar_MA.xml | 199 - lib/Zend/Locale/Data/ar_MR.xml | 96 - lib/Zend/Locale/Data/ar_OM.xml | 15 - lib/Zend/Locale/Data/ar_PS.xml | 134 - lib/Zend/Locale/Data/ar_QA.xml | 24 - lib/Zend/Locale/Data/ar_SA.xml | 38 - lib/Zend/Locale/Data/ar_SD.xml | 15 - lib/Zend/Locale/Data/ar_SO.xml | 21 - lib/Zend/Locale/Data/ar_SS.xml | 24 - lib/Zend/Locale/Data/ar_SY.xml | 120 - lib/Zend/Locale/Data/ar_TD.xml | 14 - lib/Zend/Locale/Data/ar_TN.xml | 202 - lib/Zend/Locale/Data/ar_YE.xml | 24 - lib/Zend/Locale/Data/as.xml | 293 - lib/Zend/Locale/Data/as_IN.xml | 14 - lib/Zend/Locale/Data/asa.xml | 766 -- lib/Zend/Locale/Data/asa_TZ.xml | 14 - lib/Zend/Locale/Data/ast.xml | 2613 ------ lib/Zend/Locale/Data/ast_ES.xml | 14 - lib/Zend/Locale/Data/az.xml | 5470 ------------ lib/Zend/Locale/Data/az_Cyrl.xml | 225 - lib/Zend/Locale/Data/az_Cyrl_AZ.xml | 15 - lib/Zend/Locale/Data/az_Latn.xml | 14 - lib/Zend/Locale/Data/az_Latn_AZ.xml | 15 - lib/Zend/Locale/Data/bas.xml | 780 -- lib/Zend/Locale/Data/bas_CM.xml | 14 - lib/Zend/Locale/Data/be.xml | 1312 --- lib/Zend/Locale/Data/be_BY.xml | 14 - lib/Zend/Locale/Data/bem.xml | 337 - lib/Zend/Locale/Data/bem_ZM.xml | 14 - lib/Zend/Locale/Data/bez.xml | 765 -- lib/Zend/Locale/Data/bez_TZ.xml | 14 - lib/Zend/Locale/Data/bg.xml | 6065 ------------- lib/Zend/Locale/Data/bg_BG.xml | 14 - lib/Zend/Locale/Data/bm.xml | 755 -- lib/Zend/Locale/Data/bm_ML.xml | 14 - lib/Zend/Locale/Data/bn.xml | 5954 ------------- lib/Zend/Locale/Data/bn_BD.xml | 14 - lib/Zend/Locale/Data/bn_IN.xml | 282 - lib/Zend/Locale/Data/bo.xml | 566 -- lib/Zend/Locale/Data/bo_CN.xml | 14 - lib/Zend/Locale/Data/bo_IN.xml | 26 - lib/Zend/Locale/Data/br.xml | 2391 ----- lib/Zend/Locale/Data/br_FR.xml | 14 - lib/Zend/Locale/Data/brx.xml | 4142 --------- lib/Zend/Locale/Data/brx_IN.xml | 14 - lib/Zend/Locale/Data/bs.xml | 5287 ----------- lib/Zend/Locale/Data/bs_Cyrl.xml | 6541 -------------- lib/Zend/Locale/Data/bs_Cyrl_BA.xml | 15 - lib/Zend/Locale/Data/bs_Latn.xml | 14 - lib/Zend/Locale/Data/bs_Latn_BA.xml | 15 - lib/Zend/Locale/Data/byn.xml | 513 -- lib/Zend/Locale/Data/byn_ER.xml | 14 - lib/Zend/Locale/Data/ca.xml | 5788 ------------ lib/Zend/Locale/Data/ca_AD.xml | 14 - lib/Zend/Locale/Data/ca_ES.xml | 14 - lib/Zend/Locale/Data/ca_ES_VALENCIA.xml | 15 - lib/Zend/Locale/Data/ca_FR.xml | 21 - lib/Zend/Locale/Data/ca_IT.xml | 14 - lib/Zend/Locale/Data/cgg.xml | 751 -- lib/Zend/Locale/Data/cgg_UG.xml | 14 - lib/Zend/Locale/Data/characters.xml | 526 -- lib/Zend/Locale/Data/chr.xml | 846 -- lib/Zend/Locale/Data/chr_US.xml | 14 - lib/Zend/Locale/Data/coverageLevels.xml | 498 -- lib/Zend/Locale/Data/cs.xml | 6371 ------------- lib/Zend/Locale/Data/cs_CZ.xml | 14 - lib/Zend/Locale/Data/cy.xml | 5666 ------------ lib/Zend/Locale/Data/cy_GB.xml | 14 - lib/Zend/Locale/Data/da.xml | 5281 ----------- lib/Zend/Locale/Data/da_DK.xml | 14 - lib/Zend/Locale/Data/da_GL.xml | 14 - lib/Zend/Locale/Data/dav.xml | 765 -- lib/Zend/Locale/Data/dav_KE.xml | 14 - lib/Zend/Locale/Data/dayPeriods.xml | 144 - lib/Zend/Locale/Data/de.xml | 5451 ------------ lib/Zend/Locale/Data/de_AT.xml | 169 - lib/Zend/Locale/Data/de_BE.xml | 14 - lib/Zend/Locale/Data/de_CH.xml | 59 - lib/Zend/Locale/Data/de_DE.xml | 14 - lib/Zend/Locale/Data/de_LI.xml | 28 - lib/Zend/Locale/Data/de_LU.xml | 23 - lib/Zend/Locale/Data/dje.xml | 779 -- lib/Zend/Locale/Data/dje_NE.xml | 14 - lib/Zend/Locale/Data/dua.xml | 342 - lib/Zend/Locale/Data/dua_CM.xml | 14 - lib/Zend/Locale/Data/dyo.xml | 546 -- lib/Zend/Locale/Data/dyo_SN.xml | 14 - lib/Zend/Locale/Data/dz.xml | 2651 ------ lib/Zend/Locale/Data/dz_BT.xml | 14 - lib/Zend/Locale/Data/ebu.xml | 764 -- lib/Zend/Locale/Data/ebu_KE.xml | 14 - lib/Zend/Locale/Data/ee.xml | 5541 ------------ lib/Zend/Locale/Data/ee_GH.xml | 14 - lib/Zend/Locale/Data/ee_TG.xml | 14 - lib/Zend/Locale/Data/el.xml | 6283 ------------- lib/Zend/Locale/Data/el_CY.xml | 24 - lib/Zend/Locale/Data/el_GR.xml | 14 - lib/Zend/Locale/Data/en.xml | 5446 ------------ lib/Zend/Locale/Data/en_001.xml | 94 - lib/Zend/Locale/Data/en_150.xml | 288 - lib/Zend/Locale/Data/en_AG.xml | 14 - lib/Zend/Locale/Data/en_AI.xml | 14 - lib/Zend/Locale/Data/en_AS.xml | 14 - lib/Zend/Locale/Data/en_AU.xml | 491 - lib/Zend/Locale/Data/en_BB.xml | 21 - lib/Zend/Locale/Data/en_BE.xml | 293 - lib/Zend/Locale/Data/en_BM.xml | 21 - lib/Zend/Locale/Data/en_BS.xml | 34 - lib/Zend/Locale/Data/en_BW.xml | 286 - lib/Zend/Locale/Data/en_BZ.xml | 288 - lib/Zend/Locale/Data/en_CA.xml | 121 - lib/Zend/Locale/Data/en_CC.xml | 21 - lib/Zend/Locale/Data/en_CK.xml | 21 - lib/Zend/Locale/Data/en_CM.xml | 40 - lib/Zend/Locale/Data/en_CX.xml | 21 - lib/Zend/Locale/Data/en_DG.xml | 15 - lib/Zend/Locale/Data/en_DM.xml | 14 - lib/Zend/Locale/Data/en_Dsrt.xml | 952 -- lib/Zend/Locale/Data/en_Dsrt_US.xml | 15 - lib/Zend/Locale/Data/en_ER.xml | 47 - lib/Zend/Locale/Data/en_FJ.xml | 21 - lib/Zend/Locale/Data/en_FK.xml | 24 - lib/Zend/Locale/Data/en_FM.xml | 14 - lib/Zend/Locale/Data/en_GB.xml | 1257 --- lib/Zend/Locale/Data/en_GD.xml | 14 - lib/Zend/Locale/Data/en_GG.xml | 14 - lib/Zend/Locale/Data/en_GH.xml | 47 - lib/Zend/Locale/Data/en_GI.xml | 27 - lib/Zend/Locale/Data/en_GM.xml | 47 - lib/Zend/Locale/Data/en_GU.xml | 23 - lib/Zend/Locale/Data/en_GY.xml | 21 - lib/Zend/Locale/Data/en_HK.xml | 239 - lib/Zend/Locale/Data/en_IE.xml | 214 - lib/Zend/Locale/Data/en_IM.xml | 14 - lib/Zend/Locale/Data/en_IN.xml | 312 - lib/Zend/Locale/Data/en_IO.xml | 15 - lib/Zend/Locale/Data/en_JE.xml | 14 - lib/Zend/Locale/Data/en_JM.xml | 98 - lib/Zend/Locale/Data/en_KE.xml | 47 - lib/Zend/Locale/Data/en_KI.xml | 21 - lib/Zend/Locale/Data/en_KN.xml | 14 - lib/Zend/Locale/Data/en_KY.xml | 34 - lib/Zend/Locale/Data/en_LC.xml | 14 - lib/Zend/Locale/Data/en_LR.xml | 47 - lib/Zend/Locale/Data/en_LS.xml | 47 - lib/Zend/Locale/Data/en_MG.xml | 47 - lib/Zend/Locale/Data/en_MH.xml | 74 - lib/Zend/Locale/Data/en_MO.xml | 68 - lib/Zend/Locale/Data/en_MP.xml | 74 - lib/Zend/Locale/Data/en_MS.xml | 14 - lib/Zend/Locale/Data/en_MT.xml | 260 - lib/Zend/Locale/Data/en_MU.xml | 47 - lib/Zend/Locale/Data/en_MW.xml | 47 - lib/Zend/Locale/Data/en_NA.xml | 48 - lib/Zend/Locale/Data/en_NF.xml | 21 - lib/Zend/Locale/Data/en_NG.xml | 47 - lib/Zend/Locale/Data/en_NR.xml | 21 - lib/Zend/Locale/Data/en_NU.xml | 21 - lib/Zend/Locale/Data/en_NZ.xml | 337 - lib/Zend/Locale/Data/en_PG.xml | 21 - lib/Zend/Locale/Data/en_PH.xml | 21 - lib/Zend/Locale/Data/en_PK.xml | 300 - lib/Zend/Locale/Data/en_PN.xml | 21 - lib/Zend/Locale/Data/en_PR.xml | 14 - lib/Zend/Locale/Data/en_PW.xml | 27 - lib/Zend/Locale/Data/en_RW.xml | 47 - lib/Zend/Locale/Data/en_SB.xml | 21 - lib/Zend/Locale/Data/en_SC.xml | 21 - lib/Zend/Locale/Data/en_SD.xml | 40 - lib/Zend/Locale/Data/en_SG.xml | 223 - lib/Zend/Locale/Data/en_SH.xml | 24 - lib/Zend/Locale/Data/en_SL.xml | 47 - lib/Zend/Locale/Data/en_SS.xml | 50 - lib/Zend/Locale/Data/en_SX.xml | 21 - lib/Zend/Locale/Data/en_SZ.xml | 47 - lib/Zend/Locale/Data/en_TC.xml | 14 - lib/Zend/Locale/Data/en_TK.xml | 21 - lib/Zend/Locale/Data/en_TO.xml | 21 - lib/Zend/Locale/Data/en_TT.xml | 22 - lib/Zend/Locale/Data/en_TV.xml | 21 - lib/Zend/Locale/Data/en_TZ.xml | 47 - lib/Zend/Locale/Data/en_UG.xml | 47 - lib/Zend/Locale/Data/en_UM.xml | 14 - lib/Zend/Locale/Data/en_US.xml | 14 - lib/Zend/Locale/Data/en_US_POSIX.xml | 58 - lib/Zend/Locale/Data/en_VC.xml | 14 - lib/Zend/Locale/Data/en_VG.xml | 14 - lib/Zend/Locale/Data/en_VI.xml | 14 - lib/Zend/Locale/Data/en_VU.xml | 21 - lib/Zend/Locale/Data/en_WS.xml | 21 - lib/Zend/Locale/Data/en_ZA.xml | 282 - lib/Zend/Locale/Data/en_ZM.xml | 47 - lib/Zend/Locale/Data/en_ZW.xml | 269 - lib/Zend/Locale/Data/eo.xml | 796 -- lib/Zend/Locale/Data/eo_001.xml | 14 - lib/Zend/Locale/Data/es.xml | 5584 ------------ lib/Zend/Locale/Data/es_419.xml | 237 - lib/Zend/Locale/Data/es_AR.xml | 246 - lib/Zend/Locale/Data/es_BO.xml | 25 - lib/Zend/Locale/Data/es_CL.xml | 281 - lib/Zend/Locale/Data/es_CO.xml | 260 - lib/Zend/Locale/Data/es_CR.xml | 25 - lib/Zend/Locale/Data/es_CU.xml | 24 - lib/Zend/Locale/Data/es_DO.xml | 24 - lib/Zend/Locale/Data/es_EA.xml | 14 - lib/Zend/Locale/Data/es_EC.xml | 214 - lib/Zend/Locale/Data/es_ES.xml | 14 - lib/Zend/Locale/Data/es_GQ.xml | 24 - lib/Zend/Locale/Data/es_GT.xml | 231 - lib/Zend/Locale/Data/es_HN.xml | 231 - lib/Zend/Locale/Data/es_IC.xml | 14 - lib/Zend/Locale/Data/es_MX.xml | 4940 ----------- lib/Zend/Locale/Data/es_NI.xml | 21 - lib/Zend/Locale/Data/es_PA.xml | 245 - lib/Zend/Locale/Data/es_PE.xml | 235 - lib/Zend/Locale/Data/es_PH.xml | 21 - lib/Zend/Locale/Data/es_PR.xml | 280 - lib/Zend/Locale/Data/es_PY.xml | 33 - lib/Zend/Locale/Data/es_SV.xml | 14 - lib/Zend/Locale/Data/es_US.xml | 355 - lib/Zend/Locale/Data/es_UY.xml | 39 - lib/Zend/Locale/Data/es_VE.xml | 33 - lib/Zend/Locale/Data/et.xml | 4826 ---------- lib/Zend/Locale/Data/et_EE.xml | 14 - lib/Zend/Locale/Data/eu.xml | 4137 --------- lib/Zend/Locale/Data/eu_ES.xml | 14 - lib/Zend/Locale/Data/ewo.xml | 783 -- lib/Zend/Locale/Data/ewo_CM.xml | 14 - lib/Zend/Locale/Data/fa.xml | 5812 ------------ lib/Zend/Locale/Data/fa_AF.xml | 277 - lib/Zend/Locale/Data/fa_IR.xml | 14 - lib/Zend/Locale/Data/ff.xml | 762 -- lib/Zend/Locale/Data/ff_CM.xml | 14 - lib/Zend/Locale/Data/ff_GN.xml | 21 - lib/Zend/Locale/Data/ff_MR.xml | 21 - lib/Zend/Locale/Data/ff_SN.xml | 14 - lib/Zend/Locale/Data/fi.xml | 5780 ------------ lib/Zend/Locale/Data/fi_FI.xml | 14 - lib/Zend/Locale/Data/fil.xml | 4002 --------- lib/Zend/Locale/Data/fil_PH.xml | 14 - lib/Zend/Locale/Data/fo.xml | 1686 ---- lib/Zend/Locale/Data/fo_FO.xml | 14 - lib/Zend/Locale/Data/fr.xml | 6771 -------------- lib/Zend/Locale/Data/fr_BE.xml | 210 - lib/Zend/Locale/Data/fr_BF.xml | 14 - lib/Zend/Locale/Data/fr_BI.xml | 21 - lib/Zend/Locale/Data/fr_BJ.xml | 14 - lib/Zend/Locale/Data/fr_BL.xml | 14 - lib/Zend/Locale/Data/fr_CA.xml | 559 -- lib/Zend/Locale/Data/fr_CD.xml | 21 - lib/Zend/Locale/Data/fr_CF.xml | 14 - lib/Zend/Locale/Data/fr_CG.xml | 14 - lib/Zend/Locale/Data/fr_CH.xml | 255 - lib/Zend/Locale/Data/fr_CI.xml | 14 - lib/Zend/Locale/Data/fr_CM.xml | 14 - lib/Zend/Locale/Data/fr_DJ.xml | 21 - lib/Zend/Locale/Data/fr_DZ.xml | 21 - lib/Zend/Locale/Data/fr_FR.xml | 14 - lib/Zend/Locale/Data/fr_GA.xml | 14 - lib/Zend/Locale/Data/fr_GF.xml | 14 - lib/Zend/Locale/Data/fr_GN.xml | 21 - lib/Zend/Locale/Data/fr_GP.xml | 14 - lib/Zend/Locale/Data/fr_GQ.xml | 14 - lib/Zend/Locale/Data/fr_HT.xml | 21 - lib/Zend/Locale/Data/fr_KM.xml | 21 - lib/Zend/Locale/Data/fr_LU.xml | 28 - lib/Zend/Locale/Data/fr_MA.xml | 14 - lib/Zend/Locale/Data/fr_MC.xml | 14 - lib/Zend/Locale/Data/fr_MF.xml | 14 - lib/Zend/Locale/Data/fr_MG.xml | 21 - lib/Zend/Locale/Data/fr_ML.xml | 14 - lib/Zend/Locale/Data/fr_MQ.xml | 14 - lib/Zend/Locale/Data/fr_MR.xml | 21 - lib/Zend/Locale/Data/fr_MU.xml | 21 - lib/Zend/Locale/Data/fr_NC.xml | 14 - lib/Zend/Locale/Data/fr_NE.xml | 14 - lib/Zend/Locale/Data/fr_PF.xml | 14 - lib/Zend/Locale/Data/fr_PM.xml | 14 - lib/Zend/Locale/Data/fr_RE.xml | 14 - lib/Zend/Locale/Data/fr_RW.xml | 21 - lib/Zend/Locale/Data/fr_SC.xml | 21 - lib/Zend/Locale/Data/fr_SN.xml | 14 - lib/Zend/Locale/Data/fr_SY.xml | 21 - lib/Zend/Locale/Data/fr_TD.xml | 14 - lib/Zend/Locale/Data/fr_TG.xml | 14 - lib/Zend/Locale/Data/fr_TN.xml | 21 - lib/Zend/Locale/Data/fr_VU.xml | 21 - lib/Zend/Locale/Data/fr_WF.xml | 14 - lib/Zend/Locale/Data/fr_YT.xml | 14 - lib/Zend/Locale/Data/fur.xml | 1668 ---- lib/Zend/Locale/Data/fur_IT.xml | 14 - lib/Zend/Locale/Data/fy.xml | 6954 --------------- lib/Zend/Locale/Data/fy_NL.xml | 14 - lib/Zend/Locale/Data/ga.xml | 1615 ---- lib/Zend/Locale/Data/ga_IE.xml | 14 - lib/Zend/Locale/Data/gd.xml | 1250 --- lib/Zend/Locale/Data/gd_GB.xml | 14 - lib/Zend/Locale/Data/genderList.xml | 21 - lib/Zend/Locale/Data/gl.xml | 3925 -------- lib/Zend/Locale/Data/gl_ES.xml | 14 - lib/Zend/Locale/Data/gsw.xml | 3911 -------- lib/Zend/Locale/Data/gsw_CH.xml | 14 - lib/Zend/Locale/Data/gsw_LI.xml | 14 - lib/Zend/Locale/Data/gu.xml | 5546 ------------ lib/Zend/Locale/Data/gu_IN.xml | 14 - lib/Zend/Locale/Data/guz.xml | 764 -- lib/Zend/Locale/Data/guz_KE.xml | 14 - lib/Zend/Locale/Data/gv.xml | 206 - lib/Zend/Locale/Data/gv_IM.xml | 14 - lib/Zend/Locale/Data/ha.xml | 843 -- lib/Zend/Locale/Data/ha_Latn.xml | 14 - lib/Zend/Locale/Data/ha_Latn_GH.xml | 22 - lib/Zend/Locale/Data/ha_Latn_NE.xml | 15 - lib/Zend/Locale/Data/ha_Latn_NG.xml | 15 - lib/Zend/Locale/Data/haw.xml | 315 - lib/Zend/Locale/Data/haw_US.xml | 14 - lib/Zend/Locale/Data/he.xml | 6121 ------------- lib/Zend/Locale/Data/he_IL.xml | 14 - lib/Zend/Locale/Data/hi.xml | 5954 ------------- lib/Zend/Locale/Data/hi_IN.xml | 14 - lib/Zend/Locale/Data/hr.xml | 6084 ------------- lib/Zend/Locale/Data/hr_BA.xml | 21 - lib/Zend/Locale/Data/hr_HR.xml | 14 - lib/Zend/Locale/Data/hu.xml | 5900 ------------ lib/Zend/Locale/Data/hu_HU.xml | 14 - lib/Zend/Locale/Data/hy.xml | 4971 ----------- lib/Zend/Locale/Data/hy_AM.xml | 14 - lib/Zend/Locale/Data/ia.xml | 554 -- lib/Zend/Locale/Data/ia_FR.xml | 14 - lib/Zend/Locale/Data/id.xml | 5984 ------------- lib/Zend/Locale/Data/id_ID.xml | 14 - lib/Zend/Locale/Data/ig.xml | 359 - lib/Zend/Locale/Data/ig_NG.xml | 14 - lib/Zend/Locale/Data/ii.xml | 231 - lib/Zend/Locale/Data/ii_CN.xml | 14 - lib/Zend/Locale/Data/is.xml | 4824 ---------- lib/Zend/Locale/Data/is_IS.xml | 14 - lib/Zend/Locale/Data/it.xml | 5159 ----------- lib/Zend/Locale/Data/it_CH.xml | 200 - lib/Zend/Locale/Data/it_IT.xml | 14 - lib/Zend/Locale/Data/it_SM.xml | 14 - lib/Zend/Locale/Data/ja.xml | 7868 ---------------- lib/Zend/Locale/Data/ja_JP.xml | 14 - lib/Zend/Locale/Data/jgo.xml | 608 -- lib/Zend/Locale/Data/jgo_CM.xml | 14 - lib/Zend/Locale/Data/jmc.xml | 761 -- lib/Zend/Locale/Data/jmc_TZ.xml | 14 - lib/Zend/Locale/Data/ka.xml | 5946 ------------- lib/Zend/Locale/Data/ka_GE.xml | 14 - lib/Zend/Locale/Data/kab.xml | 763 -- lib/Zend/Locale/Data/kab_DZ.xml | 14 - lib/Zend/Locale/Data/kam.xml | 763 -- lib/Zend/Locale/Data/kam_KE.xml | 14 - lib/Zend/Locale/Data/kde.xml | 766 -- lib/Zend/Locale/Data/kde_TZ.xml | 14 - lib/Zend/Locale/Data/kea.xml | 1665 ---- lib/Zend/Locale/Data/kea_CV.xml | 14 - lib/Zend/Locale/Data/khq.xml | 761 -- lib/Zend/Locale/Data/khq_ML.xml | 14 - lib/Zend/Locale/Data/ki.xml | 761 -- lib/Zend/Locale/Data/ki_KE.xml | 14 - lib/Zend/Locale/Data/kk.xml | 4875 ---------- lib/Zend/Locale/Data/kk_Cyrl.xml | 14 - lib/Zend/Locale/Data/kk_Cyrl_KZ.xml | 15 - lib/Zend/Locale/Data/kkj.xml | 319 - lib/Zend/Locale/Data/kkj_CM.xml | 14 - lib/Zend/Locale/Data/kl.xml | 1837 ---- lib/Zend/Locale/Data/kl_GL.xml | 14 - lib/Zend/Locale/Data/kln.xml | 768 -- lib/Zend/Locale/Data/kln_KE.xml | 14 - lib/Zend/Locale/Data/km.xml | 4504 ---------- lib/Zend/Locale/Data/km_KH.xml | 14 - lib/Zend/Locale/Data/kn.xml | 5207 ----------- lib/Zend/Locale/Data/kn_IN.xml | 14 - lib/Zend/Locale/Data/ko.xml | 6286 ------------- lib/Zend/Locale/Data/ko_KP.xml | 25 - lib/Zend/Locale/Data/ko_KR.xml | 14 - lib/Zend/Locale/Data/kok.xml | 330 - lib/Zend/Locale/Data/kok_IN.xml | 14 - lib/Zend/Locale/Data/ks.xml | 4135 --------- lib/Zend/Locale/Data/ks_Arab.xml | 14 - lib/Zend/Locale/Data/ks_Arab_IN.xml | 15 - lib/Zend/Locale/Data/ksb.xml | 763 -- lib/Zend/Locale/Data/ksb_TZ.xml | 14 - lib/Zend/Locale/Data/ksf.xml | 757 -- lib/Zend/Locale/Data/ksf_CM.xml | 14 - lib/Zend/Locale/Data/ksh.xml | 2973 ------- lib/Zend/Locale/Data/ksh_DE.xml | 14 - lib/Zend/Locale/Data/kw.xml | 273 - lib/Zend/Locale/Data/kw_GB.xml | 14 - lib/Zend/Locale/Data/ky.xml | 4961 ----------- lib/Zend/Locale/Data/ky_Cyrl.xml | 14 - lib/Zend/Locale/Data/ky_Cyrl_KG.xml | 15 - lib/Zend/Locale/Data/lag.xml | 753 -- lib/Zend/Locale/Data/lag_TZ.xml | 14 - lib/Zend/Locale/Data/languageInfo.xml | 151 - lib/Zend/Locale/Data/lg.xml | 756 -- lib/Zend/Locale/Data/lg_UG.xml | 14 - lib/Zend/Locale/Data/likelySubtags.xml | 1927 ---- lib/Zend/Locale/Data/lkt.xml | 545 -- lib/Zend/Locale/Data/lkt_US.xml | 14 - lib/Zend/Locale/Data/ln.xml | 1009 --- lib/Zend/Locale/Data/ln_AO.xml | 21 - lib/Zend/Locale/Data/ln_CD.xml | 14 - lib/Zend/Locale/Data/ln_CF.xml | 14 - lib/Zend/Locale/Data/ln_CG.xml | 14 - lib/Zend/Locale/Data/lo.xml | 6640 -------------- lib/Zend/Locale/Data/lo_LA.xml | 14 - lib/Zend/Locale/Data/lt.xml | 7291 --------------- lib/Zend/Locale/Data/lt_LT.xml | 14 - lib/Zend/Locale/Data/lu.xml | 775 -- lib/Zend/Locale/Data/lu_CD.xml | 14 - lib/Zend/Locale/Data/luo.xml | 761 -- lib/Zend/Locale/Data/luo_KE.xml | 14 - lib/Zend/Locale/Data/luy.xml | 763 -- lib/Zend/Locale/Data/luy_KE.xml | 14 - lib/Zend/Locale/Data/lv.xml | 5930 ------------- lib/Zend/Locale/Data/lv_LV.xml | 14 - lib/Zend/Locale/Data/mas.xml | 751 -- lib/Zend/Locale/Data/mas_KE.xml | 14 - lib/Zend/Locale/Data/mas_TZ.xml | 21 - lib/Zend/Locale/Data/mer.xml | 757 -- lib/Zend/Locale/Data/mer_KE.xml | 14 - lib/Zend/Locale/Data/metaZones.xml | 1849 ---- lib/Zend/Locale/Data/mfe.xml | 749 -- lib/Zend/Locale/Data/mfe_MU.xml | 14 - lib/Zend/Locale/Data/mg.xml | 750 -- lib/Zend/Locale/Data/mg_MG.xml | 14 - lib/Zend/Locale/Data/mgh.xml | 479 - lib/Zend/Locale/Data/mgh_MZ.xml | 14 - lib/Zend/Locale/Data/mgo.xml | 539 -- lib/Zend/Locale/Data/mgo_CM.xml | 14 - lib/Zend/Locale/Data/mk.xml | 5581 ------------ lib/Zend/Locale/Data/mk_MK.xml | 14 - lib/Zend/Locale/Data/ml.xml | 6149 ------------- lib/Zend/Locale/Data/ml_IN.xml | 14 - lib/Zend/Locale/Data/mn.xml | 4986 ----------- lib/Zend/Locale/Data/mn_Cyrl.xml | 14 - lib/Zend/Locale/Data/mn_Cyrl_MN.xml | 15 - lib/Zend/Locale/Data/mr.xml | 5584 ------------ lib/Zend/Locale/Data/mr_IN.xml | 14 - lib/Zend/Locale/Data/ms.xml | 3833 -------- lib/Zend/Locale/Data/ms_Latn.xml | 14 - lib/Zend/Locale/Data/ms_Latn_BN.xml | 56 - lib/Zend/Locale/Data/ms_Latn_MY.xml | 15 - lib/Zend/Locale/Data/ms_Latn_SG.xml | 22 - lib/Zend/Locale/Data/mt.xml | 1347 --- lib/Zend/Locale/Data/mt_MT.xml | 14 - lib/Zend/Locale/Data/mua.xml | 783 -- lib/Zend/Locale/Data/mua_CM.xml | 14 - lib/Zend/Locale/Data/my.xml | 4737 ---------- lib/Zend/Locale/Data/my_MM.xml | 14 - lib/Zend/Locale/Data/naq.xml | 762 -- lib/Zend/Locale/Data/naq_NA.xml | 14 - lib/Zend/Locale/Data/nb.xml | 5602 ------------ lib/Zend/Locale/Data/nb_NO.xml | 14 - lib/Zend/Locale/Data/nb_SJ.xml | 14 - lib/Zend/Locale/Data/nd.xml | 752 -- lib/Zend/Locale/Data/nd_ZW.xml | 14 - lib/Zend/Locale/Data/ne.xml | 5055 ----------- lib/Zend/Locale/Data/ne_IN.xml | 136 - lib/Zend/Locale/Data/ne_NP.xml | 14 - lib/Zend/Locale/Data/nl.xml | 6954 --------------- lib/Zend/Locale/Data/nl_AW.xml | 21 - lib/Zend/Locale/Data/nl_BE.xml | 124 - lib/Zend/Locale/Data/nl_BQ.xml | 21 - lib/Zend/Locale/Data/nl_CW.xml | 21 - lib/Zend/Locale/Data/nl_NL.xml | 14 - lib/Zend/Locale/Data/nl_SR.xml | 21 - lib/Zend/Locale/Data/nl_SX.xml | 21 - lib/Zend/Locale/Data/nmg.xml | 764 -- lib/Zend/Locale/Data/nmg_CM.xml | 14 - lib/Zend/Locale/Data/nn.xml | 3812 -------- lib/Zend/Locale/Data/nn_NO.xml | 14 - lib/Zend/Locale/Data/nnh.xml | 320 - lib/Zend/Locale/Data/nnh_CM.xml | 14 - lib/Zend/Locale/Data/nr.xml | 135 - lib/Zend/Locale/Data/nr_ZA.xml | 14 - lib/Zend/Locale/Data/nso.xml | 129 - lib/Zend/Locale/Data/nso_ZA.xml | 14 - lib/Zend/Locale/Data/numberingSystems.xml | 72 - lib/Zend/Locale/Data/nus.xml | 435 - lib/Zend/Locale/Data/nus_SD.xml | 14 - lib/Zend/Locale/Data/nyn.xml | 755 -- lib/Zend/Locale/Data/nyn_UG.xml | 14 - lib/Zend/Locale/Data/om.xml | 360 - lib/Zend/Locale/Data/om_ET.xml | 14 - lib/Zend/Locale/Data/om_KE.xml | 21 - lib/Zend/Locale/Data/or.xml | 1101 --- lib/Zend/Locale/Data/or_IN.xml | 14 - lib/Zend/Locale/Data/ordinals.xml | 130 - lib/Zend/Locale/Data/os.xml | 879 -- lib/Zend/Locale/Data/os_GE.xml | 14 - lib/Zend/Locale/Data/os_RU.xml | 21 - lib/Zend/Locale/Data/pa.xml | 4967 ----------- lib/Zend/Locale/Data/pa_Arab.xml | 230 - lib/Zend/Locale/Data/pa_Arab_PK.xml | 15 - lib/Zend/Locale/Data/pa_Guru.xml | 14 - lib/Zend/Locale/Data/pa_Guru_IN.xml | 15 - lib/Zend/Locale/Data/pl.xml | 6655 -------------- lib/Zend/Locale/Data/pl_PL.xml | 14 - lib/Zend/Locale/Data/plurals.xml | 225 - lib/Zend/Locale/Data/postalCodeData.xml | 171 - lib/Zend/Locale/Data/ps.xml | 407 - lib/Zend/Locale/Data/ps_AF.xml | 14 - lib/Zend/Locale/Data/pt.xml | 6115 ------------- lib/Zend/Locale/Data/pt_AO.xml | 53 - lib/Zend/Locale/Data/pt_BR.xml | 14 - lib/Zend/Locale/Data/pt_CV.xml | 57 - lib/Zend/Locale/Data/pt_GW.xml | 46 - lib/Zend/Locale/Data/pt_MO.xml | 53 - lib/Zend/Locale/Data/pt_MZ.xml | 53 - lib/Zend/Locale/Data/pt_PT.xml | 5553 ------------ lib/Zend/Locale/Data/pt_ST.xml | 53 - lib/Zend/Locale/Data/pt_TL.xml | 46 - lib/Zend/Locale/Data/rm.xml | 2793 ------ lib/Zend/Locale/Data/rm_CH.xml | 14 - lib/Zend/Locale/Data/rn.xml | 747 -- lib/Zend/Locale/Data/rn_BI.xml | 14 - lib/Zend/Locale/Data/ro.xml | 5595 ------------ lib/Zend/Locale/Data/ro_MD.xml | 21 - lib/Zend/Locale/Data/ro_RO.xml | 14 - lib/Zend/Locale/Data/rof.xml | 761 -- lib/Zend/Locale/Data/rof_TZ.xml | 14 - lib/Zend/Locale/Data/root.xml | 3771 -------- lib/Zend/Locale/Data/ru.xml | 7640 ---------------- lib/Zend/Locale/Data/ru_BY.xml | 24 - lib/Zend/Locale/Data/ru_KG.xml | 21 - lib/Zend/Locale/Data/ru_KZ.xml | 21 - lib/Zend/Locale/Data/ru_MD.xml | 21 - lib/Zend/Locale/Data/ru_RU.xml | 14 - lib/Zend/Locale/Data/ru_UA.xml | 190 - lib/Zend/Locale/Data/rw.xml | 296 - lib/Zend/Locale/Data/rw_RW.xml | 14 - lib/Zend/Locale/Data/rwk.xml | 761 -- lib/Zend/Locale/Data/rwk_TZ.xml | 14 - lib/Zend/Locale/Data/sah.xml | 417 - lib/Zend/Locale/Data/sah_RU.xml | 14 - lib/Zend/Locale/Data/saq.xml | 761 -- lib/Zend/Locale/Data/saq_KE.xml | 14 - lib/Zend/Locale/Data/sbp.xml | 765 -- lib/Zend/Locale/Data/sbp_TZ.xml | 14 - lib/Zend/Locale/Data/se.xml | 1700 ---- lib/Zend/Locale/Data/se_FI.xml | 85 - lib/Zend/Locale/Data/se_NO.xml | 14 - lib/Zend/Locale/Data/seh.xml | 738 -- lib/Zend/Locale/Data/seh_MZ.xml | 14 - lib/Zend/Locale/Data/ses.xml | 761 -- lib/Zend/Locale/Data/ses_ML.xml | 14 - lib/Zend/Locale/Data/sg.xml | 759 -- lib/Zend/Locale/Data/sg_CF.xml | 14 - lib/Zend/Locale/Data/shi.xml | 749 -- lib/Zend/Locale/Data/shi_Latn.xml | 751 -- lib/Zend/Locale/Data/shi_Latn_MA.xml | 15 - lib/Zend/Locale/Data/shi_Tfng.xml | 14 - lib/Zend/Locale/Data/shi_Tfng_MA.xml | 15 - lib/Zend/Locale/Data/si.xml | 4699 ---------- lib/Zend/Locale/Data/si_LK.xml | 14 - lib/Zend/Locale/Data/sk.xml | 5364 ----------- lib/Zend/Locale/Data/sk_SK.xml | 14 - lib/Zend/Locale/Data/sl.xml | 5048 ----------- lib/Zend/Locale/Data/sl_SI.xml | 14 - lib/Zend/Locale/Data/sn.xml | 754 -- lib/Zend/Locale/Data/sn_ZW.xml | 14 - lib/Zend/Locale/Data/so.xml | 869 -- lib/Zend/Locale/Data/so_DJ.xml | 21 - lib/Zend/Locale/Data/so_ET.xml | 21 - lib/Zend/Locale/Data/so_KE.xml | 21 - lib/Zend/Locale/Data/so_SO.xml | 14 - lib/Zend/Locale/Data/sq.xml | 4623 ---------- lib/Zend/Locale/Data/sq_AL.xml | 14 - lib/Zend/Locale/Data/sq_MK.xml | 21 - lib/Zend/Locale/Data/sq_XK.xml | 14 - lib/Zend/Locale/Data/sr.xml | 7182 --------------- lib/Zend/Locale/Data/sr_Cyrl.xml | 14 - lib/Zend/Locale/Data/sr_Cyrl_BA.xml | 146 - lib/Zend/Locale/Data/sr_Cyrl_ME.xml | 15 - lib/Zend/Locale/Data/sr_Cyrl_RS.xml | 15 - lib/Zend/Locale/Data/sr_Cyrl_XK.xml | 15 - lib/Zend/Locale/Data/sr_Latn.xml | 7183 --------------- lib/Zend/Locale/Data/sr_Latn_BA.xml | 15 - lib/Zend/Locale/Data/sr_Latn_ME.xml | 79 - lib/Zend/Locale/Data/sr_Latn_RS.xml | 15 - lib/Zend/Locale/Data/sr_Latn_XK.xml | 15 - lib/Zend/Locale/Data/ss.xml | 131 - lib/Zend/Locale/Data/ss_SZ.xml | 14 - lib/Zend/Locale/Data/ss_ZA.xml | 14 - lib/Zend/Locale/Data/ssy.xml | 215 - lib/Zend/Locale/Data/ssy_ER.xml | 14 - lib/Zend/Locale/Data/st.xml | 220 - lib/Zend/Locale/Data/st_LS.xml | 21 - lib/Zend/Locale/Data/st_ZA.xml | 14 - lib/Zend/Locale/Data/supplementalData.xml | 4980 ----------- lib/Zend/Locale/Data/supplementalMetadata.xml | 1889 ---- lib/Zend/Locale/Data/sv.xml | 6361 ------------- lib/Zend/Locale/Data/sv_AX.xml | 15 - lib/Zend/Locale/Data/sv_FI.xml | 188 - lib/Zend/Locale/Data/sv_SE.xml | 14 - lib/Zend/Locale/Data/sw.xml | 3678 -------- lib/Zend/Locale/Data/sw_KE.xml | 15 - lib/Zend/Locale/Data/sw_TZ.xml | 14 - lib/Zend/Locale/Data/sw_UG.xml | 21 - lib/Zend/Locale/Data/swc.xml | 775 -- lib/Zend/Locale/Data/swc_CD.xml | 14 - lib/Zend/Locale/Data/ta.xml | 5435 ------------ lib/Zend/Locale/Data/ta_IN.xml | 14 - lib/Zend/Locale/Data/ta_LK.xml | 21 - lib/Zend/Locale/Data/ta_MY.xml | 92 - lib/Zend/Locale/Data/ta_SG.xml | 95 - lib/Zend/Locale/Data/te.xml | 5600 ------------ lib/Zend/Locale/Data/te_IN.xml | 14 - lib/Zend/Locale/Data/telephoneCodeData.xml | 875 -- lib/Zend/Locale/Data/teo.xml | 761 -- lib/Zend/Locale/Data/teo_KE.xml | 21 - lib/Zend/Locale/Data/teo_UG.xml | 14 - lib/Zend/Locale/Data/tg.xml | 248 - lib/Zend/Locale/Data/tg_Cyrl.xml | 14 - lib/Zend/Locale/Data/tg_Cyrl_TJ.xml | 15 - lib/Zend/Locale/Data/th.xml | 7385 --------------- lib/Zend/Locale/Data/th_TH.xml | 14 - lib/Zend/Locale/Data/ti.xml | 609 -- lib/Zend/Locale/Data/ti_ER.xml | 204 - lib/Zend/Locale/Data/ti_ET.xml | 14 - lib/Zend/Locale/Data/tig.xml | 512 -- lib/Zend/Locale/Data/tig_ER.xml | 14 - lib/Zend/Locale/Data/tn.xml | 207 - lib/Zend/Locale/Data/tn_BW.xml | 21 - lib/Zend/Locale/Data/tn_ZA.xml | 14 - lib/Zend/Locale/Data/to.xml | 2943 ------ lib/Zend/Locale/Data/to_TO.xml | 14 - lib/Zend/Locale/Data/tr.xml | 5416 ----------- lib/Zend/Locale/Data/tr_CY.xml | 14 - lib/Zend/Locale/Data/tr_TR.xml | 14 - lib/Zend/Locale/Data/ts.xml | 168 - lib/Zend/Locale/Data/ts_ZA.xml | 14 - lib/Zend/Locale/Data/twq.xml | 780 -- lib/Zend/Locale/Data/twq_NE.xml | 14 - lib/Zend/Locale/Data/tzm.xml | 767 -- lib/Zend/Locale/Data/tzm_Latn.xml | 14 - lib/Zend/Locale/Data/tzm_Latn_MA.xml | 15 - lib/Zend/Locale/Data/ug.xml | 5105 ----------- lib/Zend/Locale/Data/ug_Arab.xml | 15 - lib/Zend/Locale/Data/ug_Arab_CN.xml | 16 - lib/Zend/Locale/Data/uk.xml | 7283 --------------- lib/Zend/Locale/Data/uk_UA.xml | 14 - lib/Zend/Locale/Data/ur.xml | 4857 ---------- lib/Zend/Locale/Data/ur_IN.xml | 192 - lib/Zend/Locale/Data/ur_PK.xml | 14 - lib/Zend/Locale/Data/uz.xml | 3345 ------- lib/Zend/Locale/Data/uz_Arab.xml | 225 - lib/Zend/Locale/Data/uz_Arab_AF.xml | 16 - lib/Zend/Locale/Data/uz_Cyrl.xml | 3259 ------- lib/Zend/Locale/Data/uz_Cyrl_UZ.xml | 15 - lib/Zend/Locale/Data/uz_Latn.xml | 14 - lib/Zend/Locale/Data/uz_Latn_UZ.xml | 15 - lib/Zend/Locale/Data/vai.xml | 677 -- lib/Zend/Locale/Data/vai_Latn.xml | 684 -- lib/Zend/Locale/Data/vai_Latn_LR.xml | 15 - lib/Zend/Locale/Data/vai_Vaii.xml | 14 - lib/Zend/Locale/Data/vai_Vaii_LR.xml | 15 - lib/Zend/Locale/Data/ve.xml | 145 - lib/Zend/Locale/Data/ve_ZA.xml | 14 - lib/Zend/Locale/Data/vi.xml | 5146 ----------- lib/Zend/Locale/Data/vi_VN.xml | 14 - lib/Zend/Locale/Data/vo.xml | 312 - lib/Zend/Locale/Data/vo_001.xml | 14 - lib/Zend/Locale/Data/vun.xml | 761 -- lib/Zend/Locale/Data/vun_TZ.xml | 14 - lib/Zend/Locale/Data/wae.xml | 1340 --- lib/Zend/Locale/Data/wae_CH.xml | 14 - lib/Zend/Locale/Data/wal.xml | 375 - lib/Zend/Locale/Data/wal_ET.xml | 14 - lib/Zend/Locale/Data/windowsZones.xml | 653 -- lib/Zend/Locale/Data/xh.xml | 264 - lib/Zend/Locale/Data/xh_ZA.xml | 14 - lib/Zend/Locale/Data/xog.xml | 759 -- lib/Zend/Locale/Data/xog_UG.xml | 14 - lib/Zend/Locale/Data/yav.xml | 670 -- lib/Zend/Locale/Data/yav_CM.xml | 14 - lib/Zend/Locale/Data/yo.xml | 796 -- lib/Zend/Locale/Data/yo_BJ.xml | 797 -- lib/Zend/Locale/Data/yo_NG.xml | 14 - lib/Zend/Locale/Data/zgh.xml | 755 -- lib/Zend/Locale/Data/zgh_MA.xml | 14 - lib/Zend/Locale/Data/zh.xml | 7184 --------------- lib/Zend/Locale/Data/zh_Hans.xml | 14 - lib/Zend/Locale/Data/zh_Hans_CN.xml | 15 - lib/Zend/Locale/Data/zh_Hans_HK.xml | 608 -- lib/Zend/Locale/Data/zh_Hans_MO.xml | 509 -- lib/Zend/Locale/Data/zh_Hans_SG.xml | 587 -- lib/Zend/Locale/Data/zh_Hant.xml | 7580 ---------------- lib/Zend/Locale/Data/zh_Hant_HK.xml | 938 -- lib/Zend/Locale/Data/zh_Hant_MO.xml | 186 - lib/Zend/Locale/Data/zh_Hant_TW.xml | 15 - lib/Zend/Locale/Data/zu.xml | 3229 ------- lib/Zend/Locale/Data/zu_ZA.xml | 14 - lib/Zend/Locale/Exception.php | 37 - lib/Zend/Locale/Format.php | 1342 --- lib/Zend/Locale/Math.php | 355 - lib/Zend/Locale/Math/Exception.php | 53 - lib/Zend/Locale/Math/PhpMath.php | 247 - lib/Zend/Log.php | 662 -- lib/Zend/Log/Exception.php | 33 - lib/Zend/Log/FactoryInterface.php | 38 - lib/Zend/Log/Filter/Abstract.php | 60 - lib/Zend/Log/Filter/Interface.php | 40 - lib/Zend/Log/Filter/Message.php | 85 - lib/Zend/Log/Filter/Priority.php | 101 - lib/Zend/Log/Filter/Suppress.php | 77 - lib/Zend/Log/Formatter/Abstract.php | 40 - lib/Zend/Log/Formatter/Firebug.php | 61 - lib/Zend/Log/Formatter/Interface.php | 41 - lib/Zend/Log/Formatter/Simple.php | 108 - lib/Zend/Log/Formatter/Xml.php | 165 - lib/Zend/Log/Writer/Abstract.php | 141 - lib/Zend/Log/Writer/Db.php | 147 - lib/Zend/Log/Writer/Firebug.php | 204 - lib/Zend/Log/Writer/Mail.php | 430 - lib/Zend/Log/Writer/Mock.php | 81 - lib/Zend/Log/Writer/Null.php | 56 - lib/Zend/Log/Writer/Stream.php | 138 - lib/Zend/Log/Writer/Syslog.php | 267 - lib/Zend/Log/Writer/ZendMonitor.php | 131 - lib/Zend/Mail.php | 1276 --- lib/Zend/Mail/Exception.php | 37 - lib/Zend/Mail/Header/HeaderName.php | 92 - lib/Zend/Mail/Header/HeaderValue.php | 136 - lib/Zend/Mail/Message.php | 113 - lib/Zend/Mail/Message/File.php | 96 - lib/Zend/Mail/Message/Interface.php | 55 - lib/Zend/Mail/Part.php | 603 -- lib/Zend/Mail/Part/File.php | 198 - lib/Zend/Mail/Part/Interface.php | 136 - lib/Zend/Mail/Protocol/Abstract.php | 447 - lib/Zend/Mail/Protocol/Exception.php | 39 - lib/Zend/Mail/Protocol/Imap.php | 838 -- lib/Zend/Mail/Protocol/Pop3.php | 472 - lib/Zend/Mail/Protocol/Smtp.php | 443 - lib/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php | 108 - lib/Zend/Mail/Protocol/Smtp/Auth/Login.php | 98 - lib/Zend/Mail/Protocol/Smtp/Auth/Plain.php | 96 - lib/Zend/Mail/Storage.php | 40 - lib/Zend/Mail/Storage/Abstract.php | 366 - lib/Zend/Mail/Storage/Exception.php | 39 - lib/Zend/Mail/Storage/Folder.php | 236 - lib/Zend/Mail/Storage/Folder/Interface.php | 60 - lib/Zend/Mail/Storage/Folder/Maildir.php | 265 - lib/Zend/Mail/Storage/Folder/Mbox.php | 264 - lib/Zend/Mail/Storage/Imap.php | 646 -- lib/Zend/Mail/Storage/Maildir.php | 475 - lib/Zend/Mail/Storage/Mbox.php | 447 - lib/Zend/Mail/Storage/Pop3.php | 328 - lib/Zend/Mail/Storage/Writable/Interface.php | 108 - lib/Zend/Mail/Storage/Writable/Maildir.php | 1049 --- lib/Zend/Mail/Transport/Abstract.php | 350 - lib/Zend/Mail/Transport/Exception.php | 39 - lib/Zend/Mail/Transport/File.php | 134 - lib/Zend/Mail/Transport/Sendmail.php | 226 - lib/Zend/Mail/Transport/Smtp.php | 243 - lib/Zend/Markup.php | 134 - lib/Zend/Markup/Exception.php | 38 - lib/Zend/Markup/Parser/Bbcode.php | 504 -- lib/Zend/Markup/Parser/Exception.php | 40 - lib/Zend/Markup/Parser/ParserInterface.php | 67 - lib/Zend/Markup/Renderer/Exception.php | 40 - lib/Zend/Markup/Renderer/Html.php | 528 -- lib/Zend/Markup/Renderer/Html/Code.php | 53 - .../Markup/Renderer/Html/HtmlAbstract.php | 69 - lib/Zend/Markup/Renderer/Html/Img.php | 84 - lib/Zend/Markup/Renderer/Html/List.php | 103 - lib/Zend/Markup/Renderer/Html/Url.php | 77 - lib/Zend/Markup/Renderer/RendererAbstract.php | 702 -- .../Renderer/TokenConverterInterface.php | 44 - lib/Zend/Markup/Token.php | 306 - lib/Zend/Markup/TokenList.php | 124 - lib/Zend/Measure/Abstract.php | 418 - lib/Zend/Measure/Acceleration.php | 91 - lib/Zend/Measure/Angle.php | 78 - lib/Zend/Measure/Area.php | 310 - lib/Zend/Measure/Binary.php | 122 - lib/Zend/Measure/Capacitance.php | 98 - lib/Zend/Measure/Cooking/Volume.php | 190 - lib/Zend/Measure/Cooking/Weight.php | 70 - lib/Zend/Measure/Current.php | 102 - lib/Zend/Measure/Density.php | 206 - lib/Zend/Measure/Energy.php | 252 - lib/Zend/Measure/Exception.php | 37 - lib/Zend/Measure/Flow/Mass.php | 122 - lib/Zend/Measure/Flow/Mole.php | 90 - lib/Zend/Measure/Flow/Volume.php | 402 - lib/Zend/Measure/Force.php | 126 - lib/Zend/Measure/Frequency.php | 86 - lib/Zend/Measure/Illumination.php | 72 - lib/Zend/Measure/Length.php | 674 -- lib/Zend/Measure/Lightness.php | 80 - lib/Zend/Measure/Number.php | 426 - lib/Zend/Measure/Power.php | 188 - lib/Zend/Measure/Pressure.php | 250 - lib/Zend/Measure/Speed.php | 190 - lib/Zend/Measure/Temperature.php | 60 - lib/Zend/Measure/Time.php | 117 - lib/Zend/Measure/Torque.php | 82 - lib/Zend/Measure/Viscosity/Dynamic.php | 120 - lib/Zend/Measure/Viscosity/Kinematic.php | 106 - lib/Zend/Measure/Volume.php | 213 - lib/Zend/Measure/Weight.php | 480 - lib/Zend/Memory.php | 82 - lib/Zend/Memory/AccessController.php | 149 - lib/Zend/Memory/Container.php | 35 - lib/Zend/Memory/Container/Interface.php | 66 - lib/Zend/Memory/Container/Locked.php | 113 - lib/Zend/Memory/Container/Movable.php | 297 - lib/Zend/Memory/Exception.php | 35 - lib/Zend/Memory/Manager.php | 463 - lib/Zend/Memory/Value.php | 177 - lib/Zend/Mime.php | 670 -- lib/Zend/Mime/Decode.php | 276 - lib/Zend/Mime/Exception.php | 36 - lib/Zend/Mime/Message.php | 305 - lib/Zend/Mime/Part.php | 333 - lib/Zend/Mobile/Exception.php | 33 - lib/Zend/Mobile/Push/Abstract.php | 112 - lib/Zend/Mobile/Push/Apns.php | 399 - lib/Zend/Mobile/Push/Exception.php | 35 - .../Push/Exception/DeviceQuotaExceeded.php | 35 - .../Push/Exception/InvalidAuthToken.php | 35 - .../Mobile/Push/Exception/InvalidPayload.php | 35 - .../Push/Exception/InvalidRegistration.php | 35 - .../Mobile/Push/Exception/InvalidToken.php | 35 - .../Mobile/Push/Exception/InvalidTopic.php | 35 - .../Mobile/Push/Exception/QuotaExceeded.php | 35 - .../Push/Exception/ServerUnavailable.php | 35 - lib/Zend/Mobile/Push/Gcm.php | 168 - lib/Zend/Mobile/Push/Interface.php | 64 - lib/Zend/Mobile/Push/Message/Abstract.php | 136 - lib/Zend/Mobile/Push/Message/Apns.php | 285 - lib/Zend/Mobile/Push/Message/Exception.php | 35 - lib/Zend/Mobile/Push/Message/Gcm.php | 277 - lib/Zend/Mobile/Push/Message/Interface.php | 79 - lib/Zend/Mobile/Push/Message/Mpns.php | 117 - lib/Zend/Mobile/Push/Message/Mpns/Raw.php | 152 - lib/Zend/Mobile/Push/Message/Mpns/Tile.php | 365 - lib/Zend/Mobile/Push/Message/Mpns/Toast.php | 225 - lib/Zend/Mobile/Push/Mpns.php | 158 - lib/Zend/Mobile/Push/Response/Gcm.php | 243 - lib/Zend/Mobile/Push/Test/ApnsProxy.php | 102 - lib/Zend/Navigation.php | 54 - lib/Zend/Navigation/Container.php | 623 -- lib/Zend/Navigation/Exception.php | 38 - lib/Zend/Navigation/Page.php | 1367 --- lib/Zend/Navigation/Page/Mvc.php | 696 -- lib/Zend/Navigation/Page/Uri.php | 111 - lib/Zend/Oauth.php | 90 - lib/Zend/Oauth/Client.php | 329 - lib/Zend/Oauth/Config.php | 691 -- lib/Zend/Oauth/Config/ConfigInterface.php | 79 - lib/Zend/Oauth/Consumer.php | 279 - lib/Zend/Oauth/Exception.php | 33 - lib/Zend/Oauth/Http.php | 266 - lib/Zend/Oauth/Http/AccessToken.php | 189 - lib/Zend/Oauth/Http/RequestToken.php | 162 - lib/Zend/Oauth/Http/UserAuthorization.php | 78 - lib/Zend/Oauth/Http/Utility.php | 217 - lib/Zend/Oauth/Signature/Hmac.php | 54 - lib/Zend/Oauth/Signature/Plaintext.php | 49 - lib/Zend/Oauth/Signature/Rsa.php | 65 - .../Oauth/Signature/SignatureAbstract.php | 183 - lib/Zend/Oauth/Token.php | 285 - lib/Zend/Oauth/Token/Access.php | 99 - lib/Zend/Oauth/Token/AuthorizedRequest.php | 102 - lib/Zend/Oauth/Token/Request.php | 50 - lib/Zend/OpenId.php | 758 -- lib/Zend/OpenId/Consumer.php | 999 --- lib/Zend/OpenId/Consumer/Storage.php | 132 - lib/Zend/OpenId/Consumer/Storage/File.php | 511 -- lib/Zend/OpenId/Exception.php | 58 - lib/Zend/OpenId/Extension.php | 137 - lib/Zend/OpenId/Extension/Sreg.php | 300 - lib/Zend/OpenId/Provider.php | 803 -- lib/Zend/OpenId/Provider/Storage.php | 106 - lib/Zend/OpenId/Provider/Storage/File.php | 442 - lib/Zend/OpenId/Provider/User.php | 57 - lib/Zend/OpenId/Provider/User/Session.php | 104 - lib/Zend/Paginator.php | 1173 --- lib/Zend/Paginator/Adapter/Array.php | 81 - lib/Zend/Paginator/Adapter/DbSelect.php | 290 - lib/Zend/Paginator/Adapter/DbTableSelect.php | 48 - lib/Zend/Paginator/Adapter/Interface.php | 40 - lib/Zend/Paginator/Adapter/Iterator.php | 102 - lib/Zend/Paginator/Adapter/Null.php | 80 - lib/Zend/Paginator/AdapterAggregate.php | 40 - lib/Zend/Paginator/Exception.php | 35 - lib/Zend/Paginator/ScrollingStyle/All.php | 50 - lib/Zend/Paginator/ScrollingStyle/Elastic.php | 63 - .../Paginator/ScrollingStyle/Interface.php | 38 - lib/Zend/Paginator/ScrollingStyle/Jumping.php | 63 - lib/Zend/Paginator/ScrollingStyle/Sliding.php | 78 - .../Paginator/SerializableLimitIterator.php | 142 - lib/Zend/Pdf.php | 1635 ---- lib/Zend/Pdf/Action.php | 404 - lib/Zend/Pdf/Action/GoTo.php | 116 - lib/Zend/Pdf/Action/GoTo3DView.php | 39 - lib/Zend/Pdf/Action/GoToE.php | 38 - lib/Zend/Pdf/Action/GoToR.php | 38 - lib/Zend/Pdf/Action/Hide.php | 39 - lib/Zend/Pdf/Action/ImportData.php | 39 - lib/Zend/Pdf/Action/JavaScript.php | 39 - lib/Zend/Pdf/Action/Launch.php | 38 - lib/Zend/Pdf/Action/Movie.php | 38 - lib/Zend/Pdf/Action/Named.php | 39 - lib/Zend/Pdf/Action/Rendition.php | 39 - lib/Zend/Pdf/Action/ResetForm.php | 39 - lib/Zend/Pdf/Action/SetOCGState.php | 39 - lib/Zend/Pdf/Action/Sound.php | 39 - lib/Zend/Pdf/Action/SubmitForm.php | 39 - lib/Zend/Pdf/Action/Thread.php | 38 - lib/Zend/Pdf/Action/Trans.php | 39 - lib/Zend/Pdf/Action/URI.php | 167 - lib/Zend/Pdf/Action/Unknown.php | 38 - lib/Zend/Pdf/Annotation.php | 230 - lib/Zend/Pdf/Annotation/FileAttachment.php | 101 - lib/Zend/Pdf/Annotation/Link.php | 163 - lib/Zend/Pdf/Annotation/Markup.php | 142 - lib/Zend/Pdf/Annotation/Text.php | 95 - lib/Zend/Pdf/Canvas.php | 182 - lib/Zend/Pdf/Canvas/Abstract.php | 1217 --- lib/Zend/Pdf/Canvas/Interface.php | 493 -- lib/Zend/Pdf/Cmap.php | 336 - lib/Zend/Pdf/Cmap/ByteEncoding.php | 447 - lib/Zend/Pdf/Cmap/ByteEncoding/Static.php | 62 - lib/Zend/Pdf/Cmap/SegmentToDelta.php | 407 - lib/Zend/Pdf/Cmap/TrimmedTable.php | 231 - lib/Zend/Pdf/Color.php | 53 - lib/Zend/Pdf/Color/Cmyk.php | 126 - lib/Zend/Pdf/Color/GrayScale.php | 84 - lib/Zend/Pdf/Color/Html.php | 412 - lib/Zend/Pdf/Color/Rgb.php | 114 - lib/Zend/Pdf/Destination.php | 113 - lib/Zend/Pdf/Destination/Explicit.php | 122 - lib/Zend/Pdf/Destination/Fit.php | 75 - lib/Zend/Pdf/Destination/FitBoundingBox.php | 75 - .../FitBoundingBoxHorizontally.php | 98 - .../Destination/FitBoundingBoxVertically.php | 98 - lib/Zend/Pdf/Destination/FitHorizontally.php | 98 - lib/Zend/Pdf/Destination/FitRectangle.php | 171 - lib/Zend/Pdf/Destination/FitVertically.php | 98 - lib/Zend/Pdf/Destination/Named.php | 101 - lib/Zend/Pdf/Destination/Unknown.php | 37 - lib/Zend/Pdf/Destination/Zoom.php | 177 - lib/Zend/Pdf/Element.php | 176 - lib/Zend/Pdf/Element/Array.php | 181 - lib/Zend/Pdf/Element/Boolean.php | 83 - lib/Zend/Pdf/Element/Dictionary.php | 236 - lib/Zend/Pdf/Element/Name.php | 161 - lib/Zend/Pdf/Element/Null.php | 75 - lib/Zend/Pdf/Element/Numeric.php | 95 - lib/Zend/Pdf/Element/Object.php | 284 - lib/Zend/Pdf/Element/Object/Stream.php | 453 - lib/Zend/Pdf/Element/Reference.php | 303 - lib/Zend/Pdf/Element/Reference/Context.php | 83 - lib/Zend/Pdf/Element/Reference/Table.php | 198 - lib/Zend/Pdf/Element/Stream.php | 130 - lib/Zend/Pdf/Element/String.php | 263 - lib/Zend/Pdf/Element/String/Binary.php | 98 - lib/Zend/Pdf/ElementFactory.php | 446 - lib/Zend/Pdf/ElementFactory/Interface.php | 158 - lib/Zend/Pdf/ElementFactory/Proxy.php | 234 - lib/Zend/Pdf/Exception.php | 343 - lib/Zend/Pdf/FileParser.php | 485 - lib/Zend/Pdf/FileParser/Font.php | 217 - lib/Zend/Pdf/FileParser/Font/OpenType.php | 1138 --- .../Pdf/FileParser/Font/OpenType/TrueType.php | 90 - lib/Zend/Pdf/FileParser/Image.php | 63 - lib/Zend/Pdf/FileParser/Image/Png.php | 329 - lib/Zend/Pdf/FileParserDataSource.php | 189 - lib/Zend/Pdf/FileParserDataSource/File.php | 198 - lib/Zend/Pdf/FileParserDataSource/String.php | 128 - lib/Zend/Pdf/Filter/Ascii85.php | 181 - lib/Zend/Pdf/Filter/AsciiHex.php | 135 - lib/Zend/Pdf/Filter/Compression.php | 391 - lib/Zend/Pdf/Filter/Compression/Flate.php | 102 - lib/Zend/Pdf/Filter/Compression/Lzw.php | 95 - lib/Zend/Pdf/Filter/Interface.php | 50 - lib/Zend/Pdf/Filter/RunLength.php | 125 - lib/Zend/Pdf/Font.php | 732 -- lib/Zend/Pdf/Image.php | 247 - lib/Zend/Pdf/NameTree.php | 154 - lib/Zend/Pdf/Outline.php | 373 - lib/Zend/Pdf/Outline/Created.php | 315 - lib/Zend/Pdf/Outline/Loaded.php | 460 - lib/Zend/Pdf/Page.php | 773 -- lib/Zend/Pdf/Parser.php | 472 - .../RecursivelyIteratableObjectsContainer.php | 45 - lib/Zend/Pdf/Resource.php | 165 - lib/Zend/Pdf/Resource/ContentStream.php | 114 - lib/Zend/Pdf/Resource/Extractor.php | 86 - lib/Zend/Pdf/Resource/Font.php | 530 -- lib/Zend/Pdf/Resource/Font/CidFont.php | 492 - .../Pdf/Resource/Font/CidFont/TrueType.php | 88 - lib/Zend/Pdf/Resource/Font/Extracted.php | 274 - lib/Zend/Pdf/Resource/Font/FontDescriptor.php | 204 - lib/Zend/Pdf/Resource/Font/Simple.php | 283 - lib/Zend/Pdf/Resource/Font/Simple/Parsed.php | 105 - .../Resource/Font/Simple/Parsed/TrueType.php | 67 - .../Pdf/Resource/Font/Simple/Standard.php | 82 - .../Resource/Font/Simple/Standard/Courier.php | 295 - .../Font/Simple/Standard/CourierBold.php | 296 - .../Simple/Standard/CourierBoldOblique.php | 297 - .../Font/Simple/Standard/CourierOblique.php | 297 - .../Font/Simple/Standard/Helvetica.php | 305 - .../Font/Simple/Standard/HelveticaBold.php | 305 - .../Simple/Standard/HelveticaBoldOblique.php | 308 - .../Font/Simple/Standard/HelveticaOblique.php | 307 - .../Resource/Font/Simple/Standard/Symbol.php | 465 - .../Font/Simple/Standard/TimesBold.php | 304 - .../Font/Simple/Standard/TimesBoldItalic.php | 305 - .../Font/Simple/Standard/TimesItalic.php | 305 - .../Font/Simple/Standard/TimesRoman.php | 305 - .../Font/Simple/Standard/ZapfDingbats.php | 491 - lib/Zend/Pdf/Resource/Font/Type0.php | 257 - lib/Zend/Pdf/Resource/GraphicsState.php | 109 - lib/Zend/Pdf/Resource/Image.php | 73 - lib/Zend/Pdf/Resource/Image/Jpeg.php | 152 - lib/Zend/Pdf/Resource/Image/Png.php | 380 - lib/Zend/Pdf/Resource/Image/Tiff.php | 442 - lib/Zend/Pdf/Resource/ImageFactory.php | 71 - lib/Zend/Pdf/Resource/Unified.php | 38 - lib/Zend/Pdf/StringParser.php | 725 -- lib/Zend/Pdf/Style.php | 294 - lib/Zend/Pdf/Target.php | 76 - lib/Zend/Pdf/Trailer.php | 126 - lib/Zend/Pdf/Trailer/Generator.php | 77 - lib/Zend/Pdf/Trailer/Keeper.php | 143 - lib/Zend/Pdf/UpdateInfoContainer.php | 131 - lib/Zend/ProgressBar.php | 209 - lib/Zend/ProgressBar/Adapter.php | 113 - lib/Zend/ProgressBar/Adapter/Console.php | 534 -- lib/Zend/ProgressBar/Adapter/Exception.php | 38 - lib/Zend/ProgressBar/Adapter/JsPull.php | 117 - lib/Zend/ProgressBar/Adapter/JsPush.php | 148 - lib/Zend/ProgressBar/Exception.php | 38 - lib/Zend/Queue.php | 569 -- lib/Zend/Queue/Adapter/Activemq.php | 366 - lib/Zend/Queue/Adapter/AdapterAbstract.php | 191 - lib/Zend/Queue/Adapter/AdapterInterface.php | 174 - lib/Zend/Queue/Adapter/Array.php | 355 - lib/Zend/Queue/Adapter/Db.php | 536 -- lib/Zend/Queue/Adapter/Db/Message.php | 51 - lib/Zend/Queue/Adapter/Db/Queue.php | 51 - lib/Zend/Queue/Adapter/Db/mysql.sql | 75 - lib/Zend/Queue/Adapter/Db/postgresql.sql | 49 - lib/Zend/Queue/Adapter/Db/queue_sqlite.sql | 41 - lib/Zend/Queue/Adapter/Db/sqlsrv.sql | 44 - lib/Zend/Queue/Adapter/Memcacheq.php | 428 - lib/Zend/Queue/Adapter/Null.php | 174 - lib/Zend/Queue/Adapter/PlatformJobQueue.php | 343 - lib/Zend/Queue/Exception.php | 35 - lib/Zend/Queue/Message.php | 230 - lib/Zend/Queue/Message/Iterator.php | 285 - lib/Zend/Queue/Message/PlatformJob.php | 194 - lib/Zend/Queue/Stomp/Client.php | 173 - lib/Zend/Queue/Stomp/Client/Connection.php | 280 - .../Stomp/Client/ConnectionInterface.php | 103 - lib/Zend/Queue/Stomp/Frame.php | 363 - lib/Zend/Queue/Stomp/FrameInterface.php | 154 - lib/Zend/Reflection/Class.php | 254 - lib/Zend/Reflection/Docblock.php | 294 - lib/Zend/Reflection/Docblock/Tag.php | 145 - lib/Zend/Reflection/Docblock/Tag/Param.php | 93 - lib/Zend/Reflection/Docblock/Tag/Return.php | 72 - lib/Zend/Reflection/Exception.php | 36 - lib/Zend/Reflection/Extension.php | 87 - lib/Zend/Reflection/File.php | 432 - lib/Zend/Reflection/Function.php | 131 - lib/Zend/Reflection/Method.php | 190 - lib/Zend/Reflection/Parameter.php | 127 - lib/Zend/Reflection/Property.php | 70 - lib/Zend/Registry.php | 210 - lib/Zend/Rest/Client.php | 287 - lib/Zend/Rest/Client/Exception.php | 40 - lib/Zend/Rest/Client/Result.php | 239 - lib/Zend/Rest/Client/Result/Exception.php | 36 - lib/Zend/Rest/Controller.php | 77 - lib/Zend/Rest/Exception.php | 37 - lib/Zend/Rest/Route.php | 413 - lib/Zend/Rest/Server.php | 677 -- lib/Zend/Rest/Server/Exception.php | 41 - lib/Zend/Search/Exception.php | 37 - lib/Zend/Search/Lucene.php | 1579 ---- lib/Zend/Search/Lucene/Analysis/Analyzer.php | 175 - .../Lucene/Analysis/Analyzer/Common.php | 94 - .../Lucene/Analysis/Analyzer/Common/Text.php | 96 - .../Analyzer/Common/Text/CaseInsensitive.php | 47 - .../Analysis/Analyzer/Common/TextNum.php | 95 - .../Common/TextNum/CaseInsensitive.php | 47 - .../Lucene/Analysis/Analyzer/Common/Utf8.php | 126 - .../Analyzer/Common/Utf8/CaseInsensitive.php | 49 - .../Analysis/Analyzer/Common/Utf8Num.php | 126 - .../Common/Utf8Num/CaseInsensitive.php | 49 - lib/Zend/Search/Lucene/Analysis/Token.php | 166 - .../Search/Lucene/Analysis/TokenFilter.php | 47 - .../Lucene/Analysis/TokenFilter/LowerCase.php | 52 - .../Analysis/TokenFilter/LowerCaseUtf8.php | 64 - .../Analysis/TokenFilter/ShortWords.php | 69 - .../Lucene/Analysis/TokenFilter/StopWords.php | 101 - lib/Zend/Search/Lucene/Document.php | 131 - lib/Zend/Search/Lucene/Document/Docx.php | 154 - lib/Zend/Search/Lucene/Document/Exception.php | 37 - lib/Zend/Search/Lucene/Document/Html.php | 481 - lib/Zend/Search/Lucene/Document/OpenXml.php | 131 - lib/Zend/Search/Lucene/Document/Pptx.php | 202 - lib/Zend/Search/Lucene/Document/Xlsx.php | 266 - lib/Zend/Search/Lucene/Exception.php | 37 - lib/Zend/Search/Lucene/FSM.php | 443 - lib/Zend/Search/Lucene/FSMAction.php | 66 - lib/Zend/Search/Lucene/Field.php | 226 - .../Search/Lucene/Index/DictionaryLoader.php | 268 - lib/Zend/Search/Lucene/Index/DocsFilter.php | 59 - lib/Zend/Search/Lucene/Index/FieldInfo.php | 50 - lib/Zend/Search/Lucene/Index/SegmentInfo.php | 2132 ----- .../Search/Lucene/Index/SegmentMerger.php | 271 - .../Search/Lucene/Index/SegmentWriter.php | 634 -- .../Index/SegmentWriter/DocumentWriter.php | 230 - .../Index/SegmentWriter/StreamWriter.php | 94 - lib/Zend/Search/Lucene/Index/Term.php | 144 - lib/Zend/Search/Lucene/Index/TermInfo.php | 80 - .../Lucene/Index/TermsPriorityQueue.php | 49 - .../Lucene/Index/TermsStream/Interface.php | 66 - lib/Zend/Search/Lucene/Index/Writer.php | 841 -- lib/Zend/Search/Lucene/Interface.php | 417 - .../Search/Lucene/Interface/MultiSearcher.php | 25 - lib/Zend/Search/Lucene/LockManager.php | 236 - lib/Zend/Search/Lucene/MultiSearcher.php | 992 --- lib/Zend/Search/Lucene/PriorityQueue.php | 171 - lib/Zend/Search/Lucene/Proxy.php | 612 -- .../Search/BooleanExpressionRecognizer.php | 278 - .../Lucene/Search/Highlighter/Default.php | 94 - .../Lucene/Search/Highlighter/Interface.php | 53 - lib/Zend/Search/Lucene/Search/Query.php | 233 - .../Search/Lucene/Search/Query/Boolean.php | 815 -- lib/Zend/Search/Lucene/Search/Query/Empty.php | 138 - lib/Zend/Search/Lucene/Search/Query/Fuzzy.php | 493 -- .../Lucene/Search/Query/Insignificant.php | 139 - .../Search/Lucene/Search/Query/MultiTerm.php | 668 -- .../Search/Lucene/Search/Query/Phrase.php | 576 -- .../Lucene/Search/Query/Preprocessing.php | 127 - .../Search/Query/Preprocessing/Fuzzy.php | 287 - .../Search/Query/Preprocessing/Phrase.php | 270 - .../Search/Query/Preprocessing/Term.php | 341 - lib/Zend/Search/Lucene/Search/Query/Range.php | 377 - lib/Zend/Search/Lucene/Search/Query/Term.php | 228 - .../Search/Lucene/Search/Query/Wildcard.php | 362 - lib/Zend/Search/Lucene/Search/QueryEntry.php | 67 - .../Lucene/Search/QueryEntry/Phrase.php | 116 - .../Lucene/Search/QueryEntry/Subquery.php | 77 - .../Search/Lucene/Search/QueryEntry/Term.php | 130 - lib/Zend/Search/Lucene/Search/QueryHit.php | 110 - lib/Zend/Search/Lucene/Search/QueryLexer.php | 510 -- lib/Zend/Search/Lucene/Search/QueryParser.php | 635 -- .../Lucene/Search/QueryParserContext.php | 401 - .../Lucene/Search/QueryParserException.php | 41 - lib/Zend/Search/Lucene/Search/QueryToken.php | 223 - lib/Zend/Search/Lucene/Search/Similarity.php | 551 -- .../Lucene/Search/Similarity/Default.php | 110 - lib/Zend/Search/Lucene/Search/Weight.php | 85 - .../Search/Lucene/Search/Weight/Boolean.php | 137 - .../Search/Lucene/Search/Weight/Empty.php | 57 - .../Search/Lucene/Search/Weight/MultiTerm.php | 139 - .../Search/Lucene/Search/Weight/Phrase.php | 108 - lib/Zend/Search/Lucene/Search/Weight/Term.php | 125 - lib/Zend/Search/Lucene/Storage/Directory.php | 136 - .../Lucene/Storage/Directory/Filesystem.php | 364 - lib/Zend/Search/Lucene/Storage/File.php | 473 - .../Search/Lucene/Storage/File/Filesystem.php | 231 - .../Search/Lucene/Storage/File/Memory.php | 601 -- .../Lucene/TermStreamsPriorityQueue.php | 172 - lib/Zend/Serializer.php | 188 - .../Serializer/Adapter/AdapterAbstract.php | 112 - .../Serializer/Adapter/AdapterInterface.php | 92 - lib/Zend/Serializer/Adapter/Amf0.php | 88 - lib/Zend/Serializer/Adapter/Amf3.php | 87 - lib/Zend/Serializer/Adapter/Igbinary.php | 98 - lib/Zend/Serializer/Adapter/Json.php | 90 - lib/Zend/Serializer/Adapter/PhpCode.php | 67 - lib/Zend/Serializer/Adapter/PhpSerialize.php | 94 - lib/Zend/Serializer/Adapter/PythonPickle.php | 1478 --- lib/Zend/Serializer/Adapter/Wddx.php | 124 - lib/Zend/Serializer/Exception.php | 33 - lib/Zend/Server/Abstract.php | 242 - lib/Zend/Server/Cache.php | 147 - lib/Zend/Server/Definition.php | 267 - lib/Zend/Server/Exception.php | 35 - lib/Zend/Server/Interface.php | 118 - lib/Zend/Server/Method/Callback.php | 205 - lib/Zend/Server/Method/Definition.php | 293 - lib/Zend/Server/Method/Parameter.php | 214 - lib/Zend/Server/Method/Prototype.php | 208 - lib/Zend/Server/Reflection.php | 111 - lib/Zend/Server/Reflection/Class.php | 198 - lib/Zend/Server/Reflection/Exception.php | 38 - lib/Zend/Server/Reflection/Function.php | 39 - .../Server/Reflection/Function/Abstract.php | 514 -- lib/Zend/Server/Reflection/Method.php | 110 - lib/Zend/Server/Reflection/Node.php | 201 - lib/Zend/Server/Reflection/Parameter.php | 161 - lib/Zend/Server/Reflection/Prototype.php | 103 - lib/Zend/Server/Reflection/ReturnValue.php | 110 - lib/Zend/Service/Abstract.php | 71 - lib/Zend/Service/Akismet.php | 387 - lib/Zend/Service/Amazon.php | 326 - lib/Zend/Service/Amazon/Abstract.php | 119 - lib/Zend/Service/Amazon/Accessories.php | 58 - lib/Zend/Service/Amazon/Authentication.php | 82 - .../Amazon/Authentication/Exception.php | 37 - lib/Zend/Service/Amazon/Authentication/S3.php | 112 - lib/Zend/Service/Amazon/Authentication/V1.php | 108 - lib/Zend/Service/Amazon/Authentication/V2.php | 138 - lib/Zend/Service/Amazon/CustomerReview.php | 86 - lib/Zend/Service/Amazon/Ec2.php | 87 - lib/Zend/Service/Amazon/Ec2/Abstract.php | 277 - .../Service/Amazon/Ec2/Availabilityzones.php | 76 - lib/Zend/Service/Amazon/Ec2/CloudWatch.php | 357 - lib/Zend/Service/Amazon/Ec2/Ebs.php | 342 - lib/Zend/Service/Amazon/Ec2/Elasticip.php | 158 - lib/Zend/Service/Amazon/Ec2/Exception.php | 51 - lib/Zend/Service/Amazon/Ec2/Image.php | 333 - lib/Zend/Service/Amazon/Ec2/Instance.php | 532 -- .../Service/Amazon/Ec2/Instance/Reserved.php | 143 - .../Service/Amazon/Ec2/Instance/Windows.php | 195 - lib/Zend/Service/Amazon/Ec2/Keypair.php | 137 - lib/Zend/Service/Amazon/Ec2/Region.php | 77 - lib/Zend/Service/Amazon/Ec2/Response.php | 164 - .../Service/Amazon/Ec2/Securitygroups.php | 301 - lib/Zend/Service/Amazon/EditorialReview.php | 58 - lib/Zend/Service/Amazon/Exception.php | 35 - lib/Zend/Service/Amazon/Image.php | 69 - lib/Zend/Service/Amazon/Item.php | 272 - lib/Zend/Service/Amazon/ListmaniaList.php | 58 - lib/Zend/Service/Amazon/Offer.php | 111 - lib/Zend/Service/Amazon/OfferSet.php | 118 - lib/Zend/Service/Amazon/Query.php | 98 - lib/Zend/Service/Amazon/ResultSet.php | 170 - lib/Zend/Service/Amazon/S3.php | 1015 --- lib/Zend/Service/Amazon/S3/Exception.php | 37 - lib/Zend/Service/Amazon/S3/Stream.php | 503 -- lib/Zend/Service/Amazon/SimilarProduct.php | 61 - lib/Zend/Service/Amazon/SimpleDb.php | 579 -- .../Service/Amazon/SimpleDb/Attribute.php | 108 - .../Service/Amazon/SimpleDb/Exception.php | 66 - lib/Zend/Service/Amazon/SimpleDb/Page.php | 124 - lib/Zend/Service/Amazon/SimpleDb/Response.php | 190 - lib/Zend/Service/Amazon/Sqs.php | 542 -- lib/Zend/Service/Amazon/Sqs/Exception.php | 38 - lib/Zend/Service/Audioscrobbler.php | 689 -- lib/Zend/Service/Console/Command.php | 413 - .../Console/Command/ParameterSource/Argv.php | 71 - .../Command/ParameterSource/ConfigFile.php | 104 - .../Console/Command/ParameterSource/Env.php | 75 - .../ParameterSourceInterface.php | 43 - .../Command/ParameterSource/Prompt.php | 66 - .../Console/Command/ParameterSource/StdIn.php | 81 - lib/Zend/Service/Console/Exception.php | 39 - lib/Zend/Service/Delicious.php | 618 -- lib/Zend/Service/Delicious/Exception.php | 39 - lib/Zend/Service/Delicious/Post.php | 292 - lib/Zend/Service/Delicious/PostList.php | 300 - lib/Zend/Service/Delicious/SimplePost.php | 123 - lib/Zend/Service/Ebay/Abstract.php | 309 - lib/Zend/Service/Ebay/Exception.php | 37 - lib/Zend/Service/Ebay/Finding.php | 424 - lib/Zend/Service/Ebay/Finding/Abstract.php | 169 - lib/Zend/Service/Ebay/Finding/Aspect.php | 68 - .../Finding/Aspect/Histogram/Container.php | 106 - .../Ebay/Finding/Aspect/Histogram/Value.php | 56 - .../Finding/Aspect/Histogram/Value/Set.php | 57 - lib/Zend/Service/Ebay/Finding/Aspect/Set.php | 57 - lib/Zend/Service/Ebay/Finding/Category.php | 73 - .../Ebay/Finding/Category/Histogram.php | 77 - .../Finding/Category/Histogram/Container.php | 66 - .../Ebay/Finding/Category/Histogram/Set.php | 57 - lib/Zend/Service/Ebay/Finding/Error/Data.php | 158 - .../Service/Ebay/Finding/Error/Data/Set.php | 57 - .../Service/Ebay/Finding/Error/Message.php | 60 - lib/Zend/Service/Ebay/Finding/Exception.php | 37 - lib/Zend/Service/Ebay/Finding/ListingInfo.php | 211 - .../Service/Ebay/Finding/PaginationOutput.php | 115 - .../Ebay/Finding/Response/Abstract.php | 185 - .../Ebay/Finding/Response/Histograms.php | 86 - .../Service/Ebay/Finding/Response/Items.php | 249 - .../Ebay/Finding/Response/Keywords.php | 78 - lib/Zend/Service/Ebay/Finding/Search/Item.php | 394 - .../Service/Ebay/Finding/Search/Item/Set.php | 57 - .../Service/Ebay/Finding/Search/Result.php | 63 - lib/Zend/Service/Ebay/Finding/SellerInfo.php | 144 - .../Service/Ebay/Finding/SellingStatus.php | 130 - .../Service/Ebay/Finding/Set/Abstract.php | 128 - .../Service/Ebay/Finding/ShippingInfo.php | 126 - lib/Zend/Service/Ebay/Finding/Storefront.php | 73 - lib/Zend/Service/Exception.php | 37 - lib/Zend/Service/Flickr.php | 624 -- lib/Zend/Service/Flickr/Image.php | 76 - lib/Zend/Service/Flickr/Result.php | 195 - lib/Zend/Service/Flickr/ResultSet.php | 188 - lib/Zend/Service/LiveDocx.php | 415 - lib/Zend/Service/LiveDocx/Exception.php | 39 - lib/Zend/Service/LiveDocx/MailMerge.php | 1138 --- lib/Zend/Service/Rackspace/Abstract.php | 392 - lib/Zend/Service/Rackspace/Exception.php | 36 - lib/Zend/Service/Rackspace/Files.php | 727 -- .../Service/Rackspace/Files/Container.php | 405 - .../Service/Rackspace/Files/ContainerList.php | 221 - .../Service/Rackspace/Files/Exception.php | 36 - lib/Zend/Service/Rackspace/Files/Object.php | 312 - .../Service/Rackspace/Files/ObjectList.php | 237 - lib/Zend/Service/Rackspace/Servers.php | 1281 --- .../Service/Rackspace/Servers/Exception.php | 36 - lib/Zend/Service/Rackspace/Servers/Image.php | 209 - .../Service/Rackspace/Servers/ImageList.php | 234 - lib/Zend/Service/Rackspace/Servers/Server.php | 325 - .../Service/Rackspace/Servers/ServerList.php | 235 - .../Rackspace/Servers/SharedIpGroup.php | 165 - .../Rackspace/Servers/SharedIpGroupList.php | 234 - lib/Zend/Service/ReCaptcha.php | 502 -- lib/Zend/Service/ReCaptcha/Exception.php | 36 - lib/Zend/Service/ReCaptcha/MailHide.php | 351 - .../Service/ReCaptcha/MailHide/Exception.php | 36 - lib/Zend/Service/ReCaptcha/Response.php | 164 - .../Service/ShortUrl/AbstractShortener.php | 83 - lib/Zend/Service/ShortUrl/BitLy.php | 167 - lib/Zend/Service/ShortUrl/Exception.php | 32 - lib/Zend/Service/ShortUrl/IsGd.php | 96 - lib/Zend/Service/ShortUrl/JdemCz.php | 84 - lib/Zend/Service/ShortUrl/MetamarkNet.php | 85 - lib/Zend/Service/ShortUrl/Shortener.php | 45 - lib/Zend/Service/ShortUrl/TinyUrlCom.php | 100 - lib/Zend/Service/SlideShare.php | 676 -- lib/Zend/Service/SlideShare/Exception.php | 38 - lib/Zend/Service/SlideShare/SlideShow.php | 464 - lib/Zend/Service/SqlAzure/Exception.php | 35 - .../Service/SqlAzure/Management/Client.php | 612 -- .../Service/SqlAzure/Management/Exception.php | 35 - .../Management/FirewallRuleInstance.php | 57 - .../SqlAzure/Management/ServerInstance.php | 59 - .../Management/ServiceEntityAbstract.php | 67 - lib/Zend/Service/StrikeIron.php | 92 - lib/Zend/Service/StrikeIron/Base.php | 274 - lib/Zend/Service/StrikeIron/Decorator.php | 143 - lib/Zend/Service/StrikeIron/Exception.php | 36 - .../Service/StrikeIron/SalesUseTaxBasic.php | 45 - .../StrikeIron/USAddressVerification.php | 45 - lib/Zend/Service/StrikeIron/ZipCodeInfo.php | 45 - lib/Zend/Service/Twitter.php | 1307 --- lib/Zend/Service/Twitter/Exception.php | 37 - lib/Zend/Service/Twitter/Response.php | 179 - .../WindowsAzure/CommandLine/Certificate.php | 180 - .../WindowsAzure/CommandLine/Deployment.php | 586 -- .../CommandLine/GetAsynchronousOperation.php | 98 - .../WindowsAzure/CommandLine/Package.php | 205 - .../PackageScaffolderAbstract.php | 251 - .../Scaffolders/DefaultScaffolder.phar | Bin 4404199 -> 0 bytes .../Scaffolders/DefaultScaffolder/build.bat | 1 - .../Scaffolders/DefaultScaffolder/index.php | 63 - .../resources/PhpOnAzure.Web/Web.config | 20 - .../bin/add-environment-variables.cmd | 7 - .../bin/add-environment-variables.ps1 | 15 - .../PhpOnAzure.Web/bin/install-php.cmd | 12 - .../PhpOnAzure.Web/diagnostics.wadcfg | 35 - .../WebPICmdLine/Microsoft.Web.Deployment.dll | Bin 1201991 -> 0 bytes .../Microsoft.Web.PlatformInstaller.UI.dll | Bin 546620 -> 0 bytes .../Microsoft.Web.PlatformInstaller.dll | Bin 333658 -> 0 bytes .../resources/WebPICmdLine/WebpiCmdLine.exe | Bin 94461 -> 0 bytes .../resources/WebPICmdLine/license.rtf | 41 - .../resources/ServiceConfiguration.cscfg | 9 - .../resources/ServiceDefinition.csdef | 24 - .../WindowsAzure/CommandLine/Service.php | 201 - .../WindowsAzure/CommandLine/Storage.php | 198 - .../Credentials/CredentialsAbstract.php | 235 - .../WindowsAzure/Credentials/Exception.php | 35 - .../Credentials/SharedAccessSignature.php | 298 - .../WindowsAzure/Credentials/SharedKey.php | 173 - .../Credentials/SharedKeyLite.php | 152 - .../Diagnostics/ConfigurationDataSources.php | 81 - ...figurationDiagnosticInfrastructureLogs.php | 53 - .../Diagnostics/ConfigurationDirectories.php | 85 - .../Diagnostics/ConfigurationInstance.php | 220 - .../Diagnostics/ConfigurationLogs.php | 62 - .../ConfigurationObjectBaseAbstract.php | 66 - .../ConfigurationPerformanceCounters.php | 85 - .../ConfigurationWindowsEventLog.php | 76 - .../DirectoryConfigurationSubscription.php | 53 - .../WindowsAzure/Diagnostics/Exception.php | 35 - .../WindowsAzure/Diagnostics/LogLevel.php | 39 - .../WindowsAzure/Diagnostics/Manager.php | 221 - .../PerformanceCounterSubscription.php | 54 - lib/Zend/Service/WindowsAzure/Exception.php | 35 - .../Service/WindowsAzure/Log/Exception.php | 38 - .../Log/Formatter/WindowsAzure.php | 73 - .../WindowsAzure/Log/Writer/WindowsAzure.php | 196 - .../Management/AffinityGroupInstance.php | 66 - .../Management/CertificateInstance.php | 60 - .../WindowsAzure/Management/Client.php | 2426 ----- .../Management/DeploymentInstance.php | 90 - .../WindowsAzure/Management/Exception.php | 38 - .../Management/HostedServiceInstance.php | 69 - .../Management/LocationInstance.php | 51 - .../OperatingSystemFamilyInstance.php | 57 - .../Management/OperatingSystemInstance.php | 66 - .../Management/OperationStatusInstance.php | 60 - .../Management/ServiceEntityAbstract.php | 67 - .../Management/StorageServiceInstance.php | 66 - .../SubscriptionOperationInstance.php | 77 - .../WindowsAzure/RetryPolicy/Exception.php | 36 - .../WindowsAzure/RetryPolicy/NoRetry.php | 58 - .../WindowsAzure/RetryPolicy/RetryN.php | 88 - .../RetryPolicy/RetryPolicyAbstract.php | 72 - .../Service/WindowsAzure/SessionHandler.php | 324 - lib/Zend/Service/WindowsAzure/Storage.php | 564 -- .../Service/WindowsAzure/Storage/Batch.php | 241 - .../Storage/BatchStorageAbstract.php | 174 - .../Service/WindowsAzure/Storage/Blob.php | 2142 ----- .../WindowsAzure/Storage/Blob/Stream.php | 544 -- .../WindowsAzure/Storage/BlobContainer.php | 90 - .../WindowsAzure/Storage/BlobInstance.php | 93 - .../Storage/DynamicTableEntity.php | 219 - .../WindowsAzure/Storage/LeaseInstance.php | 60 - .../Storage/PageRegionInstance.php | 54 - .../Service/WindowsAzure/Storage/Queue.php | 592 -- .../WindowsAzure/Storage/QueueInstance.php | 56 - .../WindowsAzure/Storage/QueueMessage.php | 69 - .../WindowsAzure/Storage/SignedIdentifier.php | 60 - .../Storage/StorageEntityAbstract.php | 67 - .../Service/WindowsAzure/Storage/Table.php | 931 -- .../WindowsAzure/Storage/TableEntity.php | 354 - .../WindowsAzure/Storage/TableEntityQuery.php | 351 - .../WindowsAzure/Storage/TableInstance.php | 60 - lib/Zend/Service/Yahoo.php | 951 -- lib/Zend/Service/Yahoo/Image.php | 71 - lib/Zend/Service/Yahoo/ImageResult.php | 111 - lib/Zend/Service/Yahoo/ImageResultSet.php | 63 - lib/Zend/Service/Yahoo/InlinkDataResult.php | 58 - .../Service/Yahoo/InlinkDataResultSet.php | 62 - lib/Zend/Service/Yahoo/LocalResult.php | 124 - lib/Zend/Service/Yahoo/LocalResultSet.php | 84 - lib/Zend/Service/Yahoo/NewsResult.php | 112 - lib/Zend/Service/Yahoo/NewsResultSet.php | 63 - lib/Zend/Service/Yahoo/PageDataResult.php | 58 - lib/Zend/Service/Yahoo/PageDataResultSet.php | 62 - lib/Zend/Service/Yahoo/Result.php | 126 - lib/Zend/Service/Yahoo/ResultSet.php | 195 - lib/Zend/Service/Yahoo/VideoResult.php | 132 - lib/Zend/Service/Yahoo/VideoResultSet.php | 63 - lib/Zend/Service/Yahoo/WebResult.php | 109 - lib/Zend/Service/Yahoo/WebResultSet.php | 63 - lib/Zend/Session.php | 912 -- lib/Zend/Session/Abstract.php | 185 - lib/Zend/Session/Exception.php | 74 - lib/Zend/Session/Namespace.php | 529 -- lib/Zend/Session/SaveHandler/DbTable.php | 591 -- lib/Zend/Session/SaveHandler/Exception.php | 37 - lib/Zend/Session/SaveHandler/Interface.php | 81 - lib/Zend/Session/Validator/Abstract.php | 71 - lib/Zend/Session/Validator/Exception.php | 43 - lib/Zend/Session/Validator/HttpUserAgent.php | 66 - lib/Zend/Session/Validator/Interface.php | 52 - lib/Zend/Soap/AutoDiscover.php | 611 -- lib/Zend/Soap/AutoDiscover/Exception.php | 34 - lib/Zend/Soap/Client.php | 1242 --- lib/Zend/Soap/Client/Common.php | 76 - lib/Zend/Soap/Client/DotNet.php | 95 - lib/Zend/Soap/Client/Exception.php | 35 - lib/Zend/Soap/Client/Local.php | 99 - lib/Zend/Soap/Server.php | 1022 --- lib/Zend/Soap/Server/Exception.php | 37 - lib/Zend/Soap/Server/Proxy.php | 75 - lib/Zend/Soap/Wsdl.php | 670 -- lib/Zend/Soap/Wsdl/Exception.php | 37 - lib/Zend/Soap/Wsdl/Strategy/Abstract.php | 66 - lib/Zend/Soap/Wsdl/Strategy/AnyType.php | 59 - .../Soap/Wsdl/Strategy/ArrayOfTypeComplex.php | 145 - .../Wsdl/Strategy/ArrayOfTypeSequence.php | 155 - lib/Zend/Soap/Wsdl/Strategy/Composite.php | 188 - .../Soap/Wsdl/Strategy/DefaultComplexType.php | 91 - lib/Zend/Soap/Wsdl/Strategy/Interface.php | 48 - lib/Zend/Stdlib/CallbackHandler.php | 304 - lib/Zend/Stdlib/Exception.php | 31 - .../Exception/InvalidCallbackException.php | 35 - lib/Zend/Stdlib/PriorityQueue.php | 319 - lib/Zend/Stdlib/SplPriorityQueue.php | 499 -- lib/Zend/Tag/Cloud.php | 410 - lib/Zend/Tag/Cloud/Decorator/Cloud.php | 88 - lib/Zend/Tag/Cloud/Decorator/Exception.php | 39 - lib/Zend/Tag/Cloud/Decorator/HtmlCloud.php | 155 - lib/Zend/Tag/Cloud/Decorator/HtmlTag.php | 306 - lib/Zend/Tag/Cloud/Decorator/Tag.php | 88 - lib/Zend/Tag/Cloud/Exception.php | 38 - lib/Zend/Tag/Exception.php | 38 - lib/Zend/Tag/Item.php | 220 - lib/Zend/Tag/ItemList.php | 238 - lib/Zend/Tag/Taggable.php | 60 - lib/Zend/Test/DbAdapter.php | 345 - lib/Zend/Test/DbStatement.php | 404 - lib/Zend/Test/PHPUnit/Constraint/DomQuery.php | 38 - .../Test/PHPUnit/Constraint/DomQuery34.php | 422 - .../Test/PHPUnit/Constraint/DomQuery37.php | 434 - .../Test/PHPUnit/Constraint/DomQuery41.php | 436 - .../Test/PHPUnit/Constraint/Exception.php | 35 - lib/Zend/Test/PHPUnit/Constraint/Redirect.php | 38 - .../Test/PHPUnit/Constraint/Redirect34.php | 303 - .../Test/PHPUnit/Constraint/Redirect37.php | 315 - .../Test/PHPUnit/Constraint/Redirect41.php | 317 - .../PHPUnit/Constraint/ResponseHeader.php | 38 - .../PHPUnit/Constraint/ResponseHeader34.php | 406 - .../PHPUnit/Constraint/ResponseHeader37.php | 419 - .../PHPUnit/Constraint/ResponseHeader41.php | 421 - lib/Zend/Test/PHPUnit/ControllerTestCase.php | 1165 --- lib/Zend/Test/PHPUnit/DatabaseTestCase.php | 146 - lib/Zend/Test/PHPUnit/Db/Connection.php | 144 - lib/Zend/Test/PHPUnit/Db/DataSet/DbRowset.php | 73 - lib/Zend/Test/PHPUnit/Db/DataSet/DbTable.php | 120 - .../PHPUnit/Db/DataSet/DbTableDataSet.php | 98 - .../Test/PHPUnit/Db/DataSet/QueryDataSet.php | 80 - .../Test/PHPUnit/Db/DataSet/QueryTable.php | 82 - lib/Zend/Test/PHPUnit/Db/Exception.php | 40 - lib/Zend/Test/PHPUnit/Db/Metadata/Generic.php | 182 - .../Test/PHPUnit/Db/Operation/DeleteAll.php | 60 - lib/Zend/Test/PHPUnit/Db/Operation/Insert.php | 84 - .../Test/PHPUnit/Db/Operation/Truncate.php | 110 - lib/Zend/Test/PHPUnit/Db/SimpleTester.php | 75 - lib/Zend/Text/Exception.php | 38 - lib/Zend/Text/Figlet.php | 1232 --- lib/Zend/Text/Figlet/Exception.php | 38 - lib/Zend/Text/Figlet/zend-framework.flf | 753 -- lib/Zend/Text/MultiByte.php | 143 - lib/Zend/Text/Table.php | 533 -- lib/Zend/Text/Table/Column.php | 243 - lib/Zend/Text/Table/Decorator/Ascii.php | 147 - lib/Zend/Text/Table/Decorator/Interface.php | 108 - lib/Zend/Text/Table/Decorator/Unicode.php | 176 - lib/Zend/Text/Table/Exception.php | 38 - lib/Zend/Text/Table/Row.php | 215 - lib/Zend/TimeSync.php | 304 - lib/Zend/TimeSync/Exception.php | 64 - lib/Zend/TimeSync/Ntp.php | 431 - lib/Zend/TimeSync/Protocol.php | 148 - lib/Zend/TimeSync/Sntp.php | 119 - lib/Zend/Tool/Framework/Action/Base.php | 95 - lib/Zend/Tool/Framework/Action/Exception.php | 37 - lib/Zend/Tool/Framework/Action/Interface.php | 32 - lib/Zend/Tool/Framework/Action/Repository.php | 138 - lib/Zend/Tool/Framework/Client/Abstract.php | 333 - lib/Zend/Tool/Framework/Client/Config.php | 244 - lib/Zend/Tool/Framework/Client/Console.php | 312 - .../Client/Console/ArgumentParser.php | 539 -- .../Framework/Client/Console/HelpSystem.php | 378 - .../Framework/Client/Console/Manifest.php | 209 - .../Console/ResponseDecorator/AlignCenter.php | 66 - .../Console/ResponseDecorator/Blockize.php | 69 - .../Console/ResponseDecorator/Colorizer.php | 92 - .../Console/ResponseDecorator/Indention.php | 56 - lib/Zend/Tool/Framework/Client/Exception.php | 36 - .../Client/Interactive/InputHandler.php | 74 - .../Client/Interactive/InputInterface.php | 41 - .../Client/Interactive/InputRequest.php | 54 - .../Client/Interactive/InputResponse.php | 52 - .../Client/Interactive/OutputInterface.php | 33 - lib/Zend/Tool/Framework/Client/Manifest.php | 206 - lib/Zend/Tool/Framework/Client/Request.php | 299 - lib/Zend/Tool/Framework/Client/Response.php | 223 - .../Response/ContentDecorator/Interface.php | 35 - .../Response/ContentDecorator/Separator.php | 93 - lib/Zend/Tool/Framework/Client/Storage.php | 117 - .../Client/Storage/AdapterInterface.php | 42 - .../Framework/Client/Storage/Directory.php | 73 - lib/Zend/Tool/Framework/Exception.php | 36 - lib/Zend/Tool/Framework/Loader/Abstract.php | 156 - .../Tool/Framework/Loader/BasicLoader.php | 157 - .../Framework/Loader/IncludePathLoader.php | 139 - .../RecursiveFilterIterator.php | 93 - lib/Zend/Tool/Framework/Loader/Interface.php | 42 - .../Framework/Manifest/ActionManifestable.php | 47 - .../Framework/Manifest/ActionMetadata.php | 31 - .../Tool/Framework/Manifest/Exception.php | 37 - .../Tool/Framework/Manifest/Indexable.php | 42 - .../Tool/Framework/Manifest/Interface.php | 82 - lib/Zend/Tool/Framework/Manifest/Metadata.php | 31 - .../Manifest/MetadataManifestable.php | 47 - .../Manifest/ProviderManifestable.php | 47 - .../Framework/Manifest/ProviderMetadata.php | 31 - .../Tool/Framework/Manifest/Repository.php | 313 - .../Tool/Framework/Metadata/Attributable.php | 33 - lib/Zend/Tool/Framework/Metadata/Basic.php | 227 - lib/Zend/Tool/Framework/Metadata/Dynamic.php | 219 - .../Tool/Framework/Metadata/Interface.php | 52 - lib/Zend/Tool/Framework/Metadata/Tool.php | 218 - lib/Zend/Tool/Framework/Provider/Abstract.php | 68 - .../Provider/DocblockManifestable.php | 30 - .../Tool/Framework/Provider/Exception.php | 37 - .../Tool/Framework/Provider/Initializable.php | 31 - .../Tool/Framework/Provider/Interactable.php | 30 - .../Tool/Framework/Provider/Interface.php | 31 - .../Tool/Framework/Provider/Pretendable.php | 31 - .../Tool/Framework/Provider/Repository.php | 275 - .../Tool/Framework/Provider/Signature.php | 394 - lib/Zend/Tool/Framework/Registry.php | 419 - .../Framework/Registry/EnabledInterface.php | 40 - .../Tool/Framework/Registry/Exception.php | 33 - .../Tool/Framework/Registry/Interface.php | 137 - .../Tool/Framework/System/Action/Create.php | 44 - .../Tool/Framework/System/Action/Delete.php | 44 - lib/Zend/Tool/Framework/System/Manifest.php | 63 - .../Tool/Framework/System/Provider/Config.php | 323 - .../Framework/System/Provider/Manifest.php | 114 - .../Framework/System/Provider/Phpinfo.php | 38 - .../Framework/System/Provider/Version.php | 111 - .../Tool/Project/Context/Content/Engine.php | 106 - .../Context/Content/Engine/CodeGenerator.php | 98 - .../Project/Context/Content/Engine/Phtml.php | 89 - lib/Zend/Tool/Project/Context/Exception.php | 33 - .../Project/Context/Filesystem/Abstract.php | 165 - .../Project/Context/Filesystem/Directory.php | 87 - .../Tool/Project/Context/Filesystem/File.php | 174 - lib/Zend/Tool/Project/Context/Interface.php | 38 - lib/Zend/Tool/Project/Context/Repository.php | 189 - .../Tool/Project/Context/System/Interface.php | 37 - .../Context/System/NotOverwritable.php | 37 - .../Context/System/ProjectDirectory.php | 128 - .../Context/System/ProjectProfileFile.php | 118 - .../System/ProjectProvidersDirectory.php | 87 - .../Context/System/TopLevelRestrictable.php | 37 - .../Project/Context/Zf/AbstractClassFile.php | 84 - .../Tool/Project/Context/Zf/ActionMethod.php | 224 - .../Tool/Project/Context/Zf/ApisDirectory.php | 55 - .../Context/Zf/ApplicationConfigFile.php | 285 - .../Context/Zf/ApplicationDirectory.php | 81 - .../Tool/Project/Context/Zf/BootstrapFile.php | 119 - .../Project/Context/Zf/CacheDirectory.php | 57 - .../Tool/Project/Context/Zf/ConfigFile.php | 67 - .../Project/Context/Zf/ConfigsDirectory.php | 57 - .../Project/Context/Zf/ControllerFile.php | 223 - .../Context/Zf/ControllersDirectory.php | 57 - .../Tool/Project/Context/Zf/DataDirectory.php | 57 - .../Project/Context/Zf/DbTableDirectory.php | 57 - .../Tool/Project/Context/Zf/DbTableFile.php | 92 - .../Tool/Project/Context/Zf/DocsDirectory.php | 61 - lib/Zend/Tool/Project/Context/Zf/FormFile.php | 113 - .../Project/Context/Zf/FormsDirectory.php | 57 - .../Tool/Project/Context/Zf/HtaccessFile.php | 87 - .../Project/Context/Zf/LayoutScriptFile.php | 109 - .../Context/Zf/LayoutScriptsDirectory.php | 57 - .../Project/Context/Zf/LayoutsDirectory.php | 57 - .../Project/Context/Zf/LibraryDirectory.php | 57 - .../Project/Context/Zf/LocalesDirectory.php | 57 - .../Tool/Project/Context/Zf/LogsDirectory.php | 57 - .../Tool/Project/Context/Zf/ModelFile.php | 107 - .../Project/Context/Zf/ModelsDirectory.php | 57 - .../Project/Context/Zf/ModuleDirectory.php | 97 - .../Project/Context/Zf/ModulesDirectory.php | 57 - .../Context/Zf/ProjectProviderFile.php | 152 - .../Project/Context/Zf/PublicDirectory.php | 57 - .../Context/Zf/PublicImagesDirectory.php | 57 - .../Project/Context/Zf/PublicIndexFile.php | 95 - .../Context/Zf/PublicScriptsDirectory.php | 57 - .../Context/Zf/PublicStylesheetsDirectory.php | 57 - .../Context/Zf/SearchIndexesDirectory.php | 57 - .../Project/Context/Zf/ServicesDirectory.php | 55 - .../Project/Context/Zf/SessionsDirectory.php | 57 - .../Project/Context/Zf/TemporaryDirectory.php | 57 - .../Zf/TestApplicationActionMethod.php | 229 - .../Zf/TestApplicationBootstrapFile.php | 57 - .../Zf/TestApplicationControllerDirectory.php | 57 - .../Zf/TestApplicationControllerFile.php | 131 - .../Context/Zf/TestApplicationDirectory.php | 57 - .../Zf/TestApplicationModuleDirectory.php | 98 - .../Zf/TestApplicationModulesDirectory.php | 57 - .../Context/Zf/TestLibraryBootstrapFile.php | 57 - .../Context/Zf/TestLibraryDirectory.php | 57 - .../Project/Context/Zf/TestLibraryFile.php | 107 - .../Zf/TestLibraryNamespaceDirectory.php | 88 - .../Context/Zf/TestPHPUnitBootstrapFile.php | 88 - .../Context/Zf/TestPHPUnitConfigFile.php | 81 - .../Project/Context/Zf/TestsDirectory.php | 57 - .../Project/Context/Zf/UploadsDirectory.php | 57 - .../Zf/ViewControllerScriptsDirectory.php | 111 - .../Context/Zf/ViewFiltersDirectory.php | 57 - .../Context/Zf/ViewHelpersDirectory.php | 57 - .../Project/Context/Zf/ViewScriptFile.php | 247 - .../Context/Zf/ViewScriptsDirectory.php | 57 - .../Project/Context/Zf/ViewsDirectory.php | 57 - .../Context/Zf/ZfStandardLibraryDirectory.php | 104 - lib/Zend/Tool/Project/Exception.php | 37 - lib/Zend/Tool/Project/Profile.php | 237 - lib/Zend/Tool/Project/Profile/Exception.php | 37 - .../Project/Profile/FileParser/Interface.php | 54 - .../Tool/Project/Profile/FileParser/Xml.php | 240 - .../Profile/Iterator/ContextFilter.php | 213 - .../Iterator/EnabledResourceFilter.php | 44 - lib/Zend/Tool/Project/Profile/Resource.php | 262 - .../Project/Profile/Resource/Container.php | 421 - .../Profile/Resource/SearchConstraints.php | 117 - lib/Zend/Tool/Project/Provider/Abstract.php | 279 - lib/Zend/Tool/Project/Provider/Action.php | 242 - .../Tool/Project/Provider/Application.php | 87 - lib/Zend/Tool/Project/Provider/Controller.php | 209 - lib/Zend/Tool/Project/Provider/DbAdapter.php | 139 - lib/Zend/Tool/Project/Provider/DbTable.php | 225 - lib/Zend/Tool/Project/Provider/Exception.php | 37 - lib/Zend/Tool/Project/Provider/Form.php | 180 - lib/Zend/Tool/Project/Provider/Layout.php | 140 - lib/Zend/Tool/Project/Provider/Manifest.php | 75 - lib/Zend/Tool/Project/Provider/Model.php | 178 - lib/Zend/Tool/Project/Provider/Module.php | 181 - lib/Zend/Tool/Project/Provider/Profile.php | 54 - lib/Zend/Tool/Project/Provider/Project.php | 254 - .../Tool/Project/Provider/ProjectProvider.php | 97 - lib/Zend/Tool/Project/Provider/Test.php | 198 - lib/Zend/Tool/Project/Provider/View.php | 118 - lib/Zend/Translate.php | 224 - lib/Zend/Translate/Adapter.php | 997 --- lib/Zend/Translate/Adapter/Array.php | 81 - lib/Zend/Translate/Adapter/Csv.php | 121 - lib/Zend/Translate/Adapter/Gettext.php | 169 - lib/Zend/Translate/Adapter/Ini.php | 74 - lib/Zend/Translate/Adapter/Qt.php | 175 - lib/Zend/Translate/Adapter/Tbx.php | 180 - lib/Zend/Translate/Adapter/Tmx.php | 248 - lib/Zend/Translate/Adapter/Xliff.php | 244 - lib/Zend/Translate/Adapter/XmlTm.php | 154 - lib/Zend/Translate/Exception.php | 37 - lib/Zend/Translate/Plural.php | 224 - lib/Zend/Uri.php | 207 - lib/Zend/Uri/Exception.php | 37 - lib/Zend/Uri/Http.php | 765 -- lib/Zend/Validate.php | 290 - lib/Zend/Validate/Abstract.php | 483 - lib/Zend/Validate/Alnum.php | 149 - lib/Zend/Validate/Alpha.php | 149 - lib/Zend/Validate/Barcode.php | 227 - lib/Zend/Validate/Barcode/AdapterAbstract.php | 315 - .../Validate/Barcode/AdapterInterface.php | 68 - lib/Zend/Validate/Barcode/Code25.php | 62 - .../Validate/Barcode/Code25interleaved.php | 62 - lib/Zend/Validate/Barcode/Code39.php | 98 - lib/Zend/Validate/Barcode/Code39ext.php | 56 - lib/Zend/Validate/Barcode/Code93.php | 118 - lib/Zend/Validate/Barcode/Code93ext.php | 56 - lib/Zend/Validate/Barcode/Ean12.php | 52 - lib/Zend/Validate/Barcode/Ean13.php | 52 - lib/Zend/Validate/Barcode/Ean14.php | 52 - lib/Zend/Validate/Barcode/Ean18.php | 52 - lib/Zend/Validate/Barcode/Ean2.php | 56 - lib/Zend/Validate/Barcode/Ean5.php | 56 - lib/Zend/Validate/Barcode/Ean8.php | 69 - lib/Zend/Validate/Barcode/Gtin12.php | 52 - lib/Zend/Validate/Barcode/Gtin13.php | 52 - lib/Zend/Validate/Barcode/Gtin14.php | 52 - lib/Zend/Validate/Barcode/Identcode.php | 52 - lib/Zend/Validate/Barcode/Intelligentmail.php | 56 - lib/Zend/Validate/Barcode/Issn.php | 119 - lib/Zend/Validate/Barcode/Itf14.php | 52 - lib/Zend/Validate/Barcode/Leitcode.php | 52 - lib/Zend/Validate/Barcode/Planet.php | 52 - lib/Zend/Validate/Barcode/Postnet.php | 52 - lib/Zend/Validate/Barcode/Royalmail.php | 121 - lib/Zend/Validate/Barcode/Sscc.php | 52 - lib/Zend/Validate/Barcode/Upca.php | 52 - lib/Zend/Validate/Barcode/Upce.php | 69 - lib/Zend/Validate/Between.php | 224 - lib/Zend/Validate/Callback.php | 173 - lib/Zend/Validate/Ccnum.php | 112 - lib/Zend/Validate/CreditCard.php | 319 - lib/Zend/Validate/Date.php | 258 - lib/Zend/Validate/Db/Abstract.php | 355 - lib/Zend/Validate/Db/NoRecordExists.php | 51 - lib/Zend/Validate/Db/RecordExists.php | 51 - lib/Zend/Validate/Digits.php | 91 - lib/Zend/Validate/EmailAddress.php | 564 -- lib/Zend/Validate/Exception.php | 34 - lib/Zend/Validate/File/Count.php | 285 - lib/Zend/Validate/File/Crc32.php | 180 - lib/Zend/Validate/File/ExcludeExtension.php | 94 - lib/Zend/Validate/File/ExcludeMimeType.php | 101 - lib/Zend/Validate/File/Exists.php | 204 - lib/Zend/Validate/File/Extension.php | 237 - lib/Zend/Validate/File/FilesSize.php | 164 - lib/Zend/Validate/File/Hash.php | 195 - lib/Zend/Validate/File/ImageSize.php | 364 - lib/Zend/Validate/File/IsCompressed.php | 149 - lib/Zend/Validate/File/IsImage.php | 172 - lib/Zend/Validate/File/Md5.php | 182 - lib/Zend/Validate/File/MimeType.php | 476 - lib/Zend/Validate/File/NotExists.php | 84 - lib/Zend/Validate/File/Sha1.php | 182 - lib/Zend/Validate/File/Size.php | 405 - lib/Zend/Validate/File/Upload.php | 251 - lib/Zend/Validate/File/WordCount.php | 101 - lib/Zend/Validate/Float.php | 135 - lib/Zend/Validate/GreaterThan.php | 124 - lib/Zend/Validate/Hex.php | 72 - lib/Zend/Validate/Hostname.php | 1661 ---- lib/Zend/Validate/Hostname/Biz.php | 2917 ------ lib/Zend/Validate/Hostname/Cn.php | 2199 ----- lib/Zend/Validate/Hostname/Com.php | 196 - lib/Zend/Validate/Hostname/Jp.php | 739 -- lib/Zend/Validate/Iban.php | 250 - lib/Zend/Validate/Identical.php | 164 - lib/Zend/Validate/InArray.php | 204 - lib/Zend/Validate/Int.php | 149 - lib/Zend/Validate/Interface.php | 54 - lib/Zend/Validate/Ip.php | 192 - lib/Zend/Validate/Isbn.php | 278 - lib/Zend/Validate/Ldap/Dn.php | 65 - lib/Zend/Validate/LessThan.php | 122 - lib/Zend/Validate/NotEmpty.php | 279 - lib/Zend/Validate/PostCode.php | 210 - lib/Zend/Validate/Regex.php | 146 - lib/Zend/Validate/Sitemap/Changefreq.php | 95 - lib/Zend/Validate/Sitemap/Lastmod.php | 88 - lib/Zend/Validate/Sitemap/Loc.php | 87 - lib/Zend/Validate/Sitemap/Priority.php | 82 - lib/Zend/Validate/StringLength.php | 263 - lib/Zend/Version.php | 81 - lib/Zend/View.php | 160 - lib/Zend/View/Abstract.php | 1200 --- lib/Zend/View/Exception.php | 51 - lib/Zend/View/Helper/Abstract.php | 64 - lib/Zend/View/Helper/Action.php | 164 - lib/Zend/View/Helper/BaseUrl.php | 116 - lib/Zend/View/Helper/Currency.php | 120 - lib/Zend/View/Helper/Cycle.php | 225 - lib/Zend/View/Helper/DeclareVars.php | 95 - lib/Zend/View/Helper/Doctype.php | 242 - lib/Zend/View/Helper/Fieldset.php | 79 - lib/Zend/View/Helper/Form.php | 86 - lib/Zend/View/Helper/FormButton.php | 105 - lib/Zend/View/Helper/FormCheckbox.php | 164 - lib/Zend/View/Helper/FormElement.php | 204 - lib/Zend/View/Helper/FormErrors.php | 167 - lib/Zend/View/Helper/FormFile.php | 75 - lib/Zend/View/Helper/FormHidden.php | 66 - lib/Zend/View/Helper/FormImage.php | 95 - lib/Zend/View/Helper/FormLabel.php | 72 - lib/Zend/View/Helper/FormMultiCheckbox.php | 74 - lib/Zend/View/Helper/FormNote.php | 61 - lib/Zend/View/Helper/FormPassword.php | 89 - lib/Zend/View/Helper/FormRadio.php | 187 - lib/Zend/View/Helper/FormReset.php | 82 - lib/Zend/View/Helper/FormSelect.php | 200 - lib/Zend/View/Helper/FormSubmit.php | 81 - lib/Zend/View/Helper/FormText.php | 78 - lib/Zend/View/Helper/FormTextarea.php | 104 - lib/Zend/View/Helper/Gravatar.php | 363 - lib/Zend/View/Helper/HeadLink.php | 478 - lib/Zend/View/Helper/HeadMeta.php | 449 - lib/Zend/View/Helper/HeadScript.php | 520 -- lib/Zend/View/Helper/HeadStyle.php | 433 - lib/Zend/View/Helper/HeadTitle.php | 222 - lib/Zend/View/Helper/HtmlElement.php | 167 - lib/Zend/View/Helper/HtmlFlash.php | 60 - lib/Zend/View/Helper/HtmlList.php | 90 - lib/Zend/View/Helper/HtmlObject.php | 80 - lib/Zend/View/Helper/HtmlPage.php | 75 - lib/Zend/View/Helper/HtmlQuicktime.php | 82 - lib/Zend/View/Helper/InlineScript.php | 61 - lib/Zend/View/Helper/Interface.php | 46 - lib/Zend/View/Helper/Json.php | 90 - lib/Zend/View/Helper/Layout.php | 81 - lib/Zend/View/Helper/Navigation.php | 350 - .../View/Helper/Navigation/Breadcrumbs.php | 331 - lib/Zend/View/Helper/Navigation/Helper.php | 212 - .../View/Helper/Navigation/HelperAbstract.php | 976 -- lib/Zend/View/Helper/Navigation/Links.php | 783 -- lib/Zend/View/Helper/Navigation/Menu.php | 1099 --- lib/Zend/View/Helper/Navigation/Sitemap.php | 444 - lib/Zend/View/Helper/PaginationControl.php | 145 - lib/Zend/View/Helper/Partial.php | 153 - lib/Zend/View/Helper/Partial/Exception.php | 39 - lib/Zend/View/Helper/PartialLoop.php | 100 - lib/Zend/View/Helper/Placeholder.php | 87 - .../View/Helper/Placeholder/Container.php | 36 - .../Helper/Placeholder/Container/Abstract.php | 385 - .../Placeholder/Container/Exception.php | 39 - .../Placeholder/Container/Standalone.php | 324 - lib/Zend/View/Helper/Placeholder/Registry.php | 188 - .../Helper/Placeholder/Registry/Exception.php | 39 - lib/Zend/View/Helper/RenderToPlaceholder.php | 53 - lib/Zend/View/Helper/ServerUrl.php | 148 - lib/Zend/View/Helper/Translate.php | 180 - lib/Zend/View/Helper/Url.php | 51 - lib/Zend/View/Helper/UserAgent.php | 83 - lib/Zend/View/Interface.php | 137 - lib/Zend/View/Stream.php | 183 - lib/Zend/Wildfire/Channel/HttpHeaders.php | 343 - lib/Zend/Wildfire/Channel/Interface.php | 38 - lib/Zend/Wildfire/Exception.php | 35 - lib/Zend/Wildfire/Plugin/FirePhp.php | 823 -- lib/Zend/Wildfire/Plugin/FirePhp/Message.php | 246 - .../Wildfire/Plugin/FirePhp/TableMessage.php | 165 - lib/Zend/Wildfire/Plugin/Interface.php | 48 - lib/Zend/Wildfire/Protocol/JsonStream.php | 235 - lib/Zend/Xml/Exception.php | 36 - lib/Zend/Xml/Security.php | 488 - lib/Zend/XmlRpc/Client.php | 403 - lib/Zend/XmlRpc/Client/Exception.php | 40 - lib/Zend/XmlRpc/Client/FaultException.php | 38 - lib/Zend/XmlRpc/Client/HttpException.php | 41 - .../XmlRpc/Client/IntrospectException.php | 40 - .../XmlRpc/Client/ServerIntrospection.php | 166 - lib/Zend/XmlRpc/Client/ServerProxy.php | 95 - lib/Zend/XmlRpc/Exception.php | 37 - lib/Zend/XmlRpc/Fault.php | 307 - lib/Zend/XmlRpc/Generator/DomDocument.php | 101 - .../XmlRpc/Generator/GeneratorAbstract.php | 150 - lib/Zend/XmlRpc/Generator/XmlWriter.php | 93 - lib/Zend/XmlRpc/Request.php | 445 - lib/Zend/XmlRpc/Request/Http.php | 124 - lib/Zend/XmlRpc/Request/Stdin.php | 84 - lib/Zend/XmlRpc/Response.php | 255 - lib/Zend/XmlRpc/Response/Http.php | 51 - lib/Zend/XmlRpc/Server.php | 615 -- lib/Zend/XmlRpc/Server/Cache.php | 46 - lib/Zend/XmlRpc/Server/Exception.php | 42 - lib/Zend/XmlRpc/Server/Fault.php | 201 - lib/Zend/XmlRpc/Server/System.php | 162 - lib/Zend/XmlRpc/Value.php | 527 -- lib/Zend/XmlRpc/Value/Array.php | 73 - lib/Zend/XmlRpc/Value/Base64.php | 68 - lib/Zend/XmlRpc/Value/BigInteger.php | 58 - lib/Zend/XmlRpc/Value/Boolean.php | 63 - lib/Zend/XmlRpc/Value/Collection.php | 73 - lib/Zend/XmlRpc/Value/DateTime.php | 91 - lib/Zend/XmlRpc/Value/Double.php | 62 - lib/Zend/XmlRpc/Value/Exception.php | 39 - lib/Zend/XmlRpc/Value/Integer.php | 65 - lib/Zend/XmlRpc/Value/Nil.php | 60 - lib/Zend/XmlRpc/Value/Scalar.php | 53 - lib/Zend/XmlRpc/Value/String.php | 60 - lib/Zend/XmlRpc/Value/Struct.php | 75 - lib/Zend/replace_recursive.php | 45 - 3070 files changed, 1093265 deletions(-) delete mode 100644 lib/Zend/Acl.php delete mode 100644 lib/Zend/Acl/Assert/Interface.php delete mode 100644 lib/Zend/Acl/Exception.php delete mode 100644 lib/Zend/Acl/Resource.php delete mode 100644 lib/Zend/Acl/Resource/Interface.php delete mode 100644 lib/Zend/Acl/Role.php delete mode 100644 lib/Zend/Acl/Role/Interface.php delete mode 100644 lib/Zend/Acl/Role/Registry.php delete mode 100644 lib/Zend/Acl/Role/Registry/Exception.php delete mode 100644 lib/Zend/Amf/Adobe/Auth.php delete mode 100644 lib/Zend/Amf/Adobe/DbInspector.php delete mode 100644 lib/Zend/Amf/Adobe/Introspector.php delete mode 100644 lib/Zend/Amf/Auth/Abstract.php delete mode 100644 lib/Zend/Amf/Constants.php delete mode 100644 lib/Zend/Amf/Exception.php delete mode 100644 lib/Zend/Amf/Parse/Amf0/Deserializer.php delete mode 100644 lib/Zend/Amf/Parse/Amf0/Serializer.php delete mode 100644 lib/Zend/Amf/Parse/Amf3/Deserializer.php delete mode 100644 lib/Zend/Amf/Parse/Amf3/Serializer.php delete mode 100644 lib/Zend/Amf/Parse/Deserializer.php delete mode 100644 lib/Zend/Amf/Parse/InputStream.php delete mode 100644 lib/Zend/Amf/Parse/OutputStream.php delete mode 100644 lib/Zend/Amf/Parse/Resource/MysqlResult.php delete mode 100644 lib/Zend/Amf/Parse/Resource/MysqliResult.php delete mode 100644 lib/Zend/Amf/Parse/Resource/Stream.php delete mode 100644 lib/Zend/Amf/Parse/Serializer.php delete mode 100644 lib/Zend/Amf/Parse/TypeLoader.php delete mode 100644 lib/Zend/Amf/Request.php delete mode 100644 lib/Zend/Amf/Request/Http.php delete mode 100644 lib/Zend/Amf/Response.php delete mode 100644 lib/Zend/Amf/Response/Http.php delete mode 100644 lib/Zend/Amf/Server.php delete mode 100644 lib/Zend/Amf/Server/Exception.php delete mode 100644 lib/Zend/Amf/Util/BinaryStream.php delete mode 100644 lib/Zend/Amf/Value/ByteArray.php delete mode 100644 lib/Zend/Amf/Value/MessageBody.php delete mode 100644 lib/Zend/Amf/Value/MessageHeader.php delete mode 100644 lib/Zend/Amf/Value/Messaging/AbstractMessage.php delete mode 100644 lib/Zend/Amf/Value/Messaging/AcknowledgeMessage.php delete mode 100644 lib/Zend/Amf/Value/Messaging/ArrayCollection.php delete mode 100644 lib/Zend/Amf/Value/Messaging/AsyncMessage.php delete mode 100644 lib/Zend/Amf/Value/Messaging/CommandMessage.php delete mode 100644 lib/Zend/Amf/Value/Messaging/ErrorMessage.php delete mode 100644 lib/Zend/Amf/Value/Messaging/RemotingMessage.php delete mode 100644 lib/Zend/Amf/Value/TraitsInfo.php delete mode 100644 lib/Zend/Application.php delete mode 100644 lib/Zend/Application/Bootstrap/Bootstrap.php delete mode 100644 lib/Zend/Application/Bootstrap/BootstrapAbstract.php delete mode 100644 lib/Zend/Application/Bootstrap/Bootstrapper.php delete mode 100644 lib/Zend/Application/Bootstrap/Exception.php delete mode 100644 lib/Zend/Application/Bootstrap/ResourceBootstrapper.php delete mode 100644 lib/Zend/Application/Exception.php delete mode 100644 lib/Zend/Application/Module/Autoloader.php delete mode 100644 lib/Zend/Application/Module/Bootstrap.php delete mode 100644 lib/Zend/Application/Resource/Cachemanager.php delete mode 100644 lib/Zend/Application/Resource/Db.php delete mode 100644 lib/Zend/Application/Resource/Dojo.php delete mode 100644 lib/Zend/Application/Resource/Exception.php delete mode 100644 lib/Zend/Application/Resource/Frontcontroller.php delete mode 100644 lib/Zend/Application/Resource/Layout.php delete mode 100644 lib/Zend/Application/Resource/Locale.php delete mode 100644 lib/Zend/Application/Resource/Log.php delete mode 100644 lib/Zend/Application/Resource/Mail.php delete mode 100644 lib/Zend/Application/Resource/Modules.php delete mode 100644 lib/Zend/Application/Resource/Multidb.php delete mode 100644 lib/Zend/Application/Resource/Navigation.php delete mode 100644 lib/Zend/Application/Resource/Resource.php delete mode 100644 lib/Zend/Application/Resource/ResourceAbstract.php delete mode 100644 lib/Zend/Application/Resource/Router.php delete mode 100644 lib/Zend/Application/Resource/Session.php delete mode 100644 lib/Zend/Application/Resource/Translate.php delete mode 100644 lib/Zend/Application/Resource/Useragent.php delete mode 100644 lib/Zend/Application/Resource/View.php delete mode 100644 lib/Zend/Auth.php delete mode 100644 lib/Zend/Auth/Adapter/DbTable.php delete mode 100644 lib/Zend/Auth/Adapter/Digest.php delete mode 100644 lib/Zend/Auth/Adapter/Exception.php delete mode 100644 lib/Zend/Auth/Adapter/Http.php delete mode 100644 lib/Zend/Auth/Adapter/Http/Resolver/Exception.php delete mode 100644 lib/Zend/Auth/Adapter/Http/Resolver/File.php delete mode 100644 lib/Zend/Auth/Adapter/Http/Resolver/Interface.php delete mode 100644 lib/Zend/Auth/Adapter/Interface.php delete mode 100644 lib/Zend/Auth/Adapter/Ldap.php delete mode 100644 lib/Zend/Auth/Adapter/OpenId.php delete mode 100644 lib/Zend/Auth/Exception.php delete mode 100644 lib/Zend/Auth/Result.php delete mode 100644 lib/Zend/Auth/Storage/Exception.php delete mode 100644 lib/Zend/Auth/Storage/Interface.php delete mode 100644 lib/Zend/Auth/Storage/NonPersistent.php delete mode 100644 lib/Zend/Auth/Storage/Session.php delete mode 100644 lib/Zend/Barcode.php delete mode 100644 lib/Zend/Barcode/Exception.php delete mode 100644 lib/Zend/Barcode/Object/Code128.php delete mode 100644 lib/Zend/Barcode/Object/Code25.php delete mode 100644 lib/Zend/Barcode/Object/Code25interleaved.php delete mode 100644 lib/Zend/Barcode/Object/Code39.php delete mode 100644 lib/Zend/Barcode/Object/Ean13.php delete mode 100644 lib/Zend/Barcode/Object/Ean2.php delete mode 100644 lib/Zend/Barcode/Object/Ean5.php delete mode 100644 lib/Zend/Barcode/Object/Ean8.php delete mode 100644 lib/Zend/Barcode/Object/Error.php delete mode 100644 lib/Zend/Barcode/Object/Exception.php delete mode 100644 lib/Zend/Barcode/Object/Identcode.php delete mode 100644 lib/Zend/Barcode/Object/Itf14.php delete mode 100644 lib/Zend/Barcode/Object/Leitcode.php delete mode 100644 lib/Zend/Barcode/Object/ObjectAbstract.php delete mode 100644 lib/Zend/Barcode/Object/Planet.php delete mode 100644 lib/Zend/Barcode/Object/Postnet.php delete mode 100644 lib/Zend/Barcode/Object/Royalmail.php delete mode 100644 lib/Zend/Barcode/Object/Upca.php delete mode 100644 lib/Zend/Barcode/Object/Upce.php delete mode 100644 lib/Zend/Barcode/Renderer/Exception.php delete mode 100644 lib/Zend/Barcode/Renderer/Image.php delete mode 100644 lib/Zend/Barcode/Renderer/Pdf.php delete mode 100644 lib/Zend/Barcode/Renderer/RendererAbstract.php delete mode 100644 lib/Zend/Barcode/Renderer/Svg.php delete mode 100644 lib/Zend/Cache.php delete mode 100644 lib/Zend/Cache/Backend.php delete mode 100644 lib/Zend/Cache/Backend/Apc.php delete mode 100644 lib/Zend/Cache/Backend/BlackHole.php delete mode 100644 lib/Zend/Cache/Backend/ExtendedInterface.php delete mode 100644 lib/Zend/Cache/Backend/File.php delete mode 100644 lib/Zend/Cache/Backend/Interface.php delete mode 100644 lib/Zend/Cache/Backend/Libmemcached.php delete mode 100644 lib/Zend/Cache/Backend/Memcached.php delete mode 100644 lib/Zend/Cache/Backend/Sqlite.php delete mode 100644 lib/Zend/Cache/Backend/Static.php delete mode 100644 lib/Zend/Cache/Backend/Test.php delete mode 100644 lib/Zend/Cache/Backend/TwoLevels.php delete mode 100644 lib/Zend/Cache/Backend/WinCache.php delete mode 100644 lib/Zend/Cache/Backend/Xcache.php delete mode 100644 lib/Zend/Cache/Backend/ZendPlatform.php delete mode 100644 lib/Zend/Cache/Backend/ZendServer.php delete mode 100644 lib/Zend/Cache/Backend/ZendServer/Disk.php delete mode 100644 lib/Zend/Cache/Backend/ZendServer/ShMem.php delete mode 100644 lib/Zend/Cache/Core.php delete mode 100644 lib/Zend/Cache/Exception.php delete mode 100644 lib/Zend/Cache/Frontend/Capture.php delete mode 100644 lib/Zend/Cache/Frontend/Class.php delete mode 100644 lib/Zend/Cache/Frontend/File.php delete mode 100644 lib/Zend/Cache/Frontend/Function.php delete mode 100644 lib/Zend/Cache/Frontend/Output.php delete mode 100644 lib/Zend/Cache/Frontend/Page.php delete mode 100644 lib/Zend/Cache/Manager.php delete mode 100644 lib/Zend/Captcha/Adapter.php delete mode 100644 lib/Zend/Captcha/Base.php delete mode 100644 lib/Zend/Captcha/Dumb.php delete mode 100644 lib/Zend/Captcha/Exception.php delete mode 100644 lib/Zend/Captcha/Figlet.php delete mode 100644 lib/Zend/Captcha/Image.php delete mode 100644 lib/Zend/Captcha/ReCaptcha.php delete mode 100644 lib/Zend/Captcha/Word.php delete mode 100644 lib/Zend/Cloud/AbstractFactory.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter/AbstractAdapter.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter/SimpleDb.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure.php delete mode 100644 lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php delete mode 100644 lib/Zend/Cloud/DocumentService/Document.php delete mode 100644 lib/Zend/Cloud/DocumentService/DocumentSet.php delete mode 100644 lib/Zend/Cloud/DocumentService/Exception.php delete mode 100644 lib/Zend/Cloud/DocumentService/Factory.php delete mode 100644 lib/Zend/Cloud/DocumentService/Query.php delete mode 100644 lib/Zend/Cloud/DocumentService/QueryAdapter.php delete mode 100644 lib/Zend/Cloud/Exception.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Adapter.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Adapter/AbstractAdapter.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Adapter/Ec2.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Adapter/Rackspace.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Exception.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Factory.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Image.php delete mode 100644 lib/Zend/Cloud/Infrastructure/ImageList.php delete mode 100644 lib/Zend/Cloud/Infrastructure/Instance.php delete mode 100644 lib/Zend/Cloud/Infrastructure/InstanceList.php delete mode 100644 lib/Zend/Cloud/OperationNotAvailableException.php delete mode 100644 lib/Zend/Cloud/QueueService/Adapter.php delete mode 100644 lib/Zend/Cloud/QueueService/Adapter/AbstractAdapter.php delete mode 100644 lib/Zend/Cloud/QueueService/Adapter/Sqs.php delete mode 100644 lib/Zend/Cloud/QueueService/Adapter/WindowsAzure.php delete mode 100644 lib/Zend/Cloud/QueueService/Adapter/ZendQueue.php delete mode 100644 lib/Zend/Cloud/QueueService/Exception.php delete mode 100644 lib/Zend/Cloud/QueueService/Factory.php delete mode 100644 lib/Zend/Cloud/QueueService/Message.php delete mode 100644 lib/Zend/Cloud/QueueService/MessageSet.php delete mode 100644 lib/Zend/Cloud/StorageService/Adapter.php delete mode 100644 lib/Zend/Cloud/StorageService/Adapter/FileSystem.php delete mode 100644 lib/Zend/Cloud/StorageService/Adapter/Rackspace.php delete mode 100644 lib/Zend/Cloud/StorageService/Adapter/S3.php delete mode 100644 lib/Zend/Cloud/StorageService/Adapter/WindowsAzure.php delete mode 100644 lib/Zend/Cloud/StorageService/Exception.php delete mode 100644 lib/Zend/Cloud/StorageService/Factory.php delete mode 100644 lib/Zend/CodeGenerator/Abstract.php delete mode 100644 lib/Zend/CodeGenerator/Exception.php delete mode 100644 lib/Zend/CodeGenerator/Php/Abstract.php delete mode 100644 lib/Zend/CodeGenerator/Php/Body.php delete mode 100644 lib/Zend/CodeGenerator/Php/Class.php delete mode 100644 lib/Zend/CodeGenerator/Php/Docblock.php delete mode 100644 lib/Zend/CodeGenerator/Php/Docblock/Tag.php delete mode 100644 lib/Zend/CodeGenerator/Php/Docblock/Tag/License.php delete mode 100644 lib/Zend/CodeGenerator/Php/Docblock/Tag/Param.php delete mode 100644 lib/Zend/CodeGenerator/Php/Docblock/Tag/Return.php delete mode 100644 lib/Zend/CodeGenerator/Php/Exception.php delete mode 100644 lib/Zend/CodeGenerator/Php/File.php delete mode 100644 lib/Zend/CodeGenerator/Php/Member/Abstract.php delete mode 100644 lib/Zend/CodeGenerator/Php/Member/Container.php delete mode 100644 lib/Zend/CodeGenerator/Php/Method.php delete mode 100644 lib/Zend/CodeGenerator/Php/Parameter.php delete mode 100644 lib/Zend/CodeGenerator/Php/Parameter/DefaultValue.php delete mode 100644 lib/Zend/CodeGenerator/Php/Property.php delete mode 100644 lib/Zend/CodeGenerator/Php/Property/DefaultValue.php delete mode 100644 lib/Zend/Config.php delete mode 100644 lib/Zend/Config/Exception.php delete mode 100644 lib/Zend/Config/Ini.php delete mode 100644 lib/Zend/Config/Json.php delete mode 100644 lib/Zend/Config/Writer.php delete mode 100644 lib/Zend/Config/Writer/Array.php delete mode 100644 lib/Zend/Config/Writer/FileAbstract.php delete mode 100644 lib/Zend/Config/Writer/Ini.php delete mode 100644 lib/Zend/Config/Writer/Json.php delete mode 100644 lib/Zend/Config/Writer/Xml.php delete mode 100644 lib/Zend/Config/Writer/Yaml.php delete mode 100644 lib/Zend/Config/Xml.php delete mode 100644 lib/Zend/Config/Yaml.php delete mode 100644 lib/Zend/Console/Getopt.php delete mode 100644 lib/Zend/Console/Getopt/Exception.php delete mode 100644 lib/Zend/Controller/Action.php delete mode 100644 lib/Zend/Controller/Action/Exception.php delete mode 100644 lib/Zend/Controller/Action/Helper/Abstract.php delete mode 100644 lib/Zend/Controller/Action/Helper/ActionStack.php delete mode 100644 lib/Zend/Controller/Action/Helper/AjaxContext.php delete mode 100644 lib/Zend/Controller/Action/Helper/AutoComplete/Abstract.php delete mode 100644 lib/Zend/Controller/Action/Helper/AutoCompleteDojo.php delete mode 100644 lib/Zend/Controller/Action/Helper/AutoCompleteScriptaculous.php delete mode 100644 lib/Zend/Controller/Action/Helper/Cache.php delete mode 100644 lib/Zend/Controller/Action/Helper/ContextSwitch.php delete mode 100644 lib/Zend/Controller/Action/Helper/FlashMessenger.php delete mode 100644 lib/Zend/Controller/Action/Helper/Json.php delete mode 100644 lib/Zend/Controller/Action/Helper/Redirector.php delete mode 100644 lib/Zend/Controller/Action/Helper/Url.php delete mode 100644 lib/Zend/Controller/Action/Helper/ViewRenderer.php delete mode 100644 lib/Zend/Controller/Action/HelperBroker.php delete mode 100644 lib/Zend/Controller/Action/HelperBroker/PriorityStack.php delete mode 100644 lib/Zend/Controller/Action/Interface.php delete mode 100644 lib/Zend/Controller/Dispatcher/Abstract.php delete mode 100644 lib/Zend/Controller/Dispatcher/Exception.php delete mode 100644 lib/Zend/Controller/Dispatcher/Interface.php delete mode 100644 lib/Zend/Controller/Dispatcher/Standard.php delete mode 100644 lib/Zend/Controller/Exception.php delete mode 100644 lib/Zend/Controller/Front.php delete mode 100644 lib/Zend/Controller/Plugin/Abstract.php delete mode 100644 lib/Zend/Controller/Plugin/ActionStack.php delete mode 100644 lib/Zend/Controller/Plugin/Broker.php delete mode 100644 lib/Zend/Controller/Plugin/ErrorHandler.php delete mode 100644 lib/Zend/Controller/Plugin/PutHandler.php delete mode 100644 lib/Zend/Controller/Request/Abstract.php delete mode 100644 lib/Zend/Controller/Request/Apache404.php delete mode 100644 lib/Zend/Controller/Request/Exception.php delete mode 100644 lib/Zend/Controller/Request/Http.php delete mode 100644 lib/Zend/Controller/Request/HttpTestCase.php delete mode 100644 lib/Zend/Controller/Request/Simple.php delete mode 100644 lib/Zend/Controller/Response/Abstract.php delete mode 100644 lib/Zend/Controller/Response/Cli.php delete mode 100644 lib/Zend/Controller/Response/Exception.php delete mode 100644 lib/Zend/Controller/Response/Http.php delete mode 100644 lib/Zend/Controller/Response/HttpTestCase.php delete mode 100644 lib/Zend/Controller/Router/Abstract.php delete mode 100644 lib/Zend/Controller/Router/Exception.php delete mode 100644 lib/Zend/Controller/Router/Interface.php delete mode 100644 lib/Zend/Controller/Router/Rewrite.php delete mode 100644 lib/Zend/Controller/Router/Route.php delete mode 100644 lib/Zend/Controller/Router/Route/Abstract.php delete mode 100644 lib/Zend/Controller/Router/Route/Chain.php delete mode 100644 lib/Zend/Controller/Router/Route/Hostname.php delete mode 100644 lib/Zend/Controller/Router/Route/Interface.php delete mode 100644 lib/Zend/Controller/Router/Route/Module.php delete mode 100644 lib/Zend/Controller/Router/Route/Regex.php delete mode 100644 lib/Zend/Controller/Router/Route/Static.php delete mode 100644 lib/Zend/Crypt.php delete mode 100644 lib/Zend/Crypt/DiffieHellman.php delete mode 100644 lib/Zend/Crypt/DiffieHellman/Exception.php delete mode 100644 lib/Zend/Crypt/Exception.php delete mode 100644 lib/Zend/Crypt/Hmac.php delete mode 100644 lib/Zend/Crypt/Hmac/Exception.php delete mode 100644 lib/Zend/Crypt/Math.php delete mode 100644 lib/Zend/Crypt/Math/BigInteger.php delete mode 100644 lib/Zend/Crypt/Math/BigInteger/Bcmath.php delete mode 100644 lib/Zend/Crypt/Math/BigInteger/Exception.php delete mode 100644 lib/Zend/Crypt/Math/BigInteger/Gmp.php delete mode 100644 lib/Zend/Crypt/Math/BigInteger/Interface.php delete mode 100644 lib/Zend/Crypt/Math/Exception.php delete mode 100644 lib/Zend/Crypt/Rsa.php delete mode 100644 lib/Zend/Crypt/Rsa/Exception.php delete mode 100644 lib/Zend/Crypt/Rsa/Key.php delete mode 100644 lib/Zend/Crypt/Rsa/Key/Private.php delete mode 100644 lib/Zend/Crypt/Rsa/Key/Public.php delete mode 100644 lib/Zend/Currency.php delete mode 100644 lib/Zend/Currency/CurrencyInterface.php delete mode 100644 lib/Zend/Currency/Exception.php delete mode 100644 lib/Zend/Date.php delete mode 100644 lib/Zend/Date/Cities.php delete mode 100644 lib/Zend/Date/DateObject.php delete mode 100644 lib/Zend/Date/Exception.php delete mode 100644 lib/Zend/Db.php delete mode 100644 lib/Zend/Db/Adapter/Abstract.php delete mode 100644 lib/Zend/Db/Adapter/Db2.php delete mode 100644 lib/Zend/Db/Adapter/Db2/Exception.php delete mode 100644 lib/Zend/Db/Adapter/Exception.php delete mode 100644 lib/Zend/Db/Adapter/Mysqli.php delete mode 100644 lib/Zend/Db/Adapter/Mysqli/Exception.php delete mode 100644 lib/Zend/Db/Adapter/Oracle.php delete mode 100644 lib/Zend/Db/Adapter/Oracle/Exception.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Abstract.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Ibm.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Ibm/Db2.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Ibm/Ids.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Mssql.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Mysql.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Oci.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Pgsql.php delete mode 100644 lib/Zend/Db/Adapter/Pdo/Sqlite.php delete mode 100644 lib/Zend/Db/Adapter/Sqlsrv.php delete mode 100644 lib/Zend/Db/Adapter/Sqlsrv/Exception.php delete mode 100644 lib/Zend/Db/Exception.php delete mode 100644 lib/Zend/Db/Expr.php delete mode 100644 lib/Zend/Db/Profiler.php delete mode 100644 lib/Zend/Db/Profiler/Exception.php delete mode 100644 lib/Zend/Db/Profiler/Firebug.php delete mode 100644 lib/Zend/Db/Profiler/Query.php delete mode 100644 lib/Zend/Db/Select.php delete mode 100644 lib/Zend/Db/Select/Exception.php delete mode 100644 lib/Zend/Db/Statement.php delete mode 100644 lib/Zend/Db/Statement/Db2.php delete mode 100644 lib/Zend/Db/Statement/Db2/Exception.php delete mode 100644 lib/Zend/Db/Statement/Exception.php delete mode 100644 lib/Zend/Db/Statement/Interface.php delete mode 100644 lib/Zend/Db/Statement/Mysqli.php delete mode 100644 lib/Zend/Db/Statement/Mysqli/Exception.php delete mode 100644 lib/Zend/Db/Statement/Oracle.php delete mode 100644 lib/Zend/Db/Statement/Oracle/Exception.php delete mode 100644 lib/Zend/Db/Statement/Pdo.php delete mode 100644 lib/Zend/Db/Statement/Pdo/Ibm.php delete mode 100644 lib/Zend/Db/Statement/Pdo/Oci.php delete mode 100644 lib/Zend/Db/Statement/Sqlsrv.php delete mode 100644 lib/Zend/Db/Statement/Sqlsrv/Exception.php delete mode 100644 lib/Zend/Db/Table.php delete mode 100644 lib/Zend/Db/Table/Abstract.php delete mode 100644 lib/Zend/Db/Table/Definition.php delete mode 100644 lib/Zend/Db/Table/Exception.php delete mode 100644 lib/Zend/Db/Table/Row.php delete mode 100644 lib/Zend/Db/Table/Row/Abstract.php delete mode 100644 lib/Zend/Db/Table/Row/Exception.php delete mode 100644 lib/Zend/Db/Table/Rowset.php delete mode 100644 lib/Zend/Db/Table/Rowset/Abstract.php delete mode 100644 lib/Zend/Db/Table/Rowset/Exception.php delete mode 100644 lib/Zend/Db/Table/Select.php delete mode 100644 lib/Zend/Db/Table/Select/Exception.php delete mode 100644 lib/Zend/Debug.php delete mode 100644 lib/Zend/Dojo.php delete mode 100644 lib/Zend/Dojo/BuildLayer.php delete mode 100644 lib/Zend/Dojo/Data.php delete mode 100644 lib/Zend/Dojo/Exception.php delete mode 100644 lib/Zend/Dojo/Form.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/AccordionContainer.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/AccordionPane.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/BorderContainer.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/ContentPane.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/DijitContainer.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/DijitElement.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/DijitForm.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/SplitContainer.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/StackContainer.php delete mode 100644 lib/Zend/Dojo/Form/Decorator/TabContainer.php delete mode 100644 lib/Zend/Dojo/Form/DisplayGroup.php delete mode 100644 lib/Zend/Dojo/Form/Element/Button.php delete mode 100644 lib/Zend/Dojo/Form/Element/CheckBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/ComboBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/CurrencyTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/DateTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/Dijit.php delete mode 100644 lib/Zend/Dojo/Form/Element/DijitMulti.php delete mode 100644 lib/Zend/Dojo/Form/Element/Editor.php delete mode 100644 lib/Zend/Dojo/Form/Element/FilteringSelect.php delete mode 100644 lib/Zend/Dojo/Form/Element/HorizontalSlider.php delete mode 100644 lib/Zend/Dojo/Form/Element/NumberSpinner.php delete mode 100644 lib/Zend/Dojo/Form/Element/NumberTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/PasswordTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/RadioButton.php delete mode 100644 lib/Zend/Dojo/Form/Element/SimpleTextarea.php delete mode 100644 lib/Zend/Dojo/Form/Element/Slider.php delete mode 100644 lib/Zend/Dojo/Form/Element/SubmitButton.php delete mode 100644 lib/Zend/Dojo/Form/Element/TextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/Textarea.php delete mode 100644 lib/Zend/Dojo/Form/Element/TimeTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/ValidationTextBox.php delete mode 100644 lib/Zend/Dojo/Form/Element/VerticalSlider.php delete mode 100644 lib/Zend/Dojo/Form/SubForm.php delete mode 100644 lib/Zend/Dojo/View/Exception.php delete mode 100644 lib/Zend/Dojo/View/Helper/AccordionContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/AccordionPane.php delete mode 100644 lib/Zend/Dojo/View/Helper/BorderContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/Button.php delete mode 100644 lib/Zend/Dojo/View/Helper/CheckBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/ComboBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/ContentPane.php delete mode 100644 lib/Zend/Dojo/View/Helper/CurrencyTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/CustomDijit.php delete mode 100644 lib/Zend/Dojo/View/Helper/DateTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/Dijit.php delete mode 100644 lib/Zend/Dojo/View/Helper/DijitContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/Dojo.php delete mode 100644 lib/Zend/Dojo/View/Helper/Dojo/Container.php delete mode 100644 lib/Zend/Dojo/View/Helper/Editor.php delete mode 100644 lib/Zend/Dojo/View/Helper/FilteringSelect.php delete mode 100644 lib/Zend/Dojo/View/Helper/Form.php delete mode 100644 lib/Zend/Dojo/View/Helper/HorizontalSlider.php delete mode 100644 lib/Zend/Dojo/View/Helper/NumberSpinner.php delete mode 100644 lib/Zend/Dojo/View/Helper/NumberTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/PasswordTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/RadioButton.php delete mode 100644 lib/Zend/Dojo/View/Helper/SimpleTextarea.php delete mode 100644 lib/Zend/Dojo/View/Helper/Slider.php delete mode 100644 lib/Zend/Dojo/View/Helper/SplitContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/StackContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/SubmitButton.php delete mode 100644 lib/Zend/Dojo/View/Helper/TabContainer.php delete mode 100644 lib/Zend/Dojo/View/Helper/TextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/Textarea.php delete mode 100644 lib/Zend/Dojo/View/Helper/TimeTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/ValidationTextBox.php delete mode 100644 lib/Zend/Dojo/View/Helper/VerticalSlider.php delete mode 100644 lib/Zend/Dom/Exception.php delete mode 100644 lib/Zend/Dom/Query.php delete mode 100644 lib/Zend/Dom/Query/Css2Xpath.php delete mode 100644 lib/Zend/Dom/Query/Result.php delete mode 100644 lib/Zend/EventManager/Event.php delete mode 100644 lib/Zend/EventManager/EventCollection.php delete mode 100644 lib/Zend/EventManager/EventDescription.php delete mode 100644 lib/Zend/EventManager/EventManager.php delete mode 100644 lib/Zend/EventManager/EventManagerAware.php delete mode 100644 lib/Zend/EventManager/Exception.php delete mode 100644 lib/Zend/EventManager/Exception/InvalidArgumentException.php delete mode 100644 lib/Zend/EventManager/Filter.php delete mode 100644 lib/Zend/EventManager/Filter/FilterIterator.php delete mode 100644 lib/Zend/EventManager/FilterChain.php delete mode 100644 lib/Zend/EventManager/GlobalEventManager.php delete mode 100644 lib/Zend/EventManager/ListenerAggregate.php delete mode 100644 lib/Zend/EventManager/ResponseCollection.php delete mode 100644 lib/Zend/EventManager/SharedEventCollection.php delete mode 100644 lib/Zend/EventManager/SharedEventCollectionAware.php delete mode 100644 lib/Zend/EventManager/SharedEventManager.php delete mode 100644 lib/Zend/EventManager/StaticEventManager.php delete mode 100644 lib/Zend/Exception.php delete mode 100644 lib/Zend/Feed.php delete mode 100644 lib/Zend/Feed/Abstract.php delete mode 100644 lib/Zend/Feed/Atom.php delete mode 100644 lib/Zend/Feed/Builder.php delete mode 100644 lib/Zend/Feed/Builder/Entry.php delete mode 100644 lib/Zend/Feed/Builder/Exception.php delete mode 100644 lib/Zend/Feed/Builder/Header.php delete mode 100644 lib/Zend/Feed/Builder/Header/Itunes.php delete mode 100644 lib/Zend/Feed/Builder/Interface.php delete mode 100644 lib/Zend/Feed/Element.php delete mode 100644 lib/Zend/Feed/Entry/Abstract.php delete mode 100644 lib/Zend/Feed/Entry/Atom.php delete mode 100644 lib/Zend/Feed/Entry/Rss.php delete mode 100644 lib/Zend/Feed/Exception.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/CallbackAbstract.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/CallbackInterface.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Exception.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/HttpResponse.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Model/ModelAbstract.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Model/Subscription.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Model/SubscriptionInterface.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Publisher.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Subscriber.php delete mode 100644 lib/Zend/Feed/Pubsubhubbub/Subscriber/Callback.php delete mode 100644 lib/Zend/Feed/Reader.php delete mode 100644 lib/Zend/Feed/Reader/Collection.php delete mode 100644 lib/Zend/Feed/Reader/Collection/Author.php delete mode 100644 lib/Zend/Feed/Reader/Collection/Category.php delete mode 100644 lib/Zend/Feed/Reader/Collection/CollectionAbstract.php delete mode 100644 lib/Zend/Feed/Reader/Entry/Atom.php delete mode 100644 lib/Zend/Feed/Reader/Entry/Rss.php delete mode 100644 lib/Zend/Feed/Reader/EntryAbstract.php delete mode 100644 lib/Zend/Feed/Reader/EntryInterface.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Atom/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Atom/Feed.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Content/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php delete mode 100644 lib/Zend/Feed/Reader/Extension/DublinCore/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/DublinCore/Feed.php delete mode 100644 lib/Zend/Feed/Reader/Extension/EntryAbstract.php delete mode 100644 lib/Zend/Feed/Reader/Extension/FeedAbstract.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Podcast/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Podcast/Feed.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Slash/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Syndication/Feed.php delete mode 100644 lib/Zend/Feed/Reader/Extension/Thread/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php delete mode 100644 lib/Zend/Feed/Reader/Feed/Atom.php delete mode 100644 lib/Zend/Feed/Reader/Feed/Atom/Source.php delete mode 100644 lib/Zend/Feed/Reader/Feed/Rss.php delete mode 100644 lib/Zend/Feed/Reader/FeedAbstract.php delete mode 100644 lib/Zend/Feed/Reader/FeedInterface.php delete mode 100644 lib/Zend/Feed/Reader/FeedSet.php delete mode 100644 lib/Zend/Feed/Rss.php delete mode 100644 lib/Zend/Feed/Writer.php delete mode 100644 lib/Zend/Feed/Writer/Deleted.php delete mode 100644 lib/Zend/Feed/Writer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Exception/InvalidMethodException.php delete mode 100644 lib/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php delete mode 100644 lib/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php delete mode 100644 lib/Zend/Feed/Writer/Extension/ITunes/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/ITunes/Feed.php delete mode 100644 lib/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php delete mode 100644 lib/Zend/Feed/Writer/Extension/RendererAbstract.php delete mode 100644 lib/Zend/Feed/Writer/Extension/RendererInterface.php delete mode 100644 lib/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php delete mode 100644 lib/Zend/Feed/Writer/Feed.php delete mode 100644 lib/Zend/Feed/Writer/Feed/FeedAbstract.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Entry/Atom.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Entry/Rss.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Feed/Atom.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/Feed/Rss.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/RendererAbstract.php delete mode 100644 lib/Zend/Feed/Writer/Renderer/RendererInterface.php delete mode 100644 lib/Zend/Feed/Writer/Source.php delete mode 100644 lib/Zend/File/ClassFileLocator.php delete mode 100644 lib/Zend/File/PhpClassFile.php delete mode 100644 lib/Zend/File/Transfer.php delete mode 100644 lib/Zend/File/Transfer/Adapter/Abstract.php delete mode 100644 lib/Zend/File/Transfer/Adapter/Http.php delete mode 100644 lib/Zend/File/Transfer/Exception.php delete mode 100644 lib/Zend/Filter.php delete mode 100644 lib/Zend/Filter/Alnum.php delete mode 100644 lib/Zend/Filter/Alpha.php delete mode 100644 lib/Zend/Filter/BaseName.php delete mode 100644 lib/Zend/Filter/Boolean.php delete mode 100644 lib/Zend/Filter/Callback.php delete mode 100644 lib/Zend/Filter/Compress.php delete mode 100644 lib/Zend/Filter/Compress/Bz2.php delete mode 100644 lib/Zend/Filter/Compress/CompressAbstract.php delete mode 100644 lib/Zend/Filter/Compress/CompressInterface.php delete mode 100644 lib/Zend/Filter/Compress/Gz.php delete mode 100644 lib/Zend/Filter/Compress/Lzf.php delete mode 100644 lib/Zend/Filter/Compress/Rar.php delete mode 100644 lib/Zend/Filter/Compress/Tar.php delete mode 100644 lib/Zend/Filter/Compress/Zip.php delete mode 100644 lib/Zend/Filter/Decompress.php delete mode 100644 lib/Zend/Filter/Decrypt.php delete mode 100644 lib/Zend/Filter/Digits.php delete mode 100644 lib/Zend/Filter/Dir.php delete mode 100644 lib/Zend/Filter/Encrypt.php delete mode 100644 lib/Zend/Filter/Encrypt/Interface.php delete mode 100644 lib/Zend/Filter/Encrypt/Mcrypt.php delete mode 100644 lib/Zend/Filter/Encrypt/Openssl.php delete mode 100644 lib/Zend/Filter/Exception.php delete mode 100644 lib/Zend/Filter/File/Decrypt.php delete mode 100644 lib/Zend/Filter/File/Encrypt.php delete mode 100644 lib/Zend/Filter/File/LowerCase.php delete mode 100644 lib/Zend/Filter/File/Rename.php delete mode 100644 lib/Zend/Filter/File/UpperCase.php delete mode 100644 lib/Zend/Filter/HtmlEntities.php delete mode 100644 lib/Zend/Filter/Inflector.php delete mode 100644 lib/Zend/Filter/Input.php delete mode 100644 lib/Zend/Filter/Int.php delete mode 100644 lib/Zend/Filter/Interface.php delete mode 100644 lib/Zend/Filter/LocalizedToNormalized.php delete mode 100644 lib/Zend/Filter/NormalizedToLocalized.php delete mode 100644 lib/Zend/Filter/Null.php delete mode 100644 lib/Zend/Filter/PregReplace.php delete mode 100644 lib/Zend/Filter/RealPath.php delete mode 100644 lib/Zend/Filter/StringToLower.php delete mode 100644 lib/Zend/Filter/StringToUpper.php delete mode 100644 lib/Zend/Filter/StringTrim.php delete mode 100644 lib/Zend/Filter/StripNewlines.php delete mode 100644 lib/Zend/Filter/StripTags.php delete mode 100644 lib/Zend/Filter/Word/CamelCaseToDash.php delete mode 100644 lib/Zend/Filter/Word/CamelCaseToSeparator.php delete mode 100644 lib/Zend/Filter/Word/CamelCaseToUnderscore.php delete mode 100644 lib/Zend/Filter/Word/DashToCamelCase.php delete mode 100644 lib/Zend/Filter/Word/DashToSeparator.php delete mode 100644 lib/Zend/Filter/Word/DashToUnderscore.php delete mode 100644 lib/Zend/Filter/Word/Separator/Abstract.php delete mode 100644 lib/Zend/Filter/Word/SeparatorToCamelCase.php delete mode 100644 lib/Zend/Filter/Word/SeparatorToDash.php delete mode 100644 lib/Zend/Filter/Word/SeparatorToSeparator.php delete mode 100644 lib/Zend/Filter/Word/UnderscoreToCamelCase.php delete mode 100644 lib/Zend/Filter/Word/UnderscoreToDash.php delete mode 100644 lib/Zend/Filter/Word/UnderscoreToSeparator.php delete mode 100644 lib/Zend/Form.php delete mode 100644 lib/Zend/Form/Decorator/Abstract.php delete mode 100644 lib/Zend/Form/Decorator/Callback.php delete mode 100644 lib/Zend/Form/Decorator/Captcha.php delete mode 100644 lib/Zend/Form/Decorator/Captcha/ReCaptcha.php delete mode 100644 lib/Zend/Form/Decorator/Captcha/Word.php delete mode 100644 lib/Zend/Form/Decorator/Description.php delete mode 100644 lib/Zend/Form/Decorator/DtDdWrapper.php delete mode 100644 lib/Zend/Form/Decorator/Errors.php delete mode 100644 lib/Zend/Form/Decorator/Exception.php delete mode 100644 lib/Zend/Form/Decorator/Fieldset.php delete mode 100644 lib/Zend/Form/Decorator/File.php delete mode 100644 lib/Zend/Form/Decorator/Form.php delete mode 100644 lib/Zend/Form/Decorator/FormElements.php delete mode 100644 lib/Zend/Form/Decorator/FormErrors.php delete mode 100644 lib/Zend/Form/Decorator/HtmlTag.php delete mode 100644 lib/Zend/Form/Decorator/Image.php delete mode 100644 lib/Zend/Form/Decorator/Interface.php delete mode 100644 lib/Zend/Form/Decorator/Label.php delete mode 100644 lib/Zend/Form/Decorator/Marker/File/Interface.php delete mode 100644 lib/Zend/Form/Decorator/PrepareElements.php delete mode 100644 lib/Zend/Form/Decorator/Tooltip.php delete mode 100644 lib/Zend/Form/Decorator/ViewHelper.php delete mode 100644 lib/Zend/Form/Decorator/ViewScript.php delete mode 100644 lib/Zend/Form/DisplayGroup.php delete mode 100644 lib/Zend/Form/Element.php delete mode 100644 lib/Zend/Form/Element/Button.php delete mode 100644 lib/Zend/Form/Element/Captcha.php delete mode 100644 lib/Zend/Form/Element/Checkbox.php delete mode 100644 lib/Zend/Form/Element/Exception.php delete mode 100644 lib/Zend/Form/Element/File.php delete mode 100644 lib/Zend/Form/Element/Hash.php delete mode 100644 lib/Zend/Form/Element/Hidden.php delete mode 100644 lib/Zend/Form/Element/Image.php delete mode 100644 lib/Zend/Form/Element/Multi.php delete mode 100644 lib/Zend/Form/Element/MultiCheckbox.php delete mode 100644 lib/Zend/Form/Element/Multiselect.php delete mode 100644 lib/Zend/Form/Element/Note.php delete mode 100644 lib/Zend/Form/Element/Password.php delete mode 100644 lib/Zend/Form/Element/Radio.php delete mode 100644 lib/Zend/Form/Element/Reset.php delete mode 100644 lib/Zend/Form/Element/Select.php delete mode 100644 lib/Zend/Form/Element/Submit.php delete mode 100644 lib/Zend/Form/Element/Text.php delete mode 100644 lib/Zend/Form/Element/Textarea.php delete mode 100644 lib/Zend/Form/Element/Xhtml.php delete mode 100644 lib/Zend/Form/Exception.php delete mode 100644 lib/Zend/Form/SubForm.php delete mode 100644 lib/Zend/Gdata.php delete mode 100644 lib/Zend/Gdata/Analytics.php delete mode 100644 lib/Zend/Gdata/Analytics/AccountEntry.php delete mode 100644 lib/Zend/Gdata/Analytics/AccountFeed.php delete mode 100644 lib/Zend/Gdata/Analytics/AccountQuery.php delete mode 100644 lib/Zend/Gdata/Analytics/DataEntry.php delete mode 100644 lib/Zend/Gdata/Analytics/DataFeed.php delete mode 100644 lib/Zend/Gdata/Analytics/DataQuery.php delete mode 100644 lib/Zend/Gdata/Analytics/Extension/Dimension.php delete mode 100644 lib/Zend/Gdata/Analytics/Extension/Goal.php delete mode 100644 lib/Zend/Gdata/Analytics/Extension/Metric.php delete mode 100644 lib/Zend/Gdata/Analytics/Extension/Property.php delete mode 100644 lib/Zend/Gdata/Analytics/Extension/TableId.php delete mode 100644 lib/Zend/Gdata/App.php delete mode 100644 lib/Zend/Gdata/App/AuthException.php delete mode 100644 lib/Zend/Gdata/App/BadMethodCallException.php delete mode 100644 lib/Zend/Gdata/App/Base.php delete mode 100644 lib/Zend/Gdata/App/BaseMediaSource.php delete mode 100644 lib/Zend/Gdata/App/CaptchaRequiredException.php delete mode 100644 lib/Zend/Gdata/App/Entry.php delete mode 100644 lib/Zend/Gdata/App/Exception.php delete mode 100644 lib/Zend/Gdata/App/Extension.php delete mode 100644 lib/Zend/Gdata/App/Extension/Author.php delete mode 100644 lib/Zend/Gdata/App/Extension/Category.php delete mode 100644 lib/Zend/Gdata/App/Extension/Content.php delete mode 100644 lib/Zend/Gdata/App/Extension/Contributor.php delete mode 100644 lib/Zend/Gdata/App/Extension/Control.php delete mode 100644 lib/Zend/Gdata/App/Extension/Draft.php delete mode 100644 lib/Zend/Gdata/App/Extension/Edited.php delete mode 100644 lib/Zend/Gdata/App/Extension/Element.php delete mode 100644 lib/Zend/Gdata/App/Extension/Email.php delete mode 100644 lib/Zend/Gdata/App/Extension/Generator.php delete mode 100644 lib/Zend/Gdata/App/Extension/Icon.php delete mode 100644 lib/Zend/Gdata/App/Extension/Id.php delete mode 100644 lib/Zend/Gdata/App/Extension/Link.php delete mode 100644 lib/Zend/Gdata/App/Extension/Logo.php delete mode 100644 lib/Zend/Gdata/App/Extension/Name.php delete mode 100644 lib/Zend/Gdata/App/Extension/Person.php delete mode 100644 lib/Zend/Gdata/App/Extension/Published.php delete mode 100644 lib/Zend/Gdata/App/Extension/Rights.php delete mode 100644 lib/Zend/Gdata/App/Extension/Source.php delete mode 100644 lib/Zend/Gdata/App/Extension/Subtitle.php delete mode 100644 lib/Zend/Gdata/App/Extension/Summary.php delete mode 100644 lib/Zend/Gdata/App/Extension/Text.php delete mode 100644 lib/Zend/Gdata/App/Extension/Title.php delete mode 100644 lib/Zend/Gdata/App/Extension/Updated.php delete mode 100644 lib/Zend/Gdata/App/Extension/Uri.php delete mode 100644 lib/Zend/Gdata/App/Feed.php delete mode 100644 lib/Zend/Gdata/App/FeedEntryParent.php delete mode 100644 lib/Zend/Gdata/App/FeedSourceParent.php delete mode 100644 lib/Zend/Gdata/App/HttpException.php delete mode 100644 lib/Zend/Gdata/App/IOException.php delete mode 100644 lib/Zend/Gdata/App/InvalidArgumentException.php delete mode 100644 lib/Zend/Gdata/App/LoggingHttpClientAdapterSocket.php delete mode 100644 lib/Zend/Gdata/App/MediaEntry.php delete mode 100644 lib/Zend/Gdata/App/MediaFileSource.php delete mode 100644 lib/Zend/Gdata/App/MediaSource.php delete mode 100644 lib/Zend/Gdata/App/Util.php delete mode 100644 lib/Zend/Gdata/App/VersionException.php delete mode 100644 lib/Zend/Gdata/AuthSub.php delete mode 100644 lib/Zend/Gdata/Books.php delete mode 100644 lib/Zend/Gdata/Books/CollectionEntry.php delete mode 100644 lib/Zend/Gdata/Books/CollectionFeed.php delete mode 100644 lib/Zend/Gdata/Books/Extension/AnnotationLink.php delete mode 100644 lib/Zend/Gdata/Books/Extension/BooksCategory.php delete mode 100644 lib/Zend/Gdata/Books/Extension/BooksLink.php delete mode 100644 lib/Zend/Gdata/Books/Extension/Embeddability.php delete mode 100644 lib/Zend/Gdata/Books/Extension/InfoLink.php delete mode 100644 lib/Zend/Gdata/Books/Extension/PreviewLink.php delete mode 100644 lib/Zend/Gdata/Books/Extension/Review.php delete mode 100644 lib/Zend/Gdata/Books/Extension/ThumbnailLink.php delete mode 100644 lib/Zend/Gdata/Books/Extension/Viewability.php delete mode 100644 lib/Zend/Gdata/Books/VolumeEntry.php delete mode 100644 lib/Zend/Gdata/Books/VolumeFeed.php delete mode 100644 lib/Zend/Gdata/Books/VolumeQuery.php delete mode 100644 lib/Zend/Gdata/Calendar.php delete mode 100644 lib/Zend/Gdata/Calendar/EventEntry.php delete mode 100644 lib/Zend/Gdata/Calendar/EventFeed.php delete mode 100644 lib/Zend/Gdata/Calendar/EventQuery.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/AccessLevel.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/Color.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/Hidden.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/Link.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/QuickAdd.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/Selected.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/SendEventNotifications.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/Timezone.php delete mode 100644 lib/Zend/Gdata/Calendar/Extension/WebContent.php delete mode 100644 lib/Zend/Gdata/Calendar/ListEntry.php delete mode 100644 lib/Zend/Gdata/Calendar/ListFeed.php delete mode 100644 lib/Zend/Gdata/ClientLogin.php delete mode 100644 lib/Zend/Gdata/Docs.php delete mode 100644 lib/Zend/Gdata/Docs/DocumentListEntry.php delete mode 100644 lib/Zend/Gdata/Docs/DocumentListFeed.php delete mode 100644 lib/Zend/Gdata/Docs/Query.php delete mode 100644 lib/Zend/Gdata/DublinCore.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Creator.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Date.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Description.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Format.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Identifier.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Language.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Publisher.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Rights.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Subject.php delete mode 100644 lib/Zend/Gdata/DublinCore/Extension/Title.php delete mode 100644 lib/Zend/Gdata/Entry.php delete mode 100644 lib/Zend/Gdata/Exif.php delete mode 100644 lib/Zend/Gdata/Exif/Entry.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Distance.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Exposure.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/FStop.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Flash.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/FocalLength.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/ImageUniqueId.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Iso.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Make.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Model.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Tags.php delete mode 100644 lib/Zend/Gdata/Exif/Extension/Time.php delete mode 100644 lib/Zend/Gdata/Exif/Feed.php delete mode 100644 lib/Zend/Gdata/Extension.php delete mode 100644 lib/Zend/Gdata/Extension/AttendeeStatus.php delete mode 100644 lib/Zend/Gdata/Extension/AttendeeType.php delete mode 100644 lib/Zend/Gdata/Extension/Comments.php delete mode 100644 lib/Zend/Gdata/Extension/EntryLink.php delete mode 100644 lib/Zend/Gdata/Extension/EventStatus.php delete mode 100644 lib/Zend/Gdata/Extension/ExtendedProperty.php delete mode 100644 lib/Zend/Gdata/Extension/FeedLink.php delete mode 100644 lib/Zend/Gdata/Extension/OpenSearchItemsPerPage.php delete mode 100644 lib/Zend/Gdata/Extension/OpenSearchStartIndex.php delete mode 100644 lib/Zend/Gdata/Extension/OpenSearchTotalResults.php delete mode 100644 lib/Zend/Gdata/Extension/OriginalEvent.php delete mode 100644 lib/Zend/Gdata/Extension/Rating.php delete mode 100644 lib/Zend/Gdata/Extension/Recurrence.php delete mode 100644 lib/Zend/Gdata/Extension/RecurrenceException.php delete mode 100644 lib/Zend/Gdata/Extension/Reminder.php delete mode 100644 lib/Zend/Gdata/Extension/Transparency.php delete mode 100644 lib/Zend/Gdata/Extension/Visibility.php delete mode 100644 lib/Zend/Gdata/Extension/When.php delete mode 100644 lib/Zend/Gdata/Extension/Where.php delete mode 100644 lib/Zend/Gdata/Extension/Who.php delete mode 100644 lib/Zend/Gdata/Feed.php delete mode 100644 lib/Zend/Gdata/Gapps.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListRecipientEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListRecipientFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/EmailListRecipientQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/Error.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/EmailList.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/Login.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/Name.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/Nickname.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/Property.php delete mode 100644 lib/Zend/Gdata/Gapps/Extension/Quota.php delete mode 100644 lib/Zend/Gdata/Gapps/GroupEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/GroupFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/GroupQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/MemberEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/MemberFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/MemberQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/NicknameEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/NicknameFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/NicknameQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/OwnerEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/OwnerFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/OwnerQuery.php delete mode 100644 lib/Zend/Gdata/Gapps/Query.php delete mode 100644 lib/Zend/Gdata/Gapps/ServiceException.php delete mode 100644 lib/Zend/Gdata/Gapps/UserEntry.php delete mode 100644 lib/Zend/Gdata/Gapps/UserFeed.php delete mode 100644 lib/Zend/Gdata/Gapps/UserQuery.php delete mode 100644 lib/Zend/Gdata/Gbase.php delete mode 100644 lib/Zend/Gdata/Gbase/Entry.php delete mode 100644 lib/Zend/Gdata/Gbase/Extension/BaseAttribute.php delete mode 100644 lib/Zend/Gdata/Gbase/Feed.php delete mode 100644 lib/Zend/Gdata/Gbase/ItemEntry.php delete mode 100644 lib/Zend/Gdata/Gbase/ItemFeed.php delete mode 100644 lib/Zend/Gdata/Gbase/ItemQuery.php delete mode 100644 lib/Zend/Gdata/Gbase/Query.php delete mode 100644 lib/Zend/Gdata/Gbase/SnippetEntry.php delete mode 100644 lib/Zend/Gdata/Gbase/SnippetFeed.php delete mode 100644 lib/Zend/Gdata/Gbase/SnippetQuery.php delete mode 100644 lib/Zend/Gdata/Geo.php delete mode 100644 lib/Zend/Gdata/Geo/Entry.php delete mode 100644 lib/Zend/Gdata/Geo/Extension/GeoRssWhere.php delete mode 100644 lib/Zend/Gdata/Geo/Extension/GmlPoint.php delete mode 100644 lib/Zend/Gdata/Geo/Extension/GmlPos.php delete mode 100644 lib/Zend/Gdata/Geo/Feed.php delete mode 100644 lib/Zend/Gdata/Health.php delete mode 100644 lib/Zend/Gdata/Health/Extension/Ccr.php delete mode 100644 lib/Zend/Gdata/Health/ProfileEntry.php delete mode 100644 lib/Zend/Gdata/Health/ProfileFeed.php delete mode 100644 lib/Zend/Gdata/Health/ProfileListEntry.php delete mode 100644 lib/Zend/Gdata/Health/ProfileListFeed.php delete mode 100644 lib/Zend/Gdata/Health/Query.php delete mode 100644 lib/Zend/Gdata/HttpAdapterStreamingProxy.php delete mode 100644 lib/Zend/Gdata/HttpAdapterStreamingSocket.php delete mode 100644 lib/Zend/Gdata/HttpClient.php delete mode 100644 lib/Zend/Gdata/Kind/EventEntry.php delete mode 100644 lib/Zend/Gdata/Media.php delete mode 100644 lib/Zend/Gdata/Media/Entry.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaCategory.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaContent.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaCopyright.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaCredit.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaDescription.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaGroup.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaHash.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaKeywords.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaPlayer.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaRating.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaRestriction.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaText.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaThumbnail.php delete mode 100644 lib/Zend/Gdata/Media/Extension/MediaTitle.php delete mode 100644 lib/Zend/Gdata/Media/Feed.php delete mode 100644 lib/Zend/Gdata/MediaMimeStream.php delete mode 100644 lib/Zend/Gdata/MimeBodyString.php delete mode 100644 lib/Zend/Gdata/MimeFile.php delete mode 100644 lib/Zend/Gdata/Photos.php delete mode 100644 lib/Zend/Gdata/Photos/AlbumEntry.php delete mode 100644 lib/Zend/Gdata/Photos/AlbumFeed.php delete mode 100644 lib/Zend/Gdata/Photos/AlbumQuery.php delete mode 100644 lib/Zend/Gdata/Photos/CommentEntry.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Access.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/AlbumId.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/BytesUsed.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Checksum.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Client.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/CommentCount.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/CommentingEnabled.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Height.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Id.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Location.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/MaxPhotosPerAlbum.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Name.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Nickname.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/NumPhotos.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/NumPhotosRemaining.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/PhotoId.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Position.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/QuotaCurrent.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/QuotaLimit.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Rotation.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Size.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Thumbnail.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Timestamp.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/User.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Version.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Weight.php delete mode 100644 lib/Zend/Gdata/Photos/Extension/Width.php delete mode 100644 lib/Zend/Gdata/Photos/PhotoEntry.php delete mode 100644 lib/Zend/Gdata/Photos/PhotoFeed.php delete mode 100644 lib/Zend/Gdata/Photos/PhotoQuery.php delete mode 100644 lib/Zend/Gdata/Photos/TagEntry.php delete mode 100644 lib/Zend/Gdata/Photos/UserEntry.php delete mode 100644 lib/Zend/Gdata/Photos/UserFeed.php delete mode 100644 lib/Zend/Gdata/Photos/UserQuery.php delete mode 100644 lib/Zend/Gdata/Query.php delete mode 100644 lib/Zend/Gdata/Spreadsheets.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/CellEntry.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/CellFeed.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/CellQuery.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/DocumentQuery.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/Extension/Cell.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/Extension/ColCount.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/Extension/Custom.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/Extension/RowCount.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/ListEntry.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/ListFeed.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/ListQuery.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/SpreadsheetEntry.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/SpreadsheetFeed.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/WorksheetEntry.php delete mode 100644 lib/Zend/Gdata/Spreadsheets/WorksheetFeed.php delete mode 100644 lib/Zend/Gdata/YouTube.php delete mode 100644 lib/Zend/Gdata/YouTube/ActivityEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/ActivityFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/CommentEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/CommentFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/ContactEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/ContactFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/AboutMe.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Age.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Books.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Company.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Control.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/CountHint.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Description.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Duration.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/FirstName.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Gender.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Hobbies.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Hometown.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/LastName.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Link.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Location.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/MediaContent.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/MediaCredit.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/MediaGroup.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/MediaRating.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Movies.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Music.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/NoEmbed.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Occupation.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/PlaylistId.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/PlaylistTitle.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Position.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Private.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/QueryString.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Racy.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Recorded.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Relationship.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/ReleaseDate.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/School.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/State.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Statistics.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Status.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Token.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Uploaded.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/Username.php delete mode 100644 lib/Zend/Gdata/YouTube/Extension/VideoId.php delete mode 100644 lib/Zend/Gdata/YouTube/InboxEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/InboxFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/MediaEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/PlaylistListEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/PlaylistListFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/PlaylistVideoEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/PlaylistVideoFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/SubscriptionEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/SubscriptionFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/UserProfileEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/VideoEntry.php delete mode 100644 lib/Zend/Gdata/YouTube/VideoFeed.php delete mode 100644 lib/Zend/Gdata/YouTube/VideoQuery.php delete mode 100644 lib/Zend/Http/Client.php delete mode 100644 lib/Zend/Http/Client/Adapter/Curl.php delete mode 100644 lib/Zend/Http/Client/Adapter/Exception.php delete mode 100644 lib/Zend/Http/Client/Adapter/Interface.php delete mode 100644 lib/Zend/Http/Client/Adapter/Proxy.php delete mode 100644 lib/Zend/Http/Client/Adapter/Socket.php delete mode 100644 lib/Zend/Http/Client/Adapter/Stream.php delete mode 100644 lib/Zend/Http/Client/Adapter/Test.php delete mode 100644 lib/Zend/Http/Client/Exception.php delete mode 100644 lib/Zend/Http/Cookie.php delete mode 100644 lib/Zend/Http/CookieJar.php delete mode 100644 lib/Zend/Http/Exception.php delete mode 100644 lib/Zend/Http/Header/Exception/InvalidArgumentException.php delete mode 100644 lib/Zend/Http/Header/Exception/RuntimeException.php delete mode 100644 lib/Zend/Http/Header/HeaderValue.php delete mode 100644 lib/Zend/Http/Header/SetCookie.php delete mode 100644 lib/Zend/Http/Response.php delete mode 100644 lib/Zend/Http/Response/Stream.php delete mode 100644 lib/Zend/Http/UserAgent.php delete mode 100644 lib/Zend/Http/UserAgent/AbstractDevice.php delete mode 100644 lib/Zend/Http/UserAgent/Bot.php delete mode 100644 lib/Zend/Http/UserAgent/Checker.php delete mode 100644 lib/Zend/Http/UserAgent/Console.php delete mode 100644 lib/Zend/Http/UserAgent/Desktop.php delete mode 100644 lib/Zend/Http/UserAgent/Device.php delete mode 100644 lib/Zend/Http/UserAgent/Email.php delete mode 100644 lib/Zend/Http/UserAgent/Exception.php delete mode 100644 lib/Zend/Http/UserAgent/Features/Adapter.php delete mode 100644 lib/Zend/Http/UserAgent/Features/Adapter/Browscap.php delete mode 100644 lib/Zend/Http/UserAgent/Features/Adapter/DeviceAtlas.php delete mode 100644 lib/Zend/Http/UserAgent/Features/Adapter/TeraWurfl.php delete mode 100644 lib/Zend/Http/UserAgent/Features/Exception.php delete mode 100644 lib/Zend/Http/UserAgent/Feed.php delete mode 100644 lib/Zend/Http/UserAgent/Mobile.php delete mode 100644 lib/Zend/Http/UserAgent/Offline.php delete mode 100644 lib/Zend/Http/UserAgent/Probe.php delete mode 100644 lib/Zend/Http/UserAgent/Spam.php delete mode 100644 lib/Zend/Http/UserAgent/Storage.php delete mode 100644 lib/Zend/Http/UserAgent/Storage/Exception.php delete mode 100644 lib/Zend/Http/UserAgent/Storage/NonPersistent.php delete mode 100644 lib/Zend/Http/UserAgent/Storage/Session.php delete mode 100644 lib/Zend/Http/UserAgent/Text.php delete mode 100644 lib/Zend/Http/UserAgent/Validator.php delete mode 100644 lib/Zend/Json.php delete mode 100644 lib/Zend/Json/Decoder.php delete mode 100644 lib/Zend/Json/Encoder.php delete mode 100644 lib/Zend/Json/Exception.php delete mode 100644 lib/Zend/Json/Expr.php delete mode 100644 lib/Zend/Json/Server.php delete mode 100644 lib/Zend/Json/Server/Cache.php delete mode 100644 lib/Zend/Json/Server/Error.php delete mode 100644 lib/Zend/Json/Server/Exception.php delete mode 100644 lib/Zend/Json/Server/Request.php delete mode 100644 lib/Zend/Json/Server/Request/Http.php delete mode 100644 lib/Zend/Json/Server/Response.php delete mode 100644 lib/Zend/Json/Server/Response/Http.php delete mode 100644 lib/Zend/Json/Server/Smd.php delete mode 100644 lib/Zend/Json/Server/Smd/Service.php delete mode 100644 lib/Zend/Layout.php delete mode 100644 lib/Zend/Layout/Controller/Action/Helper/Layout.php delete mode 100644 lib/Zend/Layout/Controller/Plugin/Layout.php delete mode 100644 lib/Zend/Layout/Exception.php delete mode 100644 lib/Zend/Ldap.php delete mode 100644 lib/Zend/Ldap/Attribute.php delete mode 100644 lib/Zend/Ldap/Collection.php delete mode 100644 lib/Zend/Ldap/Collection/Iterator/Default.php delete mode 100644 lib/Zend/Ldap/Converter.php delete mode 100644 lib/Zend/Ldap/Converter/Exception.php delete mode 100644 lib/Zend/Ldap/Dn.php delete mode 100644 lib/Zend/Ldap/Exception.php delete mode 100644 lib/Zend/Ldap/Filter.php delete mode 100644 lib/Zend/Ldap/Filter/Abstract.php delete mode 100644 lib/Zend/Ldap/Filter/And.php delete mode 100644 lib/Zend/Ldap/Filter/Exception.php delete mode 100644 lib/Zend/Ldap/Filter/Logical.php delete mode 100644 lib/Zend/Ldap/Filter/Mask.php delete mode 100644 lib/Zend/Ldap/Filter/Not.php delete mode 100644 lib/Zend/Ldap/Filter/Or.php delete mode 100644 lib/Zend/Ldap/Filter/String.php delete mode 100644 lib/Zend/Ldap/Ldif/Encoder.php delete mode 100644 lib/Zend/Ldap/Node.php delete mode 100644 lib/Zend/Ldap/Node/Abstract.php delete mode 100644 lib/Zend/Ldap/Node/ChildrenIterator.php delete mode 100644 lib/Zend/Ldap/Node/Collection.php delete mode 100644 lib/Zend/Ldap/Node/RootDse.php delete mode 100644 lib/Zend/Ldap/Node/RootDse/ActiveDirectory.php delete mode 100644 lib/Zend/Ldap/Node/RootDse/OpenLdap.php delete mode 100644 lib/Zend/Ldap/Node/RootDse/eDirectory.php delete mode 100644 lib/Zend/Ldap/Node/Schema.php delete mode 100644 lib/Zend/Ldap/Node/Schema/ActiveDirectory.php delete mode 100644 lib/Zend/Ldap/Node/Schema/AttributeType/ActiveDirectory.php delete mode 100644 lib/Zend/Ldap/Node/Schema/AttributeType/Interface.php delete mode 100644 lib/Zend/Ldap/Node/Schema/AttributeType/OpenLdap.php delete mode 100644 lib/Zend/Ldap/Node/Schema/Item.php delete mode 100644 lib/Zend/Ldap/Node/Schema/ObjectClass/ActiveDirectory.php delete mode 100644 lib/Zend/Ldap/Node/Schema/ObjectClass/Interface.php delete mode 100644 lib/Zend/Ldap/Node/Schema/ObjectClass/OpenLdap.php delete mode 100644 lib/Zend/Ldap/Node/Schema/OpenLdap.php delete mode 100644 lib/Zend/Loader.php delete mode 100644 lib/Zend/Loader/Autoloader.php delete mode 100644 lib/Zend/Loader/Autoloader/Interface.php delete mode 100644 lib/Zend/Loader/Autoloader/Resource.php delete mode 100644 lib/Zend/Loader/AutoloaderFactory.php delete mode 100644 lib/Zend/Loader/ClassMapAutoloader.php delete mode 100644 lib/Zend/Loader/Exception.php delete mode 100644 lib/Zend/Loader/Exception/InvalidArgumentException.php delete mode 100644 lib/Zend/Loader/PluginLoader.php delete mode 100644 lib/Zend/Loader/PluginLoader/Exception.php delete mode 100644 lib/Zend/Loader/PluginLoader/Interface.php delete mode 100644 lib/Zend/Loader/SplAutoloader.php delete mode 100644 lib/Zend/Loader/StandardAutoloader.php delete mode 100644 lib/Zend/Locale.php delete mode 100644 lib/Zend/Locale/Data.php delete mode 100644 lib/Zend/Locale/Data/Translation.php delete mode 100644 lib/Zend/Locale/Data/aa.xml delete mode 100644 lib/Zend/Locale/Data/aa_DJ.xml delete mode 100644 lib/Zend/Locale/Data/aa_ER.xml delete mode 100644 lib/Zend/Locale/Data/aa_ET.xml delete mode 100644 lib/Zend/Locale/Data/af.xml delete mode 100644 lib/Zend/Locale/Data/af_NA.xml delete mode 100644 lib/Zend/Locale/Data/af_ZA.xml delete mode 100644 lib/Zend/Locale/Data/agq.xml delete mode 100644 lib/Zend/Locale/Data/agq_CM.xml delete mode 100644 lib/Zend/Locale/Data/ak.xml delete mode 100644 lib/Zend/Locale/Data/ak_GH.xml delete mode 100644 lib/Zend/Locale/Data/am.xml delete mode 100644 lib/Zend/Locale/Data/am_ET.xml delete mode 100644 lib/Zend/Locale/Data/ar.xml delete mode 100644 lib/Zend/Locale/Data/ar_001.xml delete mode 100644 lib/Zend/Locale/Data/ar_AE.xml delete mode 100644 lib/Zend/Locale/Data/ar_BH.xml delete mode 100644 lib/Zend/Locale/Data/ar_DJ.xml delete mode 100644 lib/Zend/Locale/Data/ar_DZ.xml delete mode 100644 lib/Zend/Locale/Data/ar_EG.xml delete mode 100644 lib/Zend/Locale/Data/ar_EH.xml delete mode 100644 lib/Zend/Locale/Data/ar_ER.xml delete mode 100644 lib/Zend/Locale/Data/ar_IL.xml delete mode 100644 lib/Zend/Locale/Data/ar_IQ.xml delete mode 100644 lib/Zend/Locale/Data/ar_JO.xml delete mode 100644 lib/Zend/Locale/Data/ar_KM.xml delete mode 100644 lib/Zend/Locale/Data/ar_KW.xml delete mode 100644 lib/Zend/Locale/Data/ar_LB.xml delete mode 100644 lib/Zend/Locale/Data/ar_LY.xml delete mode 100644 lib/Zend/Locale/Data/ar_MA.xml delete mode 100644 lib/Zend/Locale/Data/ar_MR.xml delete mode 100644 lib/Zend/Locale/Data/ar_OM.xml delete mode 100644 lib/Zend/Locale/Data/ar_PS.xml delete mode 100644 lib/Zend/Locale/Data/ar_QA.xml delete mode 100644 lib/Zend/Locale/Data/ar_SA.xml delete mode 100644 lib/Zend/Locale/Data/ar_SD.xml delete mode 100644 lib/Zend/Locale/Data/ar_SO.xml delete mode 100644 lib/Zend/Locale/Data/ar_SS.xml delete mode 100644 lib/Zend/Locale/Data/ar_SY.xml delete mode 100644 lib/Zend/Locale/Data/ar_TD.xml delete mode 100644 lib/Zend/Locale/Data/ar_TN.xml delete mode 100644 lib/Zend/Locale/Data/ar_YE.xml delete mode 100644 lib/Zend/Locale/Data/as.xml delete mode 100644 lib/Zend/Locale/Data/as_IN.xml delete mode 100644 lib/Zend/Locale/Data/asa.xml delete mode 100644 lib/Zend/Locale/Data/asa_TZ.xml delete mode 100644 lib/Zend/Locale/Data/ast.xml delete mode 100644 lib/Zend/Locale/Data/ast_ES.xml delete mode 100644 lib/Zend/Locale/Data/az.xml delete mode 100644 lib/Zend/Locale/Data/az_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/az_Cyrl_AZ.xml delete mode 100644 lib/Zend/Locale/Data/az_Latn.xml delete mode 100644 lib/Zend/Locale/Data/az_Latn_AZ.xml delete mode 100644 lib/Zend/Locale/Data/bas.xml delete mode 100644 lib/Zend/Locale/Data/bas_CM.xml delete mode 100644 lib/Zend/Locale/Data/be.xml delete mode 100644 lib/Zend/Locale/Data/be_BY.xml delete mode 100644 lib/Zend/Locale/Data/bem.xml delete mode 100644 lib/Zend/Locale/Data/bem_ZM.xml delete mode 100644 lib/Zend/Locale/Data/bez.xml delete mode 100644 lib/Zend/Locale/Data/bez_TZ.xml delete mode 100644 lib/Zend/Locale/Data/bg.xml delete mode 100644 lib/Zend/Locale/Data/bg_BG.xml delete mode 100644 lib/Zend/Locale/Data/bm.xml delete mode 100644 lib/Zend/Locale/Data/bm_ML.xml delete mode 100644 lib/Zend/Locale/Data/bn.xml delete mode 100644 lib/Zend/Locale/Data/bn_BD.xml delete mode 100644 lib/Zend/Locale/Data/bn_IN.xml delete mode 100644 lib/Zend/Locale/Data/bo.xml delete mode 100644 lib/Zend/Locale/Data/bo_CN.xml delete mode 100644 lib/Zend/Locale/Data/bo_IN.xml delete mode 100644 lib/Zend/Locale/Data/br.xml delete mode 100644 lib/Zend/Locale/Data/br_FR.xml delete mode 100644 lib/Zend/Locale/Data/brx.xml delete mode 100644 lib/Zend/Locale/Data/brx_IN.xml delete mode 100644 lib/Zend/Locale/Data/bs.xml delete mode 100644 lib/Zend/Locale/Data/bs_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/bs_Cyrl_BA.xml delete mode 100644 lib/Zend/Locale/Data/bs_Latn.xml delete mode 100644 lib/Zend/Locale/Data/bs_Latn_BA.xml delete mode 100644 lib/Zend/Locale/Data/byn.xml delete mode 100644 lib/Zend/Locale/Data/byn_ER.xml delete mode 100644 lib/Zend/Locale/Data/ca.xml delete mode 100644 lib/Zend/Locale/Data/ca_AD.xml delete mode 100644 lib/Zend/Locale/Data/ca_ES.xml delete mode 100644 lib/Zend/Locale/Data/ca_ES_VALENCIA.xml delete mode 100644 lib/Zend/Locale/Data/ca_FR.xml delete mode 100644 lib/Zend/Locale/Data/ca_IT.xml delete mode 100644 lib/Zend/Locale/Data/cgg.xml delete mode 100644 lib/Zend/Locale/Data/cgg_UG.xml delete mode 100644 lib/Zend/Locale/Data/characters.xml delete mode 100644 lib/Zend/Locale/Data/chr.xml delete mode 100644 lib/Zend/Locale/Data/chr_US.xml delete mode 100644 lib/Zend/Locale/Data/coverageLevels.xml delete mode 100644 lib/Zend/Locale/Data/cs.xml delete mode 100644 lib/Zend/Locale/Data/cs_CZ.xml delete mode 100644 lib/Zend/Locale/Data/cy.xml delete mode 100644 lib/Zend/Locale/Data/cy_GB.xml delete mode 100644 lib/Zend/Locale/Data/da.xml delete mode 100644 lib/Zend/Locale/Data/da_DK.xml delete mode 100644 lib/Zend/Locale/Data/da_GL.xml delete mode 100644 lib/Zend/Locale/Data/dav.xml delete mode 100644 lib/Zend/Locale/Data/dav_KE.xml delete mode 100644 lib/Zend/Locale/Data/dayPeriods.xml delete mode 100644 lib/Zend/Locale/Data/de.xml delete mode 100644 lib/Zend/Locale/Data/de_AT.xml delete mode 100644 lib/Zend/Locale/Data/de_BE.xml delete mode 100644 lib/Zend/Locale/Data/de_CH.xml delete mode 100644 lib/Zend/Locale/Data/de_DE.xml delete mode 100644 lib/Zend/Locale/Data/de_LI.xml delete mode 100644 lib/Zend/Locale/Data/de_LU.xml delete mode 100644 lib/Zend/Locale/Data/dje.xml delete mode 100644 lib/Zend/Locale/Data/dje_NE.xml delete mode 100644 lib/Zend/Locale/Data/dua.xml delete mode 100644 lib/Zend/Locale/Data/dua_CM.xml delete mode 100644 lib/Zend/Locale/Data/dyo.xml delete mode 100644 lib/Zend/Locale/Data/dyo_SN.xml delete mode 100644 lib/Zend/Locale/Data/dz.xml delete mode 100644 lib/Zend/Locale/Data/dz_BT.xml delete mode 100644 lib/Zend/Locale/Data/ebu.xml delete mode 100644 lib/Zend/Locale/Data/ebu_KE.xml delete mode 100644 lib/Zend/Locale/Data/ee.xml delete mode 100644 lib/Zend/Locale/Data/ee_GH.xml delete mode 100644 lib/Zend/Locale/Data/ee_TG.xml delete mode 100644 lib/Zend/Locale/Data/el.xml delete mode 100644 lib/Zend/Locale/Data/el_CY.xml delete mode 100644 lib/Zend/Locale/Data/el_GR.xml delete mode 100644 lib/Zend/Locale/Data/en.xml delete mode 100644 lib/Zend/Locale/Data/en_001.xml delete mode 100644 lib/Zend/Locale/Data/en_150.xml delete mode 100644 lib/Zend/Locale/Data/en_AG.xml delete mode 100644 lib/Zend/Locale/Data/en_AI.xml delete mode 100644 lib/Zend/Locale/Data/en_AS.xml delete mode 100644 lib/Zend/Locale/Data/en_AU.xml delete mode 100644 lib/Zend/Locale/Data/en_BB.xml delete mode 100644 lib/Zend/Locale/Data/en_BE.xml delete mode 100644 lib/Zend/Locale/Data/en_BM.xml delete mode 100644 lib/Zend/Locale/Data/en_BS.xml delete mode 100644 lib/Zend/Locale/Data/en_BW.xml delete mode 100644 lib/Zend/Locale/Data/en_BZ.xml delete mode 100644 lib/Zend/Locale/Data/en_CA.xml delete mode 100644 lib/Zend/Locale/Data/en_CC.xml delete mode 100644 lib/Zend/Locale/Data/en_CK.xml delete mode 100644 lib/Zend/Locale/Data/en_CM.xml delete mode 100644 lib/Zend/Locale/Data/en_CX.xml delete mode 100644 lib/Zend/Locale/Data/en_DG.xml delete mode 100644 lib/Zend/Locale/Data/en_DM.xml delete mode 100644 lib/Zend/Locale/Data/en_Dsrt.xml delete mode 100644 lib/Zend/Locale/Data/en_Dsrt_US.xml delete mode 100644 lib/Zend/Locale/Data/en_ER.xml delete mode 100644 lib/Zend/Locale/Data/en_FJ.xml delete mode 100644 lib/Zend/Locale/Data/en_FK.xml delete mode 100644 lib/Zend/Locale/Data/en_FM.xml delete mode 100644 lib/Zend/Locale/Data/en_GB.xml delete mode 100644 lib/Zend/Locale/Data/en_GD.xml delete mode 100644 lib/Zend/Locale/Data/en_GG.xml delete mode 100644 lib/Zend/Locale/Data/en_GH.xml delete mode 100644 lib/Zend/Locale/Data/en_GI.xml delete mode 100644 lib/Zend/Locale/Data/en_GM.xml delete mode 100644 lib/Zend/Locale/Data/en_GU.xml delete mode 100644 lib/Zend/Locale/Data/en_GY.xml delete mode 100644 lib/Zend/Locale/Data/en_HK.xml delete mode 100644 lib/Zend/Locale/Data/en_IE.xml delete mode 100644 lib/Zend/Locale/Data/en_IM.xml delete mode 100644 lib/Zend/Locale/Data/en_IN.xml delete mode 100644 lib/Zend/Locale/Data/en_IO.xml delete mode 100644 lib/Zend/Locale/Data/en_JE.xml delete mode 100644 lib/Zend/Locale/Data/en_JM.xml delete mode 100644 lib/Zend/Locale/Data/en_KE.xml delete mode 100644 lib/Zend/Locale/Data/en_KI.xml delete mode 100644 lib/Zend/Locale/Data/en_KN.xml delete mode 100644 lib/Zend/Locale/Data/en_KY.xml delete mode 100644 lib/Zend/Locale/Data/en_LC.xml delete mode 100644 lib/Zend/Locale/Data/en_LR.xml delete mode 100644 lib/Zend/Locale/Data/en_LS.xml delete mode 100644 lib/Zend/Locale/Data/en_MG.xml delete mode 100644 lib/Zend/Locale/Data/en_MH.xml delete mode 100644 lib/Zend/Locale/Data/en_MO.xml delete mode 100644 lib/Zend/Locale/Data/en_MP.xml delete mode 100644 lib/Zend/Locale/Data/en_MS.xml delete mode 100644 lib/Zend/Locale/Data/en_MT.xml delete mode 100644 lib/Zend/Locale/Data/en_MU.xml delete mode 100644 lib/Zend/Locale/Data/en_MW.xml delete mode 100644 lib/Zend/Locale/Data/en_NA.xml delete mode 100644 lib/Zend/Locale/Data/en_NF.xml delete mode 100644 lib/Zend/Locale/Data/en_NG.xml delete mode 100644 lib/Zend/Locale/Data/en_NR.xml delete mode 100644 lib/Zend/Locale/Data/en_NU.xml delete mode 100644 lib/Zend/Locale/Data/en_NZ.xml delete mode 100644 lib/Zend/Locale/Data/en_PG.xml delete mode 100644 lib/Zend/Locale/Data/en_PH.xml delete mode 100644 lib/Zend/Locale/Data/en_PK.xml delete mode 100644 lib/Zend/Locale/Data/en_PN.xml delete mode 100644 lib/Zend/Locale/Data/en_PR.xml delete mode 100644 lib/Zend/Locale/Data/en_PW.xml delete mode 100644 lib/Zend/Locale/Data/en_RW.xml delete mode 100644 lib/Zend/Locale/Data/en_SB.xml delete mode 100644 lib/Zend/Locale/Data/en_SC.xml delete mode 100644 lib/Zend/Locale/Data/en_SD.xml delete mode 100644 lib/Zend/Locale/Data/en_SG.xml delete mode 100644 lib/Zend/Locale/Data/en_SH.xml delete mode 100644 lib/Zend/Locale/Data/en_SL.xml delete mode 100644 lib/Zend/Locale/Data/en_SS.xml delete mode 100644 lib/Zend/Locale/Data/en_SX.xml delete mode 100644 lib/Zend/Locale/Data/en_SZ.xml delete mode 100644 lib/Zend/Locale/Data/en_TC.xml delete mode 100644 lib/Zend/Locale/Data/en_TK.xml delete mode 100644 lib/Zend/Locale/Data/en_TO.xml delete mode 100644 lib/Zend/Locale/Data/en_TT.xml delete mode 100644 lib/Zend/Locale/Data/en_TV.xml delete mode 100644 lib/Zend/Locale/Data/en_TZ.xml delete mode 100644 lib/Zend/Locale/Data/en_UG.xml delete mode 100644 lib/Zend/Locale/Data/en_UM.xml delete mode 100644 lib/Zend/Locale/Data/en_US.xml delete mode 100644 lib/Zend/Locale/Data/en_US_POSIX.xml delete mode 100644 lib/Zend/Locale/Data/en_VC.xml delete mode 100644 lib/Zend/Locale/Data/en_VG.xml delete mode 100644 lib/Zend/Locale/Data/en_VI.xml delete mode 100644 lib/Zend/Locale/Data/en_VU.xml delete mode 100644 lib/Zend/Locale/Data/en_WS.xml delete mode 100644 lib/Zend/Locale/Data/en_ZA.xml delete mode 100644 lib/Zend/Locale/Data/en_ZM.xml delete mode 100644 lib/Zend/Locale/Data/en_ZW.xml delete mode 100644 lib/Zend/Locale/Data/eo.xml delete mode 100644 lib/Zend/Locale/Data/eo_001.xml delete mode 100644 lib/Zend/Locale/Data/es.xml delete mode 100644 lib/Zend/Locale/Data/es_419.xml delete mode 100644 lib/Zend/Locale/Data/es_AR.xml delete mode 100644 lib/Zend/Locale/Data/es_BO.xml delete mode 100644 lib/Zend/Locale/Data/es_CL.xml delete mode 100644 lib/Zend/Locale/Data/es_CO.xml delete mode 100644 lib/Zend/Locale/Data/es_CR.xml delete mode 100644 lib/Zend/Locale/Data/es_CU.xml delete mode 100644 lib/Zend/Locale/Data/es_DO.xml delete mode 100644 lib/Zend/Locale/Data/es_EA.xml delete mode 100644 lib/Zend/Locale/Data/es_EC.xml delete mode 100644 lib/Zend/Locale/Data/es_ES.xml delete mode 100644 lib/Zend/Locale/Data/es_GQ.xml delete mode 100644 lib/Zend/Locale/Data/es_GT.xml delete mode 100644 lib/Zend/Locale/Data/es_HN.xml delete mode 100644 lib/Zend/Locale/Data/es_IC.xml delete mode 100644 lib/Zend/Locale/Data/es_MX.xml delete mode 100644 lib/Zend/Locale/Data/es_NI.xml delete mode 100644 lib/Zend/Locale/Data/es_PA.xml delete mode 100644 lib/Zend/Locale/Data/es_PE.xml delete mode 100644 lib/Zend/Locale/Data/es_PH.xml delete mode 100644 lib/Zend/Locale/Data/es_PR.xml delete mode 100644 lib/Zend/Locale/Data/es_PY.xml delete mode 100644 lib/Zend/Locale/Data/es_SV.xml delete mode 100644 lib/Zend/Locale/Data/es_US.xml delete mode 100644 lib/Zend/Locale/Data/es_UY.xml delete mode 100644 lib/Zend/Locale/Data/es_VE.xml delete mode 100644 lib/Zend/Locale/Data/et.xml delete mode 100644 lib/Zend/Locale/Data/et_EE.xml delete mode 100644 lib/Zend/Locale/Data/eu.xml delete mode 100644 lib/Zend/Locale/Data/eu_ES.xml delete mode 100644 lib/Zend/Locale/Data/ewo.xml delete mode 100644 lib/Zend/Locale/Data/ewo_CM.xml delete mode 100644 lib/Zend/Locale/Data/fa.xml delete mode 100644 lib/Zend/Locale/Data/fa_AF.xml delete mode 100644 lib/Zend/Locale/Data/fa_IR.xml delete mode 100644 lib/Zend/Locale/Data/ff.xml delete mode 100644 lib/Zend/Locale/Data/ff_CM.xml delete mode 100644 lib/Zend/Locale/Data/ff_GN.xml delete mode 100644 lib/Zend/Locale/Data/ff_MR.xml delete mode 100644 lib/Zend/Locale/Data/ff_SN.xml delete mode 100644 lib/Zend/Locale/Data/fi.xml delete mode 100644 lib/Zend/Locale/Data/fi_FI.xml delete mode 100644 lib/Zend/Locale/Data/fil.xml delete mode 100644 lib/Zend/Locale/Data/fil_PH.xml delete mode 100644 lib/Zend/Locale/Data/fo.xml delete mode 100644 lib/Zend/Locale/Data/fo_FO.xml delete mode 100644 lib/Zend/Locale/Data/fr.xml delete mode 100644 lib/Zend/Locale/Data/fr_BE.xml delete mode 100644 lib/Zend/Locale/Data/fr_BF.xml delete mode 100644 lib/Zend/Locale/Data/fr_BI.xml delete mode 100644 lib/Zend/Locale/Data/fr_BJ.xml delete mode 100644 lib/Zend/Locale/Data/fr_BL.xml delete mode 100644 lib/Zend/Locale/Data/fr_CA.xml delete mode 100644 lib/Zend/Locale/Data/fr_CD.xml delete mode 100644 lib/Zend/Locale/Data/fr_CF.xml delete mode 100644 lib/Zend/Locale/Data/fr_CG.xml delete mode 100644 lib/Zend/Locale/Data/fr_CH.xml delete mode 100644 lib/Zend/Locale/Data/fr_CI.xml delete mode 100644 lib/Zend/Locale/Data/fr_CM.xml delete mode 100644 lib/Zend/Locale/Data/fr_DJ.xml delete mode 100644 lib/Zend/Locale/Data/fr_DZ.xml delete mode 100644 lib/Zend/Locale/Data/fr_FR.xml delete mode 100644 lib/Zend/Locale/Data/fr_GA.xml delete mode 100644 lib/Zend/Locale/Data/fr_GF.xml delete mode 100644 lib/Zend/Locale/Data/fr_GN.xml delete mode 100644 lib/Zend/Locale/Data/fr_GP.xml delete mode 100644 lib/Zend/Locale/Data/fr_GQ.xml delete mode 100644 lib/Zend/Locale/Data/fr_HT.xml delete mode 100644 lib/Zend/Locale/Data/fr_KM.xml delete mode 100644 lib/Zend/Locale/Data/fr_LU.xml delete mode 100644 lib/Zend/Locale/Data/fr_MA.xml delete mode 100644 lib/Zend/Locale/Data/fr_MC.xml delete mode 100644 lib/Zend/Locale/Data/fr_MF.xml delete mode 100644 lib/Zend/Locale/Data/fr_MG.xml delete mode 100644 lib/Zend/Locale/Data/fr_ML.xml delete mode 100644 lib/Zend/Locale/Data/fr_MQ.xml delete mode 100644 lib/Zend/Locale/Data/fr_MR.xml delete mode 100644 lib/Zend/Locale/Data/fr_MU.xml delete mode 100644 lib/Zend/Locale/Data/fr_NC.xml delete mode 100644 lib/Zend/Locale/Data/fr_NE.xml delete mode 100644 lib/Zend/Locale/Data/fr_PF.xml delete mode 100644 lib/Zend/Locale/Data/fr_PM.xml delete mode 100644 lib/Zend/Locale/Data/fr_RE.xml delete mode 100644 lib/Zend/Locale/Data/fr_RW.xml delete mode 100644 lib/Zend/Locale/Data/fr_SC.xml delete mode 100644 lib/Zend/Locale/Data/fr_SN.xml delete mode 100644 lib/Zend/Locale/Data/fr_SY.xml delete mode 100644 lib/Zend/Locale/Data/fr_TD.xml delete mode 100644 lib/Zend/Locale/Data/fr_TG.xml delete mode 100644 lib/Zend/Locale/Data/fr_TN.xml delete mode 100644 lib/Zend/Locale/Data/fr_VU.xml delete mode 100644 lib/Zend/Locale/Data/fr_WF.xml delete mode 100644 lib/Zend/Locale/Data/fr_YT.xml delete mode 100644 lib/Zend/Locale/Data/fur.xml delete mode 100644 lib/Zend/Locale/Data/fur_IT.xml delete mode 100644 lib/Zend/Locale/Data/fy.xml delete mode 100644 lib/Zend/Locale/Data/fy_NL.xml delete mode 100644 lib/Zend/Locale/Data/ga.xml delete mode 100644 lib/Zend/Locale/Data/ga_IE.xml delete mode 100644 lib/Zend/Locale/Data/gd.xml delete mode 100644 lib/Zend/Locale/Data/gd_GB.xml delete mode 100644 lib/Zend/Locale/Data/genderList.xml delete mode 100644 lib/Zend/Locale/Data/gl.xml delete mode 100644 lib/Zend/Locale/Data/gl_ES.xml delete mode 100644 lib/Zend/Locale/Data/gsw.xml delete mode 100644 lib/Zend/Locale/Data/gsw_CH.xml delete mode 100644 lib/Zend/Locale/Data/gsw_LI.xml delete mode 100644 lib/Zend/Locale/Data/gu.xml delete mode 100644 lib/Zend/Locale/Data/gu_IN.xml delete mode 100644 lib/Zend/Locale/Data/guz.xml delete mode 100644 lib/Zend/Locale/Data/guz_KE.xml delete mode 100644 lib/Zend/Locale/Data/gv.xml delete mode 100644 lib/Zend/Locale/Data/gv_IM.xml delete mode 100644 lib/Zend/Locale/Data/ha.xml delete mode 100644 lib/Zend/Locale/Data/ha_Latn.xml delete mode 100644 lib/Zend/Locale/Data/ha_Latn_GH.xml delete mode 100644 lib/Zend/Locale/Data/ha_Latn_NE.xml delete mode 100644 lib/Zend/Locale/Data/ha_Latn_NG.xml delete mode 100644 lib/Zend/Locale/Data/haw.xml delete mode 100644 lib/Zend/Locale/Data/haw_US.xml delete mode 100644 lib/Zend/Locale/Data/he.xml delete mode 100644 lib/Zend/Locale/Data/he_IL.xml delete mode 100644 lib/Zend/Locale/Data/hi.xml delete mode 100644 lib/Zend/Locale/Data/hi_IN.xml delete mode 100644 lib/Zend/Locale/Data/hr.xml delete mode 100644 lib/Zend/Locale/Data/hr_BA.xml delete mode 100644 lib/Zend/Locale/Data/hr_HR.xml delete mode 100644 lib/Zend/Locale/Data/hu.xml delete mode 100644 lib/Zend/Locale/Data/hu_HU.xml delete mode 100644 lib/Zend/Locale/Data/hy.xml delete mode 100644 lib/Zend/Locale/Data/hy_AM.xml delete mode 100644 lib/Zend/Locale/Data/ia.xml delete mode 100644 lib/Zend/Locale/Data/ia_FR.xml delete mode 100644 lib/Zend/Locale/Data/id.xml delete mode 100644 lib/Zend/Locale/Data/id_ID.xml delete mode 100644 lib/Zend/Locale/Data/ig.xml delete mode 100644 lib/Zend/Locale/Data/ig_NG.xml delete mode 100644 lib/Zend/Locale/Data/ii.xml delete mode 100644 lib/Zend/Locale/Data/ii_CN.xml delete mode 100644 lib/Zend/Locale/Data/is.xml delete mode 100644 lib/Zend/Locale/Data/is_IS.xml delete mode 100644 lib/Zend/Locale/Data/it.xml delete mode 100644 lib/Zend/Locale/Data/it_CH.xml delete mode 100644 lib/Zend/Locale/Data/it_IT.xml delete mode 100644 lib/Zend/Locale/Data/it_SM.xml delete mode 100644 lib/Zend/Locale/Data/ja.xml delete mode 100644 lib/Zend/Locale/Data/ja_JP.xml delete mode 100644 lib/Zend/Locale/Data/jgo.xml delete mode 100644 lib/Zend/Locale/Data/jgo_CM.xml delete mode 100644 lib/Zend/Locale/Data/jmc.xml delete mode 100644 lib/Zend/Locale/Data/jmc_TZ.xml delete mode 100644 lib/Zend/Locale/Data/ka.xml delete mode 100644 lib/Zend/Locale/Data/ka_GE.xml delete mode 100644 lib/Zend/Locale/Data/kab.xml delete mode 100644 lib/Zend/Locale/Data/kab_DZ.xml delete mode 100644 lib/Zend/Locale/Data/kam.xml delete mode 100644 lib/Zend/Locale/Data/kam_KE.xml delete mode 100644 lib/Zend/Locale/Data/kde.xml delete mode 100644 lib/Zend/Locale/Data/kde_TZ.xml delete mode 100644 lib/Zend/Locale/Data/kea.xml delete mode 100644 lib/Zend/Locale/Data/kea_CV.xml delete mode 100644 lib/Zend/Locale/Data/khq.xml delete mode 100644 lib/Zend/Locale/Data/khq_ML.xml delete mode 100644 lib/Zend/Locale/Data/ki.xml delete mode 100644 lib/Zend/Locale/Data/ki_KE.xml delete mode 100644 lib/Zend/Locale/Data/kk.xml delete mode 100644 lib/Zend/Locale/Data/kk_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/kk_Cyrl_KZ.xml delete mode 100644 lib/Zend/Locale/Data/kkj.xml delete mode 100644 lib/Zend/Locale/Data/kkj_CM.xml delete mode 100644 lib/Zend/Locale/Data/kl.xml delete mode 100644 lib/Zend/Locale/Data/kl_GL.xml delete mode 100644 lib/Zend/Locale/Data/kln.xml delete mode 100644 lib/Zend/Locale/Data/kln_KE.xml delete mode 100644 lib/Zend/Locale/Data/km.xml delete mode 100644 lib/Zend/Locale/Data/km_KH.xml delete mode 100644 lib/Zend/Locale/Data/kn.xml delete mode 100644 lib/Zend/Locale/Data/kn_IN.xml delete mode 100644 lib/Zend/Locale/Data/ko.xml delete mode 100644 lib/Zend/Locale/Data/ko_KP.xml delete mode 100644 lib/Zend/Locale/Data/ko_KR.xml delete mode 100644 lib/Zend/Locale/Data/kok.xml delete mode 100644 lib/Zend/Locale/Data/kok_IN.xml delete mode 100644 lib/Zend/Locale/Data/ks.xml delete mode 100644 lib/Zend/Locale/Data/ks_Arab.xml delete mode 100644 lib/Zend/Locale/Data/ks_Arab_IN.xml delete mode 100644 lib/Zend/Locale/Data/ksb.xml delete mode 100644 lib/Zend/Locale/Data/ksb_TZ.xml delete mode 100644 lib/Zend/Locale/Data/ksf.xml delete mode 100644 lib/Zend/Locale/Data/ksf_CM.xml delete mode 100644 lib/Zend/Locale/Data/ksh.xml delete mode 100644 lib/Zend/Locale/Data/ksh_DE.xml delete mode 100644 lib/Zend/Locale/Data/kw.xml delete mode 100644 lib/Zend/Locale/Data/kw_GB.xml delete mode 100644 lib/Zend/Locale/Data/ky.xml delete mode 100644 lib/Zend/Locale/Data/ky_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/ky_Cyrl_KG.xml delete mode 100644 lib/Zend/Locale/Data/lag.xml delete mode 100644 lib/Zend/Locale/Data/lag_TZ.xml delete mode 100644 lib/Zend/Locale/Data/languageInfo.xml delete mode 100644 lib/Zend/Locale/Data/lg.xml delete mode 100644 lib/Zend/Locale/Data/lg_UG.xml delete mode 100644 lib/Zend/Locale/Data/likelySubtags.xml delete mode 100644 lib/Zend/Locale/Data/lkt.xml delete mode 100644 lib/Zend/Locale/Data/lkt_US.xml delete mode 100644 lib/Zend/Locale/Data/ln.xml delete mode 100644 lib/Zend/Locale/Data/ln_AO.xml delete mode 100644 lib/Zend/Locale/Data/ln_CD.xml delete mode 100644 lib/Zend/Locale/Data/ln_CF.xml delete mode 100644 lib/Zend/Locale/Data/ln_CG.xml delete mode 100644 lib/Zend/Locale/Data/lo.xml delete mode 100644 lib/Zend/Locale/Data/lo_LA.xml delete mode 100644 lib/Zend/Locale/Data/lt.xml delete mode 100644 lib/Zend/Locale/Data/lt_LT.xml delete mode 100644 lib/Zend/Locale/Data/lu.xml delete mode 100644 lib/Zend/Locale/Data/lu_CD.xml delete mode 100644 lib/Zend/Locale/Data/luo.xml delete mode 100644 lib/Zend/Locale/Data/luo_KE.xml delete mode 100644 lib/Zend/Locale/Data/luy.xml delete mode 100644 lib/Zend/Locale/Data/luy_KE.xml delete mode 100644 lib/Zend/Locale/Data/lv.xml delete mode 100644 lib/Zend/Locale/Data/lv_LV.xml delete mode 100644 lib/Zend/Locale/Data/mas.xml delete mode 100644 lib/Zend/Locale/Data/mas_KE.xml delete mode 100644 lib/Zend/Locale/Data/mas_TZ.xml delete mode 100644 lib/Zend/Locale/Data/mer.xml delete mode 100644 lib/Zend/Locale/Data/mer_KE.xml delete mode 100644 lib/Zend/Locale/Data/metaZones.xml delete mode 100644 lib/Zend/Locale/Data/mfe.xml delete mode 100644 lib/Zend/Locale/Data/mfe_MU.xml delete mode 100644 lib/Zend/Locale/Data/mg.xml delete mode 100644 lib/Zend/Locale/Data/mg_MG.xml delete mode 100644 lib/Zend/Locale/Data/mgh.xml delete mode 100644 lib/Zend/Locale/Data/mgh_MZ.xml delete mode 100644 lib/Zend/Locale/Data/mgo.xml delete mode 100644 lib/Zend/Locale/Data/mgo_CM.xml delete mode 100644 lib/Zend/Locale/Data/mk.xml delete mode 100644 lib/Zend/Locale/Data/mk_MK.xml delete mode 100644 lib/Zend/Locale/Data/ml.xml delete mode 100644 lib/Zend/Locale/Data/ml_IN.xml delete mode 100644 lib/Zend/Locale/Data/mn.xml delete mode 100644 lib/Zend/Locale/Data/mn_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/mn_Cyrl_MN.xml delete mode 100644 lib/Zend/Locale/Data/mr.xml delete mode 100644 lib/Zend/Locale/Data/mr_IN.xml delete mode 100644 lib/Zend/Locale/Data/ms.xml delete mode 100644 lib/Zend/Locale/Data/ms_Latn.xml delete mode 100644 lib/Zend/Locale/Data/ms_Latn_BN.xml delete mode 100644 lib/Zend/Locale/Data/ms_Latn_MY.xml delete mode 100644 lib/Zend/Locale/Data/ms_Latn_SG.xml delete mode 100644 lib/Zend/Locale/Data/mt.xml delete mode 100644 lib/Zend/Locale/Data/mt_MT.xml delete mode 100644 lib/Zend/Locale/Data/mua.xml delete mode 100644 lib/Zend/Locale/Data/mua_CM.xml delete mode 100644 lib/Zend/Locale/Data/my.xml delete mode 100644 lib/Zend/Locale/Data/my_MM.xml delete mode 100644 lib/Zend/Locale/Data/naq.xml delete mode 100644 lib/Zend/Locale/Data/naq_NA.xml delete mode 100644 lib/Zend/Locale/Data/nb.xml delete mode 100644 lib/Zend/Locale/Data/nb_NO.xml delete mode 100644 lib/Zend/Locale/Data/nb_SJ.xml delete mode 100644 lib/Zend/Locale/Data/nd.xml delete mode 100644 lib/Zend/Locale/Data/nd_ZW.xml delete mode 100644 lib/Zend/Locale/Data/ne.xml delete mode 100644 lib/Zend/Locale/Data/ne_IN.xml delete mode 100644 lib/Zend/Locale/Data/ne_NP.xml delete mode 100644 lib/Zend/Locale/Data/nl.xml delete mode 100644 lib/Zend/Locale/Data/nl_AW.xml delete mode 100644 lib/Zend/Locale/Data/nl_BE.xml delete mode 100644 lib/Zend/Locale/Data/nl_BQ.xml delete mode 100644 lib/Zend/Locale/Data/nl_CW.xml delete mode 100644 lib/Zend/Locale/Data/nl_NL.xml delete mode 100644 lib/Zend/Locale/Data/nl_SR.xml delete mode 100644 lib/Zend/Locale/Data/nl_SX.xml delete mode 100644 lib/Zend/Locale/Data/nmg.xml delete mode 100644 lib/Zend/Locale/Data/nmg_CM.xml delete mode 100644 lib/Zend/Locale/Data/nn.xml delete mode 100644 lib/Zend/Locale/Data/nn_NO.xml delete mode 100644 lib/Zend/Locale/Data/nnh.xml delete mode 100644 lib/Zend/Locale/Data/nnh_CM.xml delete mode 100644 lib/Zend/Locale/Data/nr.xml delete mode 100644 lib/Zend/Locale/Data/nr_ZA.xml delete mode 100644 lib/Zend/Locale/Data/nso.xml delete mode 100644 lib/Zend/Locale/Data/nso_ZA.xml delete mode 100644 lib/Zend/Locale/Data/numberingSystems.xml delete mode 100644 lib/Zend/Locale/Data/nus.xml delete mode 100644 lib/Zend/Locale/Data/nus_SD.xml delete mode 100644 lib/Zend/Locale/Data/nyn.xml delete mode 100644 lib/Zend/Locale/Data/nyn_UG.xml delete mode 100644 lib/Zend/Locale/Data/om.xml delete mode 100644 lib/Zend/Locale/Data/om_ET.xml delete mode 100644 lib/Zend/Locale/Data/om_KE.xml delete mode 100644 lib/Zend/Locale/Data/or.xml delete mode 100644 lib/Zend/Locale/Data/or_IN.xml delete mode 100644 lib/Zend/Locale/Data/ordinals.xml delete mode 100644 lib/Zend/Locale/Data/os.xml delete mode 100644 lib/Zend/Locale/Data/os_GE.xml delete mode 100644 lib/Zend/Locale/Data/os_RU.xml delete mode 100644 lib/Zend/Locale/Data/pa.xml delete mode 100644 lib/Zend/Locale/Data/pa_Arab.xml delete mode 100644 lib/Zend/Locale/Data/pa_Arab_PK.xml delete mode 100644 lib/Zend/Locale/Data/pa_Guru.xml delete mode 100644 lib/Zend/Locale/Data/pa_Guru_IN.xml delete mode 100644 lib/Zend/Locale/Data/pl.xml delete mode 100644 lib/Zend/Locale/Data/pl_PL.xml delete mode 100644 lib/Zend/Locale/Data/plurals.xml delete mode 100644 lib/Zend/Locale/Data/postalCodeData.xml delete mode 100644 lib/Zend/Locale/Data/ps.xml delete mode 100644 lib/Zend/Locale/Data/ps_AF.xml delete mode 100644 lib/Zend/Locale/Data/pt.xml delete mode 100644 lib/Zend/Locale/Data/pt_AO.xml delete mode 100644 lib/Zend/Locale/Data/pt_BR.xml delete mode 100644 lib/Zend/Locale/Data/pt_CV.xml delete mode 100644 lib/Zend/Locale/Data/pt_GW.xml delete mode 100644 lib/Zend/Locale/Data/pt_MO.xml delete mode 100644 lib/Zend/Locale/Data/pt_MZ.xml delete mode 100644 lib/Zend/Locale/Data/pt_PT.xml delete mode 100644 lib/Zend/Locale/Data/pt_ST.xml delete mode 100644 lib/Zend/Locale/Data/pt_TL.xml delete mode 100644 lib/Zend/Locale/Data/rm.xml delete mode 100644 lib/Zend/Locale/Data/rm_CH.xml delete mode 100644 lib/Zend/Locale/Data/rn.xml delete mode 100644 lib/Zend/Locale/Data/rn_BI.xml delete mode 100644 lib/Zend/Locale/Data/ro.xml delete mode 100644 lib/Zend/Locale/Data/ro_MD.xml delete mode 100644 lib/Zend/Locale/Data/ro_RO.xml delete mode 100644 lib/Zend/Locale/Data/rof.xml delete mode 100644 lib/Zend/Locale/Data/rof_TZ.xml delete mode 100644 lib/Zend/Locale/Data/root.xml delete mode 100644 lib/Zend/Locale/Data/ru.xml delete mode 100644 lib/Zend/Locale/Data/ru_BY.xml delete mode 100644 lib/Zend/Locale/Data/ru_KG.xml delete mode 100644 lib/Zend/Locale/Data/ru_KZ.xml delete mode 100644 lib/Zend/Locale/Data/ru_MD.xml delete mode 100644 lib/Zend/Locale/Data/ru_RU.xml delete mode 100644 lib/Zend/Locale/Data/ru_UA.xml delete mode 100644 lib/Zend/Locale/Data/rw.xml delete mode 100644 lib/Zend/Locale/Data/rw_RW.xml delete mode 100644 lib/Zend/Locale/Data/rwk.xml delete mode 100644 lib/Zend/Locale/Data/rwk_TZ.xml delete mode 100644 lib/Zend/Locale/Data/sah.xml delete mode 100644 lib/Zend/Locale/Data/sah_RU.xml delete mode 100644 lib/Zend/Locale/Data/saq.xml delete mode 100644 lib/Zend/Locale/Data/saq_KE.xml delete mode 100644 lib/Zend/Locale/Data/sbp.xml delete mode 100644 lib/Zend/Locale/Data/sbp_TZ.xml delete mode 100644 lib/Zend/Locale/Data/se.xml delete mode 100644 lib/Zend/Locale/Data/se_FI.xml delete mode 100644 lib/Zend/Locale/Data/se_NO.xml delete mode 100644 lib/Zend/Locale/Data/seh.xml delete mode 100644 lib/Zend/Locale/Data/seh_MZ.xml delete mode 100644 lib/Zend/Locale/Data/ses.xml delete mode 100644 lib/Zend/Locale/Data/ses_ML.xml delete mode 100644 lib/Zend/Locale/Data/sg.xml delete mode 100644 lib/Zend/Locale/Data/sg_CF.xml delete mode 100644 lib/Zend/Locale/Data/shi.xml delete mode 100644 lib/Zend/Locale/Data/shi_Latn.xml delete mode 100644 lib/Zend/Locale/Data/shi_Latn_MA.xml delete mode 100644 lib/Zend/Locale/Data/shi_Tfng.xml delete mode 100644 lib/Zend/Locale/Data/shi_Tfng_MA.xml delete mode 100644 lib/Zend/Locale/Data/si.xml delete mode 100644 lib/Zend/Locale/Data/si_LK.xml delete mode 100644 lib/Zend/Locale/Data/sk.xml delete mode 100644 lib/Zend/Locale/Data/sk_SK.xml delete mode 100644 lib/Zend/Locale/Data/sl.xml delete mode 100644 lib/Zend/Locale/Data/sl_SI.xml delete mode 100644 lib/Zend/Locale/Data/sn.xml delete mode 100644 lib/Zend/Locale/Data/sn_ZW.xml delete mode 100644 lib/Zend/Locale/Data/so.xml delete mode 100644 lib/Zend/Locale/Data/so_DJ.xml delete mode 100644 lib/Zend/Locale/Data/so_ET.xml delete mode 100644 lib/Zend/Locale/Data/so_KE.xml delete mode 100644 lib/Zend/Locale/Data/so_SO.xml delete mode 100644 lib/Zend/Locale/Data/sq.xml delete mode 100644 lib/Zend/Locale/Data/sq_AL.xml delete mode 100644 lib/Zend/Locale/Data/sq_MK.xml delete mode 100644 lib/Zend/Locale/Data/sq_XK.xml delete mode 100644 lib/Zend/Locale/Data/sr.xml delete mode 100644 lib/Zend/Locale/Data/sr_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/sr_Cyrl_BA.xml delete mode 100644 lib/Zend/Locale/Data/sr_Cyrl_ME.xml delete mode 100644 lib/Zend/Locale/Data/sr_Cyrl_RS.xml delete mode 100644 lib/Zend/Locale/Data/sr_Cyrl_XK.xml delete mode 100644 lib/Zend/Locale/Data/sr_Latn.xml delete mode 100644 lib/Zend/Locale/Data/sr_Latn_BA.xml delete mode 100644 lib/Zend/Locale/Data/sr_Latn_ME.xml delete mode 100644 lib/Zend/Locale/Data/sr_Latn_RS.xml delete mode 100644 lib/Zend/Locale/Data/sr_Latn_XK.xml delete mode 100644 lib/Zend/Locale/Data/ss.xml delete mode 100644 lib/Zend/Locale/Data/ss_SZ.xml delete mode 100644 lib/Zend/Locale/Data/ss_ZA.xml delete mode 100644 lib/Zend/Locale/Data/ssy.xml delete mode 100644 lib/Zend/Locale/Data/ssy_ER.xml delete mode 100644 lib/Zend/Locale/Data/st.xml delete mode 100644 lib/Zend/Locale/Data/st_LS.xml delete mode 100644 lib/Zend/Locale/Data/st_ZA.xml delete mode 100644 lib/Zend/Locale/Data/supplementalData.xml delete mode 100644 lib/Zend/Locale/Data/supplementalMetadata.xml delete mode 100644 lib/Zend/Locale/Data/sv.xml delete mode 100644 lib/Zend/Locale/Data/sv_AX.xml delete mode 100644 lib/Zend/Locale/Data/sv_FI.xml delete mode 100644 lib/Zend/Locale/Data/sv_SE.xml delete mode 100644 lib/Zend/Locale/Data/sw.xml delete mode 100644 lib/Zend/Locale/Data/sw_KE.xml delete mode 100644 lib/Zend/Locale/Data/sw_TZ.xml delete mode 100644 lib/Zend/Locale/Data/sw_UG.xml delete mode 100644 lib/Zend/Locale/Data/swc.xml delete mode 100644 lib/Zend/Locale/Data/swc_CD.xml delete mode 100644 lib/Zend/Locale/Data/ta.xml delete mode 100644 lib/Zend/Locale/Data/ta_IN.xml delete mode 100644 lib/Zend/Locale/Data/ta_LK.xml delete mode 100644 lib/Zend/Locale/Data/ta_MY.xml delete mode 100644 lib/Zend/Locale/Data/ta_SG.xml delete mode 100644 lib/Zend/Locale/Data/te.xml delete mode 100644 lib/Zend/Locale/Data/te_IN.xml delete mode 100644 lib/Zend/Locale/Data/telephoneCodeData.xml delete mode 100644 lib/Zend/Locale/Data/teo.xml delete mode 100644 lib/Zend/Locale/Data/teo_KE.xml delete mode 100644 lib/Zend/Locale/Data/teo_UG.xml delete mode 100644 lib/Zend/Locale/Data/tg.xml delete mode 100644 lib/Zend/Locale/Data/tg_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/tg_Cyrl_TJ.xml delete mode 100644 lib/Zend/Locale/Data/th.xml delete mode 100644 lib/Zend/Locale/Data/th_TH.xml delete mode 100644 lib/Zend/Locale/Data/ti.xml delete mode 100644 lib/Zend/Locale/Data/ti_ER.xml delete mode 100644 lib/Zend/Locale/Data/ti_ET.xml delete mode 100644 lib/Zend/Locale/Data/tig.xml delete mode 100644 lib/Zend/Locale/Data/tig_ER.xml delete mode 100644 lib/Zend/Locale/Data/tn.xml delete mode 100644 lib/Zend/Locale/Data/tn_BW.xml delete mode 100644 lib/Zend/Locale/Data/tn_ZA.xml delete mode 100644 lib/Zend/Locale/Data/to.xml delete mode 100644 lib/Zend/Locale/Data/to_TO.xml delete mode 100644 lib/Zend/Locale/Data/tr.xml delete mode 100644 lib/Zend/Locale/Data/tr_CY.xml delete mode 100644 lib/Zend/Locale/Data/tr_TR.xml delete mode 100644 lib/Zend/Locale/Data/ts.xml delete mode 100644 lib/Zend/Locale/Data/ts_ZA.xml delete mode 100644 lib/Zend/Locale/Data/twq.xml delete mode 100644 lib/Zend/Locale/Data/twq_NE.xml delete mode 100644 lib/Zend/Locale/Data/tzm.xml delete mode 100644 lib/Zend/Locale/Data/tzm_Latn.xml delete mode 100644 lib/Zend/Locale/Data/tzm_Latn_MA.xml delete mode 100644 lib/Zend/Locale/Data/ug.xml delete mode 100644 lib/Zend/Locale/Data/ug_Arab.xml delete mode 100644 lib/Zend/Locale/Data/ug_Arab_CN.xml delete mode 100644 lib/Zend/Locale/Data/uk.xml delete mode 100644 lib/Zend/Locale/Data/uk_UA.xml delete mode 100644 lib/Zend/Locale/Data/ur.xml delete mode 100644 lib/Zend/Locale/Data/ur_IN.xml delete mode 100644 lib/Zend/Locale/Data/ur_PK.xml delete mode 100644 lib/Zend/Locale/Data/uz.xml delete mode 100644 lib/Zend/Locale/Data/uz_Arab.xml delete mode 100644 lib/Zend/Locale/Data/uz_Arab_AF.xml delete mode 100644 lib/Zend/Locale/Data/uz_Cyrl.xml delete mode 100644 lib/Zend/Locale/Data/uz_Cyrl_UZ.xml delete mode 100644 lib/Zend/Locale/Data/uz_Latn.xml delete mode 100644 lib/Zend/Locale/Data/uz_Latn_UZ.xml delete mode 100644 lib/Zend/Locale/Data/vai.xml delete mode 100644 lib/Zend/Locale/Data/vai_Latn.xml delete mode 100644 lib/Zend/Locale/Data/vai_Latn_LR.xml delete mode 100644 lib/Zend/Locale/Data/vai_Vaii.xml delete mode 100644 lib/Zend/Locale/Data/vai_Vaii_LR.xml delete mode 100644 lib/Zend/Locale/Data/ve.xml delete mode 100644 lib/Zend/Locale/Data/ve_ZA.xml delete mode 100644 lib/Zend/Locale/Data/vi.xml delete mode 100644 lib/Zend/Locale/Data/vi_VN.xml delete mode 100644 lib/Zend/Locale/Data/vo.xml delete mode 100644 lib/Zend/Locale/Data/vo_001.xml delete mode 100644 lib/Zend/Locale/Data/vun.xml delete mode 100644 lib/Zend/Locale/Data/vun_TZ.xml delete mode 100644 lib/Zend/Locale/Data/wae.xml delete mode 100644 lib/Zend/Locale/Data/wae_CH.xml delete mode 100644 lib/Zend/Locale/Data/wal.xml delete mode 100644 lib/Zend/Locale/Data/wal_ET.xml delete mode 100644 lib/Zend/Locale/Data/windowsZones.xml delete mode 100644 lib/Zend/Locale/Data/xh.xml delete mode 100644 lib/Zend/Locale/Data/xh_ZA.xml delete mode 100644 lib/Zend/Locale/Data/xog.xml delete mode 100644 lib/Zend/Locale/Data/xog_UG.xml delete mode 100644 lib/Zend/Locale/Data/yav.xml delete mode 100644 lib/Zend/Locale/Data/yav_CM.xml delete mode 100644 lib/Zend/Locale/Data/yo.xml delete mode 100644 lib/Zend/Locale/Data/yo_BJ.xml delete mode 100644 lib/Zend/Locale/Data/yo_NG.xml delete mode 100644 lib/Zend/Locale/Data/zgh.xml delete mode 100644 lib/Zend/Locale/Data/zgh_MA.xml delete mode 100644 lib/Zend/Locale/Data/zh.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hans.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hans_CN.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hans_HK.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hans_MO.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hans_SG.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hant.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hant_HK.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hant_MO.xml delete mode 100644 lib/Zend/Locale/Data/zh_Hant_TW.xml delete mode 100644 lib/Zend/Locale/Data/zu.xml delete mode 100644 lib/Zend/Locale/Data/zu_ZA.xml delete mode 100644 lib/Zend/Locale/Exception.php delete mode 100644 lib/Zend/Locale/Format.php delete mode 100644 lib/Zend/Locale/Math.php delete mode 100644 lib/Zend/Locale/Math/Exception.php delete mode 100644 lib/Zend/Locale/Math/PhpMath.php delete mode 100644 lib/Zend/Log.php delete mode 100644 lib/Zend/Log/Exception.php delete mode 100644 lib/Zend/Log/FactoryInterface.php delete mode 100644 lib/Zend/Log/Filter/Abstract.php delete mode 100644 lib/Zend/Log/Filter/Interface.php delete mode 100644 lib/Zend/Log/Filter/Message.php delete mode 100644 lib/Zend/Log/Filter/Priority.php delete mode 100644 lib/Zend/Log/Filter/Suppress.php delete mode 100644 lib/Zend/Log/Formatter/Abstract.php delete mode 100644 lib/Zend/Log/Formatter/Firebug.php delete mode 100644 lib/Zend/Log/Formatter/Interface.php delete mode 100644 lib/Zend/Log/Formatter/Simple.php delete mode 100644 lib/Zend/Log/Formatter/Xml.php delete mode 100644 lib/Zend/Log/Writer/Abstract.php delete mode 100644 lib/Zend/Log/Writer/Db.php delete mode 100644 lib/Zend/Log/Writer/Firebug.php delete mode 100644 lib/Zend/Log/Writer/Mail.php delete mode 100644 lib/Zend/Log/Writer/Mock.php delete mode 100644 lib/Zend/Log/Writer/Null.php delete mode 100644 lib/Zend/Log/Writer/Stream.php delete mode 100644 lib/Zend/Log/Writer/Syslog.php delete mode 100644 lib/Zend/Log/Writer/ZendMonitor.php delete mode 100644 lib/Zend/Mail.php delete mode 100644 lib/Zend/Mail/Exception.php delete mode 100644 lib/Zend/Mail/Header/HeaderName.php delete mode 100644 lib/Zend/Mail/Header/HeaderValue.php delete mode 100644 lib/Zend/Mail/Message.php delete mode 100644 lib/Zend/Mail/Message/File.php delete mode 100644 lib/Zend/Mail/Message/Interface.php delete mode 100644 lib/Zend/Mail/Part.php delete mode 100644 lib/Zend/Mail/Part/File.php delete mode 100644 lib/Zend/Mail/Part/Interface.php delete mode 100644 lib/Zend/Mail/Protocol/Abstract.php delete mode 100644 lib/Zend/Mail/Protocol/Exception.php delete mode 100644 lib/Zend/Mail/Protocol/Imap.php delete mode 100644 lib/Zend/Mail/Protocol/Pop3.php delete mode 100644 lib/Zend/Mail/Protocol/Smtp.php delete mode 100644 lib/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php delete mode 100644 lib/Zend/Mail/Protocol/Smtp/Auth/Login.php delete mode 100644 lib/Zend/Mail/Protocol/Smtp/Auth/Plain.php delete mode 100644 lib/Zend/Mail/Storage.php delete mode 100644 lib/Zend/Mail/Storage/Abstract.php delete mode 100644 lib/Zend/Mail/Storage/Exception.php delete mode 100644 lib/Zend/Mail/Storage/Folder.php delete mode 100644 lib/Zend/Mail/Storage/Folder/Interface.php delete mode 100644 lib/Zend/Mail/Storage/Folder/Maildir.php delete mode 100644 lib/Zend/Mail/Storage/Folder/Mbox.php delete mode 100644 lib/Zend/Mail/Storage/Imap.php delete mode 100644 lib/Zend/Mail/Storage/Maildir.php delete mode 100644 lib/Zend/Mail/Storage/Mbox.php delete mode 100644 lib/Zend/Mail/Storage/Pop3.php delete mode 100644 lib/Zend/Mail/Storage/Writable/Interface.php delete mode 100644 lib/Zend/Mail/Storage/Writable/Maildir.php delete mode 100644 lib/Zend/Mail/Transport/Abstract.php delete mode 100644 lib/Zend/Mail/Transport/Exception.php delete mode 100644 lib/Zend/Mail/Transport/File.php delete mode 100644 lib/Zend/Mail/Transport/Sendmail.php delete mode 100644 lib/Zend/Mail/Transport/Smtp.php delete mode 100644 lib/Zend/Markup.php delete mode 100644 lib/Zend/Markup/Exception.php delete mode 100644 lib/Zend/Markup/Parser/Bbcode.php delete mode 100644 lib/Zend/Markup/Parser/Exception.php delete mode 100644 lib/Zend/Markup/Parser/ParserInterface.php delete mode 100644 lib/Zend/Markup/Renderer/Exception.php delete mode 100644 lib/Zend/Markup/Renderer/Html.php delete mode 100644 lib/Zend/Markup/Renderer/Html/Code.php delete mode 100644 lib/Zend/Markup/Renderer/Html/HtmlAbstract.php delete mode 100644 lib/Zend/Markup/Renderer/Html/Img.php delete mode 100644 lib/Zend/Markup/Renderer/Html/List.php delete mode 100644 lib/Zend/Markup/Renderer/Html/Url.php delete mode 100644 lib/Zend/Markup/Renderer/RendererAbstract.php delete mode 100644 lib/Zend/Markup/Renderer/TokenConverterInterface.php delete mode 100644 lib/Zend/Markup/Token.php delete mode 100644 lib/Zend/Markup/TokenList.php delete mode 100644 lib/Zend/Measure/Abstract.php delete mode 100644 lib/Zend/Measure/Acceleration.php delete mode 100644 lib/Zend/Measure/Angle.php delete mode 100644 lib/Zend/Measure/Area.php delete mode 100644 lib/Zend/Measure/Binary.php delete mode 100644 lib/Zend/Measure/Capacitance.php delete mode 100644 lib/Zend/Measure/Cooking/Volume.php delete mode 100644 lib/Zend/Measure/Cooking/Weight.php delete mode 100644 lib/Zend/Measure/Current.php delete mode 100644 lib/Zend/Measure/Density.php delete mode 100644 lib/Zend/Measure/Energy.php delete mode 100644 lib/Zend/Measure/Exception.php delete mode 100644 lib/Zend/Measure/Flow/Mass.php delete mode 100644 lib/Zend/Measure/Flow/Mole.php delete mode 100644 lib/Zend/Measure/Flow/Volume.php delete mode 100644 lib/Zend/Measure/Force.php delete mode 100644 lib/Zend/Measure/Frequency.php delete mode 100644 lib/Zend/Measure/Illumination.php delete mode 100644 lib/Zend/Measure/Length.php delete mode 100644 lib/Zend/Measure/Lightness.php delete mode 100644 lib/Zend/Measure/Number.php delete mode 100644 lib/Zend/Measure/Power.php delete mode 100644 lib/Zend/Measure/Pressure.php delete mode 100644 lib/Zend/Measure/Speed.php delete mode 100644 lib/Zend/Measure/Temperature.php delete mode 100644 lib/Zend/Measure/Time.php delete mode 100644 lib/Zend/Measure/Torque.php delete mode 100644 lib/Zend/Measure/Viscosity/Dynamic.php delete mode 100644 lib/Zend/Measure/Viscosity/Kinematic.php delete mode 100644 lib/Zend/Measure/Volume.php delete mode 100644 lib/Zend/Measure/Weight.php delete mode 100644 lib/Zend/Memory.php delete mode 100644 lib/Zend/Memory/AccessController.php delete mode 100644 lib/Zend/Memory/Container.php delete mode 100644 lib/Zend/Memory/Container/Interface.php delete mode 100644 lib/Zend/Memory/Container/Locked.php delete mode 100644 lib/Zend/Memory/Container/Movable.php delete mode 100644 lib/Zend/Memory/Exception.php delete mode 100644 lib/Zend/Memory/Manager.php delete mode 100644 lib/Zend/Memory/Value.php delete mode 100644 lib/Zend/Mime.php delete mode 100644 lib/Zend/Mime/Decode.php delete mode 100644 lib/Zend/Mime/Exception.php delete mode 100644 lib/Zend/Mime/Message.php delete mode 100644 lib/Zend/Mime/Part.php delete mode 100644 lib/Zend/Mobile/Exception.php delete mode 100644 lib/Zend/Mobile/Push/Abstract.php delete mode 100644 lib/Zend/Mobile/Push/Apns.php delete mode 100644 lib/Zend/Mobile/Push/Exception.php delete mode 100644 lib/Zend/Mobile/Push/Exception/DeviceQuotaExceeded.php delete mode 100644 lib/Zend/Mobile/Push/Exception/InvalidAuthToken.php delete mode 100644 lib/Zend/Mobile/Push/Exception/InvalidPayload.php delete mode 100644 lib/Zend/Mobile/Push/Exception/InvalidRegistration.php delete mode 100644 lib/Zend/Mobile/Push/Exception/InvalidToken.php delete mode 100644 lib/Zend/Mobile/Push/Exception/InvalidTopic.php delete mode 100644 lib/Zend/Mobile/Push/Exception/QuotaExceeded.php delete mode 100644 lib/Zend/Mobile/Push/Exception/ServerUnavailable.php delete mode 100644 lib/Zend/Mobile/Push/Gcm.php delete mode 100644 lib/Zend/Mobile/Push/Interface.php delete mode 100644 lib/Zend/Mobile/Push/Message/Abstract.php delete mode 100644 lib/Zend/Mobile/Push/Message/Apns.php delete mode 100644 lib/Zend/Mobile/Push/Message/Exception.php delete mode 100644 lib/Zend/Mobile/Push/Message/Gcm.php delete mode 100644 lib/Zend/Mobile/Push/Message/Interface.php delete mode 100644 lib/Zend/Mobile/Push/Message/Mpns.php delete mode 100644 lib/Zend/Mobile/Push/Message/Mpns/Raw.php delete mode 100644 lib/Zend/Mobile/Push/Message/Mpns/Tile.php delete mode 100644 lib/Zend/Mobile/Push/Message/Mpns/Toast.php delete mode 100644 lib/Zend/Mobile/Push/Mpns.php delete mode 100644 lib/Zend/Mobile/Push/Response/Gcm.php delete mode 100644 lib/Zend/Mobile/Push/Test/ApnsProxy.php delete mode 100644 lib/Zend/Navigation.php delete mode 100644 lib/Zend/Navigation/Container.php delete mode 100644 lib/Zend/Navigation/Exception.php delete mode 100644 lib/Zend/Navigation/Page.php delete mode 100644 lib/Zend/Navigation/Page/Mvc.php delete mode 100644 lib/Zend/Navigation/Page/Uri.php delete mode 100644 lib/Zend/Oauth.php delete mode 100644 lib/Zend/Oauth/Client.php delete mode 100644 lib/Zend/Oauth/Config.php delete mode 100644 lib/Zend/Oauth/Config/ConfigInterface.php delete mode 100644 lib/Zend/Oauth/Consumer.php delete mode 100644 lib/Zend/Oauth/Exception.php delete mode 100644 lib/Zend/Oauth/Http.php delete mode 100644 lib/Zend/Oauth/Http/AccessToken.php delete mode 100644 lib/Zend/Oauth/Http/RequestToken.php delete mode 100644 lib/Zend/Oauth/Http/UserAuthorization.php delete mode 100644 lib/Zend/Oauth/Http/Utility.php delete mode 100644 lib/Zend/Oauth/Signature/Hmac.php delete mode 100644 lib/Zend/Oauth/Signature/Plaintext.php delete mode 100644 lib/Zend/Oauth/Signature/Rsa.php delete mode 100644 lib/Zend/Oauth/Signature/SignatureAbstract.php delete mode 100644 lib/Zend/Oauth/Token.php delete mode 100644 lib/Zend/Oauth/Token/Access.php delete mode 100644 lib/Zend/Oauth/Token/AuthorizedRequest.php delete mode 100644 lib/Zend/Oauth/Token/Request.php delete mode 100644 lib/Zend/OpenId.php delete mode 100644 lib/Zend/OpenId/Consumer.php delete mode 100644 lib/Zend/OpenId/Consumer/Storage.php delete mode 100644 lib/Zend/OpenId/Consumer/Storage/File.php delete mode 100644 lib/Zend/OpenId/Exception.php delete mode 100644 lib/Zend/OpenId/Extension.php delete mode 100644 lib/Zend/OpenId/Extension/Sreg.php delete mode 100644 lib/Zend/OpenId/Provider.php delete mode 100644 lib/Zend/OpenId/Provider/Storage.php delete mode 100644 lib/Zend/OpenId/Provider/Storage/File.php delete mode 100644 lib/Zend/OpenId/Provider/User.php delete mode 100644 lib/Zend/OpenId/Provider/User/Session.php delete mode 100644 lib/Zend/Paginator.php delete mode 100644 lib/Zend/Paginator/Adapter/Array.php delete mode 100644 lib/Zend/Paginator/Adapter/DbSelect.php delete mode 100644 lib/Zend/Paginator/Adapter/DbTableSelect.php delete mode 100644 lib/Zend/Paginator/Adapter/Interface.php delete mode 100644 lib/Zend/Paginator/Adapter/Iterator.php delete mode 100644 lib/Zend/Paginator/Adapter/Null.php delete mode 100644 lib/Zend/Paginator/AdapterAggregate.php delete mode 100644 lib/Zend/Paginator/Exception.php delete mode 100644 lib/Zend/Paginator/ScrollingStyle/All.php delete mode 100644 lib/Zend/Paginator/ScrollingStyle/Elastic.php delete mode 100644 lib/Zend/Paginator/ScrollingStyle/Interface.php delete mode 100644 lib/Zend/Paginator/ScrollingStyle/Jumping.php delete mode 100644 lib/Zend/Paginator/ScrollingStyle/Sliding.php delete mode 100644 lib/Zend/Paginator/SerializableLimitIterator.php delete mode 100644 lib/Zend/Pdf.php delete mode 100644 lib/Zend/Pdf/Action.php delete mode 100644 lib/Zend/Pdf/Action/GoTo.php delete mode 100644 lib/Zend/Pdf/Action/GoTo3DView.php delete mode 100644 lib/Zend/Pdf/Action/GoToE.php delete mode 100644 lib/Zend/Pdf/Action/GoToR.php delete mode 100644 lib/Zend/Pdf/Action/Hide.php delete mode 100644 lib/Zend/Pdf/Action/ImportData.php delete mode 100644 lib/Zend/Pdf/Action/JavaScript.php delete mode 100644 lib/Zend/Pdf/Action/Launch.php delete mode 100644 lib/Zend/Pdf/Action/Movie.php delete mode 100644 lib/Zend/Pdf/Action/Named.php delete mode 100644 lib/Zend/Pdf/Action/Rendition.php delete mode 100644 lib/Zend/Pdf/Action/ResetForm.php delete mode 100644 lib/Zend/Pdf/Action/SetOCGState.php delete mode 100644 lib/Zend/Pdf/Action/Sound.php delete mode 100644 lib/Zend/Pdf/Action/SubmitForm.php delete mode 100644 lib/Zend/Pdf/Action/Thread.php delete mode 100644 lib/Zend/Pdf/Action/Trans.php delete mode 100644 lib/Zend/Pdf/Action/URI.php delete mode 100644 lib/Zend/Pdf/Action/Unknown.php delete mode 100644 lib/Zend/Pdf/Annotation.php delete mode 100644 lib/Zend/Pdf/Annotation/FileAttachment.php delete mode 100644 lib/Zend/Pdf/Annotation/Link.php delete mode 100644 lib/Zend/Pdf/Annotation/Markup.php delete mode 100644 lib/Zend/Pdf/Annotation/Text.php delete mode 100644 lib/Zend/Pdf/Canvas.php delete mode 100644 lib/Zend/Pdf/Canvas/Abstract.php delete mode 100644 lib/Zend/Pdf/Canvas/Interface.php delete mode 100644 lib/Zend/Pdf/Cmap.php delete mode 100644 lib/Zend/Pdf/Cmap/ByteEncoding.php delete mode 100644 lib/Zend/Pdf/Cmap/ByteEncoding/Static.php delete mode 100644 lib/Zend/Pdf/Cmap/SegmentToDelta.php delete mode 100644 lib/Zend/Pdf/Cmap/TrimmedTable.php delete mode 100644 lib/Zend/Pdf/Color.php delete mode 100644 lib/Zend/Pdf/Color/Cmyk.php delete mode 100644 lib/Zend/Pdf/Color/GrayScale.php delete mode 100644 lib/Zend/Pdf/Color/Html.php delete mode 100644 lib/Zend/Pdf/Color/Rgb.php delete mode 100644 lib/Zend/Pdf/Destination.php delete mode 100644 lib/Zend/Pdf/Destination/Explicit.php delete mode 100644 lib/Zend/Pdf/Destination/Fit.php delete mode 100644 lib/Zend/Pdf/Destination/FitBoundingBox.php delete mode 100644 lib/Zend/Pdf/Destination/FitBoundingBoxHorizontally.php delete mode 100644 lib/Zend/Pdf/Destination/FitBoundingBoxVertically.php delete mode 100644 lib/Zend/Pdf/Destination/FitHorizontally.php delete mode 100644 lib/Zend/Pdf/Destination/FitRectangle.php delete mode 100644 lib/Zend/Pdf/Destination/FitVertically.php delete mode 100644 lib/Zend/Pdf/Destination/Named.php delete mode 100644 lib/Zend/Pdf/Destination/Unknown.php delete mode 100644 lib/Zend/Pdf/Destination/Zoom.php delete mode 100644 lib/Zend/Pdf/Element.php delete mode 100644 lib/Zend/Pdf/Element/Array.php delete mode 100644 lib/Zend/Pdf/Element/Boolean.php delete mode 100644 lib/Zend/Pdf/Element/Dictionary.php delete mode 100644 lib/Zend/Pdf/Element/Name.php delete mode 100644 lib/Zend/Pdf/Element/Null.php delete mode 100644 lib/Zend/Pdf/Element/Numeric.php delete mode 100644 lib/Zend/Pdf/Element/Object.php delete mode 100644 lib/Zend/Pdf/Element/Object/Stream.php delete mode 100644 lib/Zend/Pdf/Element/Reference.php delete mode 100644 lib/Zend/Pdf/Element/Reference/Context.php delete mode 100644 lib/Zend/Pdf/Element/Reference/Table.php delete mode 100644 lib/Zend/Pdf/Element/Stream.php delete mode 100644 lib/Zend/Pdf/Element/String.php delete mode 100644 lib/Zend/Pdf/Element/String/Binary.php delete mode 100644 lib/Zend/Pdf/ElementFactory.php delete mode 100644 lib/Zend/Pdf/ElementFactory/Interface.php delete mode 100644 lib/Zend/Pdf/ElementFactory/Proxy.php delete mode 100644 lib/Zend/Pdf/Exception.php delete mode 100644 lib/Zend/Pdf/FileParser.php delete mode 100644 lib/Zend/Pdf/FileParser/Font.php delete mode 100644 lib/Zend/Pdf/FileParser/Font/OpenType.php delete mode 100644 lib/Zend/Pdf/FileParser/Font/OpenType/TrueType.php delete mode 100644 lib/Zend/Pdf/FileParser/Image.php delete mode 100644 lib/Zend/Pdf/FileParser/Image/Png.php delete mode 100644 lib/Zend/Pdf/FileParserDataSource.php delete mode 100644 lib/Zend/Pdf/FileParserDataSource/File.php delete mode 100644 lib/Zend/Pdf/FileParserDataSource/String.php delete mode 100644 lib/Zend/Pdf/Filter/Ascii85.php delete mode 100644 lib/Zend/Pdf/Filter/AsciiHex.php delete mode 100644 lib/Zend/Pdf/Filter/Compression.php delete mode 100644 lib/Zend/Pdf/Filter/Compression/Flate.php delete mode 100644 lib/Zend/Pdf/Filter/Compression/Lzw.php delete mode 100644 lib/Zend/Pdf/Filter/Interface.php delete mode 100644 lib/Zend/Pdf/Filter/RunLength.php delete mode 100644 lib/Zend/Pdf/Font.php delete mode 100644 lib/Zend/Pdf/Image.php delete mode 100644 lib/Zend/Pdf/NameTree.php delete mode 100644 lib/Zend/Pdf/Outline.php delete mode 100644 lib/Zend/Pdf/Outline/Created.php delete mode 100644 lib/Zend/Pdf/Outline/Loaded.php delete mode 100644 lib/Zend/Pdf/Page.php delete mode 100644 lib/Zend/Pdf/Parser.php delete mode 100644 lib/Zend/Pdf/RecursivelyIteratableObjectsContainer.php delete mode 100644 lib/Zend/Pdf/Resource.php delete mode 100644 lib/Zend/Pdf/Resource/ContentStream.php delete mode 100644 lib/Zend/Pdf/Resource/Extractor.php delete mode 100644 lib/Zend/Pdf/Resource/Font.php delete mode 100644 lib/Zend/Pdf/Resource/Font/CidFont.php delete mode 100644 lib/Zend/Pdf/Resource/Font/CidFont/TrueType.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Extracted.php delete mode 100644 lib/Zend/Pdf/Resource/Font/FontDescriptor.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Parsed.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Parsed/TrueType.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/Courier.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/CourierBold.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/CourierBoldOblique.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/CourierOblique.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/Helvetica.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBold.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBoldOblique.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/HelveticaOblique.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/Symbol.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/TimesBold.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/TimesBoldItalic.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/TimesItalic.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/TimesRoman.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Simple/Standard/ZapfDingbats.php delete mode 100644 lib/Zend/Pdf/Resource/Font/Type0.php delete mode 100644 lib/Zend/Pdf/Resource/GraphicsState.php delete mode 100644 lib/Zend/Pdf/Resource/Image.php delete mode 100644 lib/Zend/Pdf/Resource/Image/Jpeg.php delete mode 100644 lib/Zend/Pdf/Resource/Image/Png.php delete mode 100644 lib/Zend/Pdf/Resource/Image/Tiff.php delete mode 100644 lib/Zend/Pdf/Resource/ImageFactory.php delete mode 100644 lib/Zend/Pdf/Resource/Unified.php delete mode 100644 lib/Zend/Pdf/StringParser.php delete mode 100644 lib/Zend/Pdf/Style.php delete mode 100644 lib/Zend/Pdf/Target.php delete mode 100644 lib/Zend/Pdf/Trailer.php delete mode 100644 lib/Zend/Pdf/Trailer/Generator.php delete mode 100644 lib/Zend/Pdf/Trailer/Keeper.php delete mode 100644 lib/Zend/Pdf/UpdateInfoContainer.php delete mode 100644 lib/Zend/ProgressBar.php delete mode 100644 lib/Zend/ProgressBar/Adapter.php delete mode 100644 lib/Zend/ProgressBar/Adapter/Console.php delete mode 100644 lib/Zend/ProgressBar/Adapter/Exception.php delete mode 100644 lib/Zend/ProgressBar/Adapter/JsPull.php delete mode 100644 lib/Zend/ProgressBar/Adapter/JsPush.php delete mode 100644 lib/Zend/ProgressBar/Exception.php delete mode 100644 lib/Zend/Queue.php delete mode 100644 lib/Zend/Queue/Adapter/Activemq.php delete mode 100644 lib/Zend/Queue/Adapter/AdapterAbstract.php delete mode 100644 lib/Zend/Queue/Adapter/AdapterInterface.php delete mode 100644 lib/Zend/Queue/Adapter/Array.php delete mode 100644 lib/Zend/Queue/Adapter/Db.php delete mode 100644 lib/Zend/Queue/Adapter/Db/Message.php delete mode 100644 lib/Zend/Queue/Adapter/Db/Queue.php delete mode 100644 lib/Zend/Queue/Adapter/Db/mysql.sql delete mode 100644 lib/Zend/Queue/Adapter/Db/postgresql.sql delete mode 100644 lib/Zend/Queue/Adapter/Db/queue_sqlite.sql delete mode 100644 lib/Zend/Queue/Adapter/Db/sqlsrv.sql delete mode 100644 lib/Zend/Queue/Adapter/Memcacheq.php delete mode 100644 lib/Zend/Queue/Adapter/Null.php delete mode 100644 lib/Zend/Queue/Adapter/PlatformJobQueue.php delete mode 100644 lib/Zend/Queue/Exception.php delete mode 100644 lib/Zend/Queue/Message.php delete mode 100644 lib/Zend/Queue/Message/Iterator.php delete mode 100644 lib/Zend/Queue/Message/PlatformJob.php delete mode 100644 lib/Zend/Queue/Stomp/Client.php delete mode 100644 lib/Zend/Queue/Stomp/Client/Connection.php delete mode 100644 lib/Zend/Queue/Stomp/Client/ConnectionInterface.php delete mode 100644 lib/Zend/Queue/Stomp/Frame.php delete mode 100644 lib/Zend/Queue/Stomp/FrameInterface.php delete mode 100644 lib/Zend/Reflection/Class.php delete mode 100644 lib/Zend/Reflection/Docblock.php delete mode 100644 lib/Zend/Reflection/Docblock/Tag.php delete mode 100644 lib/Zend/Reflection/Docblock/Tag/Param.php delete mode 100644 lib/Zend/Reflection/Docblock/Tag/Return.php delete mode 100644 lib/Zend/Reflection/Exception.php delete mode 100644 lib/Zend/Reflection/Extension.php delete mode 100644 lib/Zend/Reflection/File.php delete mode 100644 lib/Zend/Reflection/Function.php delete mode 100644 lib/Zend/Reflection/Method.php delete mode 100644 lib/Zend/Reflection/Parameter.php delete mode 100644 lib/Zend/Reflection/Property.php delete mode 100644 lib/Zend/Registry.php delete mode 100644 lib/Zend/Rest/Client.php delete mode 100644 lib/Zend/Rest/Client/Exception.php delete mode 100644 lib/Zend/Rest/Client/Result.php delete mode 100644 lib/Zend/Rest/Client/Result/Exception.php delete mode 100644 lib/Zend/Rest/Controller.php delete mode 100644 lib/Zend/Rest/Exception.php delete mode 100644 lib/Zend/Rest/Route.php delete mode 100644 lib/Zend/Rest/Server.php delete mode 100644 lib/Zend/Rest/Server/Exception.php delete mode 100644 lib/Zend/Search/Exception.php delete mode 100644 lib/Zend/Search/Lucene.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text/CaseInsensitive.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum/CaseInsensitive.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8/CaseInsensitive.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num/CaseInsensitive.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/Token.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/TokenFilter.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCase.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/TokenFilter/ShortWords.php delete mode 100644 lib/Zend/Search/Lucene/Analysis/TokenFilter/StopWords.php delete mode 100644 lib/Zend/Search/Lucene/Document.php delete mode 100644 lib/Zend/Search/Lucene/Document/Docx.php delete mode 100644 lib/Zend/Search/Lucene/Document/Exception.php delete mode 100644 lib/Zend/Search/Lucene/Document/Html.php delete mode 100644 lib/Zend/Search/Lucene/Document/OpenXml.php delete mode 100644 lib/Zend/Search/Lucene/Document/Pptx.php delete mode 100644 lib/Zend/Search/Lucene/Document/Xlsx.php delete mode 100644 lib/Zend/Search/Lucene/Exception.php delete mode 100644 lib/Zend/Search/Lucene/FSM.php delete mode 100644 lib/Zend/Search/Lucene/FSMAction.php delete mode 100644 lib/Zend/Search/Lucene/Field.php delete mode 100644 lib/Zend/Search/Lucene/Index/DictionaryLoader.php delete mode 100644 lib/Zend/Search/Lucene/Index/DocsFilter.php delete mode 100644 lib/Zend/Search/Lucene/Index/FieldInfo.php delete mode 100644 lib/Zend/Search/Lucene/Index/SegmentInfo.php delete mode 100644 lib/Zend/Search/Lucene/Index/SegmentMerger.php delete mode 100644 lib/Zend/Search/Lucene/Index/SegmentWriter.php delete mode 100644 lib/Zend/Search/Lucene/Index/SegmentWriter/DocumentWriter.php delete mode 100644 lib/Zend/Search/Lucene/Index/SegmentWriter/StreamWriter.php delete mode 100644 lib/Zend/Search/Lucene/Index/Term.php delete mode 100644 lib/Zend/Search/Lucene/Index/TermInfo.php delete mode 100644 lib/Zend/Search/Lucene/Index/TermsPriorityQueue.php delete mode 100644 lib/Zend/Search/Lucene/Index/TermsStream/Interface.php delete mode 100644 lib/Zend/Search/Lucene/Index/Writer.php delete mode 100644 lib/Zend/Search/Lucene/Interface.php delete mode 100644 lib/Zend/Search/Lucene/Interface/MultiSearcher.php delete mode 100644 lib/Zend/Search/Lucene/LockManager.php delete mode 100644 lib/Zend/Search/Lucene/MultiSearcher.php delete mode 100644 lib/Zend/Search/Lucene/PriorityQueue.php delete mode 100644 lib/Zend/Search/Lucene/Proxy.php delete mode 100644 lib/Zend/Search/Lucene/Search/BooleanExpressionRecognizer.php delete mode 100644 lib/Zend/Search/Lucene/Search/Highlighter/Default.php delete mode 100644 lib/Zend/Search/Lucene/Search/Highlighter/Interface.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Boolean.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Empty.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Fuzzy.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Insignificant.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/MultiTerm.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Phrase.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Preprocessing.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Preprocessing/Fuzzy.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Preprocessing/Phrase.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Preprocessing/Term.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Range.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Term.php delete mode 100644 lib/Zend/Search/Lucene/Search/Query/Wildcard.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryEntry.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryEntry/Phrase.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryEntry/Subquery.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryEntry/Term.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryHit.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryLexer.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryParser.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryParserContext.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryParserException.php delete mode 100644 lib/Zend/Search/Lucene/Search/QueryToken.php delete mode 100644 lib/Zend/Search/Lucene/Search/Similarity.php delete mode 100644 lib/Zend/Search/Lucene/Search/Similarity/Default.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight/Boolean.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight/Empty.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight/MultiTerm.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight/Phrase.php delete mode 100644 lib/Zend/Search/Lucene/Search/Weight/Term.php delete mode 100644 lib/Zend/Search/Lucene/Storage/Directory.php delete mode 100644 lib/Zend/Search/Lucene/Storage/Directory/Filesystem.php delete mode 100644 lib/Zend/Search/Lucene/Storage/File.php delete mode 100644 lib/Zend/Search/Lucene/Storage/File/Filesystem.php delete mode 100644 lib/Zend/Search/Lucene/Storage/File/Memory.php delete mode 100644 lib/Zend/Search/Lucene/TermStreamsPriorityQueue.php delete mode 100644 lib/Zend/Serializer.php delete mode 100644 lib/Zend/Serializer/Adapter/AdapterAbstract.php delete mode 100644 lib/Zend/Serializer/Adapter/AdapterInterface.php delete mode 100644 lib/Zend/Serializer/Adapter/Amf0.php delete mode 100644 lib/Zend/Serializer/Adapter/Amf3.php delete mode 100644 lib/Zend/Serializer/Adapter/Igbinary.php delete mode 100644 lib/Zend/Serializer/Adapter/Json.php delete mode 100644 lib/Zend/Serializer/Adapter/PhpCode.php delete mode 100644 lib/Zend/Serializer/Adapter/PhpSerialize.php delete mode 100644 lib/Zend/Serializer/Adapter/PythonPickle.php delete mode 100644 lib/Zend/Serializer/Adapter/Wddx.php delete mode 100644 lib/Zend/Serializer/Exception.php delete mode 100644 lib/Zend/Server/Abstract.php delete mode 100644 lib/Zend/Server/Cache.php delete mode 100644 lib/Zend/Server/Definition.php delete mode 100644 lib/Zend/Server/Exception.php delete mode 100644 lib/Zend/Server/Interface.php delete mode 100644 lib/Zend/Server/Method/Callback.php delete mode 100644 lib/Zend/Server/Method/Definition.php delete mode 100644 lib/Zend/Server/Method/Parameter.php delete mode 100644 lib/Zend/Server/Method/Prototype.php delete mode 100644 lib/Zend/Server/Reflection.php delete mode 100644 lib/Zend/Server/Reflection/Class.php delete mode 100644 lib/Zend/Server/Reflection/Exception.php delete mode 100644 lib/Zend/Server/Reflection/Function.php delete mode 100644 lib/Zend/Server/Reflection/Function/Abstract.php delete mode 100644 lib/Zend/Server/Reflection/Method.php delete mode 100644 lib/Zend/Server/Reflection/Node.php delete mode 100644 lib/Zend/Server/Reflection/Parameter.php delete mode 100644 lib/Zend/Server/Reflection/Prototype.php delete mode 100644 lib/Zend/Server/Reflection/ReturnValue.php delete mode 100644 lib/Zend/Service/Abstract.php delete mode 100644 lib/Zend/Service/Akismet.php delete mode 100644 lib/Zend/Service/Amazon.php delete mode 100644 lib/Zend/Service/Amazon/Abstract.php delete mode 100644 lib/Zend/Service/Amazon/Accessories.php delete mode 100644 lib/Zend/Service/Amazon/Authentication.php delete mode 100644 lib/Zend/Service/Amazon/Authentication/Exception.php delete mode 100644 lib/Zend/Service/Amazon/Authentication/S3.php delete mode 100644 lib/Zend/Service/Amazon/Authentication/V1.php delete mode 100644 lib/Zend/Service/Amazon/Authentication/V2.php delete mode 100644 lib/Zend/Service/Amazon/CustomerReview.php delete mode 100644 lib/Zend/Service/Amazon/Ec2.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Abstract.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Availabilityzones.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/CloudWatch.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Ebs.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Elasticip.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Exception.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Image.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Instance.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Instance/Reserved.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Instance/Windows.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Keypair.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Region.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Response.php delete mode 100644 lib/Zend/Service/Amazon/Ec2/Securitygroups.php delete mode 100644 lib/Zend/Service/Amazon/EditorialReview.php delete mode 100644 lib/Zend/Service/Amazon/Exception.php delete mode 100644 lib/Zend/Service/Amazon/Image.php delete mode 100644 lib/Zend/Service/Amazon/Item.php delete mode 100644 lib/Zend/Service/Amazon/ListmaniaList.php delete mode 100644 lib/Zend/Service/Amazon/Offer.php delete mode 100644 lib/Zend/Service/Amazon/OfferSet.php delete mode 100644 lib/Zend/Service/Amazon/Query.php delete mode 100644 lib/Zend/Service/Amazon/ResultSet.php delete mode 100644 lib/Zend/Service/Amazon/S3.php delete mode 100644 lib/Zend/Service/Amazon/S3/Exception.php delete mode 100644 lib/Zend/Service/Amazon/S3/Stream.php delete mode 100644 lib/Zend/Service/Amazon/SimilarProduct.php delete mode 100644 lib/Zend/Service/Amazon/SimpleDb.php delete mode 100644 lib/Zend/Service/Amazon/SimpleDb/Attribute.php delete mode 100644 lib/Zend/Service/Amazon/SimpleDb/Exception.php delete mode 100644 lib/Zend/Service/Amazon/SimpleDb/Page.php delete mode 100644 lib/Zend/Service/Amazon/SimpleDb/Response.php delete mode 100644 lib/Zend/Service/Amazon/Sqs.php delete mode 100644 lib/Zend/Service/Amazon/Sqs/Exception.php delete mode 100644 lib/Zend/Service/Audioscrobbler.php delete mode 100644 lib/Zend/Service/Console/Command.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/Argv.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/ConfigFile.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/Env.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/ParameterSourceInterface.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/Prompt.php delete mode 100644 lib/Zend/Service/Console/Command/ParameterSource/StdIn.php delete mode 100644 lib/Zend/Service/Console/Exception.php delete mode 100644 lib/Zend/Service/Delicious.php delete mode 100644 lib/Zend/Service/Delicious/Exception.php delete mode 100644 lib/Zend/Service/Delicious/Post.php delete mode 100644 lib/Zend/Service/Delicious/PostList.php delete mode 100644 lib/Zend/Service/Delicious/SimplePost.php delete mode 100644 lib/Zend/Service/Ebay/Abstract.php delete mode 100644 lib/Zend/Service/Ebay/Exception.php delete mode 100644 lib/Zend/Service/Ebay/Finding.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Abstract.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Aspect.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Aspect/Histogram/Container.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Aspect/Histogram/Value.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Aspect/Histogram/Value/Set.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Aspect/Set.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Category.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Category/Histogram.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Category/Histogram/Container.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Category/Histogram/Set.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Error/Data.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Error/Data/Set.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Error/Message.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Exception.php delete mode 100644 lib/Zend/Service/Ebay/Finding/ListingInfo.php delete mode 100644 lib/Zend/Service/Ebay/Finding/PaginationOutput.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Response/Abstract.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Response/Histograms.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Response/Items.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Response/Keywords.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Search/Item.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Search/Item/Set.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Search/Result.php delete mode 100644 lib/Zend/Service/Ebay/Finding/SellerInfo.php delete mode 100644 lib/Zend/Service/Ebay/Finding/SellingStatus.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Set/Abstract.php delete mode 100644 lib/Zend/Service/Ebay/Finding/ShippingInfo.php delete mode 100644 lib/Zend/Service/Ebay/Finding/Storefront.php delete mode 100644 lib/Zend/Service/Exception.php delete mode 100644 lib/Zend/Service/Flickr.php delete mode 100644 lib/Zend/Service/Flickr/Image.php delete mode 100644 lib/Zend/Service/Flickr/Result.php delete mode 100644 lib/Zend/Service/Flickr/ResultSet.php delete mode 100644 lib/Zend/Service/LiveDocx.php delete mode 100644 lib/Zend/Service/LiveDocx/Exception.php delete mode 100644 lib/Zend/Service/LiveDocx/MailMerge.php delete mode 100644 lib/Zend/Service/Rackspace/Abstract.php delete mode 100644 lib/Zend/Service/Rackspace/Exception.php delete mode 100644 lib/Zend/Service/Rackspace/Files.php delete mode 100644 lib/Zend/Service/Rackspace/Files/Container.php delete mode 100644 lib/Zend/Service/Rackspace/Files/ContainerList.php delete mode 100644 lib/Zend/Service/Rackspace/Files/Exception.php delete mode 100644 lib/Zend/Service/Rackspace/Files/Object.php delete mode 100644 lib/Zend/Service/Rackspace/Files/ObjectList.php delete mode 100644 lib/Zend/Service/Rackspace/Servers.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/Exception.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/Image.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/ImageList.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/Server.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/ServerList.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/SharedIpGroup.php delete mode 100644 lib/Zend/Service/Rackspace/Servers/SharedIpGroupList.php delete mode 100644 lib/Zend/Service/ReCaptcha.php delete mode 100644 lib/Zend/Service/ReCaptcha/Exception.php delete mode 100644 lib/Zend/Service/ReCaptcha/MailHide.php delete mode 100644 lib/Zend/Service/ReCaptcha/MailHide/Exception.php delete mode 100644 lib/Zend/Service/ReCaptcha/Response.php delete mode 100644 lib/Zend/Service/ShortUrl/AbstractShortener.php delete mode 100644 lib/Zend/Service/ShortUrl/BitLy.php delete mode 100644 lib/Zend/Service/ShortUrl/Exception.php delete mode 100644 lib/Zend/Service/ShortUrl/IsGd.php delete mode 100644 lib/Zend/Service/ShortUrl/JdemCz.php delete mode 100644 lib/Zend/Service/ShortUrl/MetamarkNet.php delete mode 100644 lib/Zend/Service/ShortUrl/Shortener.php delete mode 100644 lib/Zend/Service/ShortUrl/TinyUrlCom.php delete mode 100644 lib/Zend/Service/SlideShare.php delete mode 100644 lib/Zend/Service/SlideShare/Exception.php delete mode 100644 lib/Zend/Service/SlideShare/SlideShow.php delete mode 100644 lib/Zend/Service/SqlAzure/Exception.php delete mode 100644 lib/Zend/Service/SqlAzure/Management/Client.php delete mode 100644 lib/Zend/Service/SqlAzure/Management/Exception.php delete mode 100644 lib/Zend/Service/SqlAzure/Management/FirewallRuleInstance.php delete mode 100644 lib/Zend/Service/SqlAzure/Management/ServerInstance.php delete mode 100644 lib/Zend/Service/SqlAzure/Management/ServiceEntityAbstract.php delete mode 100644 lib/Zend/Service/StrikeIron.php delete mode 100644 lib/Zend/Service/StrikeIron/Base.php delete mode 100644 lib/Zend/Service/StrikeIron/Decorator.php delete mode 100644 lib/Zend/Service/StrikeIron/Exception.php delete mode 100644 lib/Zend/Service/StrikeIron/SalesUseTaxBasic.php delete mode 100644 lib/Zend/Service/StrikeIron/USAddressVerification.php delete mode 100644 lib/Zend/Service/StrikeIron/ZipCodeInfo.php delete mode 100644 lib/Zend/Service/Twitter.php delete mode 100644 lib/Zend/Service/Twitter/Exception.php delete mode 100644 lib/Zend/Service/Twitter/Response.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Certificate.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Deployment.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/GetAsynchronousOperation.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Package.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/PackageScaffolder/PackageScaffolderAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder.phar delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/build.bat delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/index.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/Web.config delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.cmd delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.ps1 delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/install-php.cmd delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/diagnostics.wadcfg delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.Deployment.dll delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.PlatformInstaller.UI.dll delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.PlatformInstaller.dll delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/WebpiCmdLine.exe delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/license.rtf delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceConfiguration.cscfg delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceDefinition.csdef delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Service.php delete mode 100644 lib/Zend/Service/WindowsAzure/CommandLine/Storage.php delete mode 100644 lib/Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/Credentials/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php delete mode 100644 lib/Zend/Service/WindowsAzure/Credentials/SharedKey.php delete mode 100644 lib/Zend/Service/WindowsAzure/Credentials/SharedKeyLite.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDataSources.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDirectories.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationLogs.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/LogLevel.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/Manager.php delete mode 100644 lib/Zend/Service/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php delete mode 100644 lib/Zend/Service/WindowsAzure/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/Log/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/Log/Formatter/WindowsAzure.php delete mode 100644 lib/Zend/Service/WindowsAzure/Log/Writer/WindowsAzure.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/CertificateInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/Client.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/DeploymentInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/HostedServiceInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/LocationInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/OperationStatusInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/ServiceEntityAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/StorageServiceInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/RetryPolicy/Exception.php delete mode 100644 lib/Zend/Service/WindowsAzure/RetryPolicy/NoRetry.php delete mode 100644 lib/Zend/Service/WindowsAzure/RetryPolicy/RetryN.php delete mode 100644 lib/Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/SessionHandler.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/Batch.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/Blob.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/Blob/Stream.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/BlobContainer.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/BlobInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/DynamicTableEntity.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/LeaseInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/PageRegionInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/Queue.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/QueueInstance.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/QueueMessage.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/SignedIdentifier.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/StorageEntityAbstract.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/Table.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/TableEntity.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php delete mode 100644 lib/Zend/Service/WindowsAzure/Storage/TableInstance.php delete mode 100644 lib/Zend/Service/Yahoo.php delete mode 100644 lib/Zend/Service/Yahoo/Image.php delete mode 100644 lib/Zend/Service/Yahoo/ImageResult.php delete mode 100644 lib/Zend/Service/Yahoo/ImageResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/InlinkDataResult.php delete mode 100644 lib/Zend/Service/Yahoo/InlinkDataResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/LocalResult.php delete mode 100644 lib/Zend/Service/Yahoo/LocalResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/NewsResult.php delete mode 100644 lib/Zend/Service/Yahoo/NewsResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/PageDataResult.php delete mode 100644 lib/Zend/Service/Yahoo/PageDataResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/Result.php delete mode 100644 lib/Zend/Service/Yahoo/ResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/VideoResult.php delete mode 100644 lib/Zend/Service/Yahoo/VideoResultSet.php delete mode 100644 lib/Zend/Service/Yahoo/WebResult.php delete mode 100644 lib/Zend/Service/Yahoo/WebResultSet.php delete mode 100644 lib/Zend/Session.php delete mode 100644 lib/Zend/Session/Abstract.php delete mode 100644 lib/Zend/Session/Exception.php delete mode 100644 lib/Zend/Session/Namespace.php delete mode 100644 lib/Zend/Session/SaveHandler/DbTable.php delete mode 100644 lib/Zend/Session/SaveHandler/Exception.php delete mode 100644 lib/Zend/Session/SaveHandler/Interface.php delete mode 100644 lib/Zend/Session/Validator/Abstract.php delete mode 100644 lib/Zend/Session/Validator/Exception.php delete mode 100644 lib/Zend/Session/Validator/HttpUserAgent.php delete mode 100644 lib/Zend/Session/Validator/Interface.php delete mode 100644 lib/Zend/Soap/AutoDiscover.php delete mode 100644 lib/Zend/Soap/AutoDiscover/Exception.php delete mode 100644 lib/Zend/Soap/Client.php delete mode 100644 lib/Zend/Soap/Client/Common.php delete mode 100644 lib/Zend/Soap/Client/DotNet.php delete mode 100644 lib/Zend/Soap/Client/Exception.php delete mode 100644 lib/Zend/Soap/Client/Local.php delete mode 100644 lib/Zend/Soap/Server.php delete mode 100644 lib/Zend/Soap/Server/Exception.php delete mode 100644 lib/Zend/Soap/Server/Proxy.php delete mode 100644 lib/Zend/Soap/Wsdl.php delete mode 100644 lib/Zend/Soap/Wsdl/Exception.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/Abstract.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/AnyType.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeSequence.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/Composite.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/DefaultComplexType.php delete mode 100644 lib/Zend/Soap/Wsdl/Strategy/Interface.php delete mode 100644 lib/Zend/Stdlib/CallbackHandler.php delete mode 100644 lib/Zend/Stdlib/Exception.php delete mode 100644 lib/Zend/Stdlib/Exception/InvalidCallbackException.php delete mode 100644 lib/Zend/Stdlib/PriorityQueue.php delete mode 100644 lib/Zend/Stdlib/SplPriorityQueue.php delete mode 100644 lib/Zend/Tag/Cloud.php delete mode 100644 lib/Zend/Tag/Cloud/Decorator/Cloud.php delete mode 100644 lib/Zend/Tag/Cloud/Decorator/Exception.php delete mode 100644 lib/Zend/Tag/Cloud/Decorator/HtmlCloud.php delete mode 100644 lib/Zend/Tag/Cloud/Decorator/HtmlTag.php delete mode 100644 lib/Zend/Tag/Cloud/Decorator/Tag.php delete mode 100644 lib/Zend/Tag/Cloud/Exception.php delete mode 100644 lib/Zend/Tag/Exception.php delete mode 100644 lib/Zend/Tag/Item.php delete mode 100644 lib/Zend/Tag/ItemList.php delete mode 100644 lib/Zend/Tag/Taggable.php delete mode 100644 lib/Zend/Test/DbAdapter.php delete mode 100644 lib/Zend/Test/DbStatement.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/DomQuery.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/DomQuery34.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/DomQuery37.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/DomQuery41.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/Exception.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/Redirect.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/Redirect34.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/Redirect37.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/Redirect41.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/ResponseHeader.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/ResponseHeader34.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/ResponseHeader37.php delete mode 100644 lib/Zend/Test/PHPUnit/Constraint/ResponseHeader41.php delete mode 100644 lib/Zend/Test/PHPUnit/ControllerTestCase.php delete mode 100644 lib/Zend/Test/PHPUnit/DatabaseTestCase.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Connection.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/DataSet/DbRowset.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/DataSet/DbTable.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/DataSet/DbTableDataSet.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/DataSet/QueryDataSet.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/DataSet/QueryTable.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Exception.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Metadata/Generic.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Operation/DeleteAll.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Operation/Insert.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/Operation/Truncate.php delete mode 100644 lib/Zend/Test/PHPUnit/Db/SimpleTester.php delete mode 100644 lib/Zend/Text/Exception.php delete mode 100644 lib/Zend/Text/Figlet.php delete mode 100644 lib/Zend/Text/Figlet/Exception.php delete mode 100644 lib/Zend/Text/Figlet/zend-framework.flf delete mode 100644 lib/Zend/Text/MultiByte.php delete mode 100644 lib/Zend/Text/Table.php delete mode 100644 lib/Zend/Text/Table/Column.php delete mode 100644 lib/Zend/Text/Table/Decorator/Ascii.php delete mode 100644 lib/Zend/Text/Table/Decorator/Interface.php delete mode 100644 lib/Zend/Text/Table/Decorator/Unicode.php delete mode 100644 lib/Zend/Text/Table/Exception.php delete mode 100644 lib/Zend/Text/Table/Row.php delete mode 100644 lib/Zend/TimeSync.php delete mode 100644 lib/Zend/TimeSync/Exception.php delete mode 100644 lib/Zend/TimeSync/Ntp.php delete mode 100644 lib/Zend/TimeSync/Protocol.php delete mode 100644 lib/Zend/TimeSync/Sntp.php delete mode 100644 lib/Zend/Tool/Framework/Action/Base.php delete mode 100644 lib/Zend/Tool/Framework/Action/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Action/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Action/Repository.php delete mode 100644 lib/Zend/Tool/Framework/Client/Abstract.php delete mode 100644 lib/Zend/Tool/Framework/Client/Config.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/ArgumentParser.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/HelpSystem.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/Manifest.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/AlignCenter.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Blockize.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Colorizer.php delete mode 100644 lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Indention.php delete mode 100644 lib/Zend/Tool/Framework/Client/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Client/Interactive/InputHandler.php delete mode 100644 lib/Zend/Tool/Framework/Client/Interactive/InputInterface.php delete mode 100644 lib/Zend/Tool/Framework/Client/Interactive/InputRequest.php delete mode 100644 lib/Zend/Tool/Framework/Client/Interactive/InputResponse.php delete mode 100644 lib/Zend/Tool/Framework/Client/Interactive/OutputInterface.php delete mode 100644 lib/Zend/Tool/Framework/Client/Manifest.php delete mode 100644 lib/Zend/Tool/Framework/Client/Request.php delete mode 100644 lib/Zend/Tool/Framework/Client/Response.php delete mode 100644 lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Separator.php delete mode 100644 lib/Zend/Tool/Framework/Client/Storage.php delete mode 100644 lib/Zend/Tool/Framework/Client/Storage/AdapterInterface.php delete mode 100644 lib/Zend/Tool/Framework/Client/Storage/Directory.php delete mode 100644 lib/Zend/Tool/Framework/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Loader/Abstract.php delete mode 100644 lib/Zend/Tool/Framework/Loader/BasicLoader.php delete mode 100644 lib/Zend/Tool/Framework/Loader/IncludePathLoader.php delete mode 100644 lib/Zend/Tool/Framework/Loader/IncludePathLoader/RecursiveFilterIterator.php delete mode 100644 lib/Zend/Tool/Framework/Loader/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/ActionManifestable.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/ActionMetadata.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/Indexable.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/Metadata.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/MetadataManifestable.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/ProviderManifestable.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/ProviderMetadata.php delete mode 100644 lib/Zend/Tool/Framework/Manifest/Repository.php delete mode 100644 lib/Zend/Tool/Framework/Metadata/Attributable.php delete mode 100644 lib/Zend/Tool/Framework/Metadata/Basic.php delete mode 100644 lib/Zend/Tool/Framework/Metadata/Dynamic.php delete mode 100644 lib/Zend/Tool/Framework/Metadata/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Metadata/Tool.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Abstract.php delete mode 100644 lib/Zend/Tool/Framework/Provider/DocblockManifestable.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Initializable.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Interactable.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Interface.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Pretendable.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Repository.php delete mode 100644 lib/Zend/Tool/Framework/Provider/Signature.php delete mode 100644 lib/Zend/Tool/Framework/Registry.php delete mode 100644 lib/Zend/Tool/Framework/Registry/EnabledInterface.php delete mode 100644 lib/Zend/Tool/Framework/Registry/Exception.php delete mode 100644 lib/Zend/Tool/Framework/Registry/Interface.php delete mode 100644 lib/Zend/Tool/Framework/System/Action/Create.php delete mode 100644 lib/Zend/Tool/Framework/System/Action/Delete.php delete mode 100644 lib/Zend/Tool/Framework/System/Manifest.php delete mode 100644 lib/Zend/Tool/Framework/System/Provider/Config.php delete mode 100644 lib/Zend/Tool/Framework/System/Provider/Manifest.php delete mode 100644 lib/Zend/Tool/Framework/System/Provider/Phpinfo.php delete mode 100644 lib/Zend/Tool/Framework/System/Provider/Version.php delete mode 100644 lib/Zend/Tool/Project/Context/Content/Engine.php delete mode 100644 lib/Zend/Tool/Project/Context/Content/Engine/CodeGenerator.php delete mode 100644 lib/Zend/Tool/Project/Context/Content/Engine/Phtml.php delete mode 100644 lib/Zend/Tool/Project/Context/Exception.php delete mode 100644 lib/Zend/Tool/Project/Context/Filesystem/Abstract.php delete mode 100644 lib/Zend/Tool/Project/Context/Filesystem/Directory.php delete mode 100644 lib/Zend/Tool/Project/Context/Filesystem/File.php delete mode 100644 lib/Zend/Tool/Project/Context/Interface.php delete mode 100644 lib/Zend/Tool/Project/Context/Repository.php delete mode 100644 lib/Zend/Tool/Project/Context/System/Interface.php delete mode 100644 lib/Zend/Tool/Project/Context/System/NotOverwritable.php delete mode 100644 lib/Zend/Tool/Project/Context/System/ProjectDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/System/ProjectProfileFile.php delete mode 100644 lib/Zend/Tool/Project/Context/System/ProjectProvidersDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/System/TopLevelRestrictable.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/AbstractClassFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ActionMethod.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ApisDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ApplicationConfigFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ApplicationDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/BootstrapFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/CacheDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ConfigFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ConfigsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ControllerFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ControllersDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/DataDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/DbTableDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/DbTableFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/DocsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/FormFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/FormsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/HtaccessFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LayoutScriptFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LayoutScriptsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LayoutsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LibraryDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LocalesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/LogsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ModelFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ModelsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ModuleDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ModulesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ProjectProviderFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/PublicDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/PublicImagesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/PublicIndexFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/PublicScriptsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/PublicStylesheetsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/SearchIndexesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ServicesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/SessionsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TemporaryDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationActionMethod.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationBootstrapFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationModuleDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestApplicationModulesDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestLibraryBootstrapFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestLibraryDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestLibraryFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestLibraryNamespaceDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestPHPUnitBootstrapFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestPHPUnitConfigFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/TestsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/UploadsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewControllerScriptsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewFiltersDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewHelpersDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewScriptFile.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewScriptsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ViewsDirectory.php delete mode 100644 lib/Zend/Tool/Project/Context/Zf/ZfStandardLibraryDirectory.php delete mode 100644 lib/Zend/Tool/Project/Exception.php delete mode 100644 lib/Zend/Tool/Project/Profile.php delete mode 100644 lib/Zend/Tool/Project/Profile/Exception.php delete mode 100644 lib/Zend/Tool/Project/Profile/FileParser/Interface.php delete mode 100644 lib/Zend/Tool/Project/Profile/FileParser/Xml.php delete mode 100644 lib/Zend/Tool/Project/Profile/Iterator/ContextFilter.php delete mode 100644 lib/Zend/Tool/Project/Profile/Iterator/EnabledResourceFilter.php delete mode 100644 lib/Zend/Tool/Project/Profile/Resource.php delete mode 100644 lib/Zend/Tool/Project/Profile/Resource/Container.php delete mode 100644 lib/Zend/Tool/Project/Profile/Resource/SearchConstraints.php delete mode 100644 lib/Zend/Tool/Project/Provider/Abstract.php delete mode 100644 lib/Zend/Tool/Project/Provider/Action.php delete mode 100644 lib/Zend/Tool/Project/Provider/Application.php delete mode 100644 lib/Zend/Tool/Project/Provider/Controller.php delete mode 100644 lib/Zend/Tool/Project/Provider/DbAdapter.php delete mode 100644 lib/Zend/Tool/Project/Provider/DbTable.php delete mode 100644 lib/Zend/Tool/Project/Provider/Exception.php delete mode 100644 lib/Zend/Tool/Project/Provider/Form.php delete mode 100644 lib/Zend/Tool/Project/Provider/Layout.php delete mode 100644 lib/Zend/Tool/Project/Provider/Manifest.php delete mode 100644 lib/Zend/Tool/Project/Provider/Model.php delete mode 100644 lib/Zend/Tool/Project/Provider/Module.php delete mode 100644 lib/Zend/Tool/Project/Provider/Profile.php delete mode 100644 lib/Zend/Tool/Project/Provider/Project.php delete mode 100644 lib/Zend/Tool/Project/Provider/ProjectProvider.php delete mode 100644 lib/Zend/Tool/Project/Provider/Test.php delete mode 100644 lib/Zend/Tool/Project/Provider/View.php delete mode 100644 lib/Zend/Translate.php delete mode 100644 lib/Zend/Translate/Adapter.php delete mode 100644 lib/Zend/Translate/Adapter/Array.php delete mode 100644 lib/Zend/Translate/Adapter/Csv.php delete mode 100644 lib/Zend/Translate/Adapter/Gettext.php delete mode 100644 lib/Zend/Translate/Adapter/Ini.php delete mode 100644 lib/Zend/Translate/Adapter/Qt.php delete mode 100644 lib/Zend/Translate/Adapter/Tbx.php delete mode 100644 lib/Zend/Translate/Adapter/Tmx.php delete mode 100644 lib/Zend/Translate/Adapter/Xliff.php delete mode 100644 lib/Zend/Translate/Adapter/XmlTm.php delete mode 100644 lib/Zend/Translate/Exception.php delete mode 100644 lib/Zend/Translate/Plural.php delete mode 100644 lib/Zend/Uri.php delete mode 100644 lib/Zend/Uri/Exception.php delete mode 100644 lib/Zend/Uri/Http.php delete mode 100644 lib/Zend/Validate.php delete mode 100644 lib/Zend/Validate/Abstract.php delete mode 100644 lib/Zend/Validate/Alnum.php delete mode 100644 lib/Zend/Validate/Alpha.php delete mode 100644 lib/Zend/Validate/Barcode.php delete mode 100644 lib/Zend/Validate/Barcode/AdapterAbstract.php delete mode 100644 lib/Zend/Validate/Barcode/AdapterInterface.php delete mode 100644 lib/Zend/Validate/Barcode/Code25.php delete mode 100644 lib/Zend/Validate/Barcode/Code25interleaved.php delete mode 100644 lib/Zend/Validate/Barcode/Code39.php delete mode 100644 lib/Zend/Validate/Barcode/Code39ext.php delete mode 100644 lib/Zend/Validate/Barcode/Code93.php delete mode 100644 lib/Zend/Validate/Barcode/Code93ext.php delete mode 100644 lib/Zend/Validate/Barcode/Ean12.php delete mode 100644 lib/Zend/Validate/Barcode/Ean13.php delete mode 100644 lib/Zend/Validate/Barcode/Ean14.php delete mode 100644 lib/Zend/Validate/Barcode/Ean18.php delete mode 100644 lib/Zend/Validate/Barcode/Ean2.php delete mode 100644 lib/Zend/Validate/Barcode/Ean5.php delete mode 100644 lib/Zend/Validate/Barcode/Ean8.php delete mode 100644 lib/Zend/Validate/Barcode/Gtin12.php delete mode 100644 lib/Zend/Validate/Barcode/Gtin13.php delete mode 100644 lib/Zend/Validate/Barcode/Gtin14.php delete mode 100644 lib/Zend/Validate/Barcode/Identcode.php delete mode 100644 lib/Zend/Validate/Barcode/Intelligentmail.php delete mode 100644 lib/Zend/Validate/Barcode/Issn.php delete mode 100644 lib/Zend/Validate/Barcode/Itf14.php delete mode 100644 lib/Zend/Validate/Barcode/Leitcode.php delete mode 100644 lib/Zend/Validate/Barcode/Planet.php delete mode 100644 lib/Zend/Validate/Barcode/Postnet.php delete mode 100644 lib/Zend/Validate/Barcode/Royalmail.php delete mode 100644 lib/Zend/Validate/Barcode/Sscc.php delete mode 100644 lib/Zend/Validate/Barcode/Upca.php delete mode 100644 lib/Zend/Validate/Barcode/Upce.php delete mode 100644 lib/Zend/Validate/Between.php delete mode 100644 lib/Zend/Validate/Callback.php delete mode 100644 lib/Zend/Validate/Ccnum.php delete mode 100644 lib/Zend/Validate/CreditCard.php delete mode 100644 lib/Zend/Validate/Date.php delete mode 100644 lib/Zend/Validate/Db/Abstract.php delete mode 100644 lib/Zend/Validate/Db/NoRecordExists.php delete mode 100644 lib/Zend/Validate/Db/RecordExists.php delete mode 100644 lib/Zend/Validate/Digits.php delete mode 100644 lib/Zend/Validate/EmailAddress.php delete mode 100644 lib/Zend/Validate/Exception.php delete mode 100644 lib/Zend/Validate/File/Count.php delete mode 100644 lib/Zend/Validate/File/Crc32.php delete mode 100644 lib/Zend/Validate/File/ExcludeExtension.php delete mode 100644 lib/Zend/Validate/File/ExcludeMimeType.php delete mode 100644 lib/Zend/Validate/File/Exists.php delete mode 100644 lib/Zend/Validate/File/Extension.php delete mode 100644 lib/Zend/Validate/File/FilesSize.php delete mode 100644 lib/Zend/Validate/File/Hash.php delete mode 100644 lib/Zend/Validate/File/ImageSize.php delete mode 100644 lib/Zend/Validate/File/IsCompressed.php delete mode 100644 lib/Zend/Validate/File/IsImage.php delete mode 100644 lib/Zend/Validate/File/Md5.php delete mode 100644 lib/Zend/Validate/File/MimeType.php delete mode 100644 lib/Zend/Validate/File/NotExists.php delete mode 100644 lib/Zend/Validate/File/Sha1.php delete mode 100644 lib/Zend/Validate/File/Size.php delete mode 100644 lib/Zend/Validate/File/Upload.php delete mode 100644 lib/Zend/Validate/File/WordCount.php delete mode 100644 lib/Zend/Validate/Float.php delete mode 100644 lib/Zend/Validate/GreaterThan.php delete mode 100644 lib/Zend/Validate/Hex.php delete mode 100644 lib/Zend/Validate/Hostname.php delete mode 100644 lib/Zend/Validate/Hostname/Biz.php delete mode 100644 lib/Zend/Validate/Hostname/Cn.php delete mode 100644 lib/Zend/Validate/Hostname/Com.php delete mode 100644 lib/Zend/Validate/Hostname/Jp.php delete mode 100644 lib/Zend/Validate/Iban.php delete mode 100644 lib/Zend/Validate/Identical.php delete mode 100644 lib/Zend/Validate/InArray.php delete mode 100644 lib/Zend/Validate/Int.php delete mode 100644 lib/Zend/Validate/Interface.php delete mode 100644 lib/Zend/Validate/Ip.php delete mode 100644 lib/Zend/Validate/Isbn.php delete mode 100644 lib/Zend/Validate/Ldap/Dn.php delete mode 100644 lib/Zend/Validate/LessThan.php delete mode 100644 lib/Zend/Validate/NotEmpty.php delete mode 100644 lib/Zend/Validate/PostCode.php delete mode 100644 lib/Zend/Validate/Regex.php delete mode 100644 lib/Zend/Validate/Sitemap/Changefreq.php delete mode 100644 lib/Zend/Validate/Sitemap/Lastmod.php delete mode 100644 lib/Zend/Validate/Sitemap/Loc.php delete mode 100644 lib/Zend/Validate/Sitemap/Priority.php delete mode 100644 lib/Zend/Validate/StringLength.php delete mode 100644 lib/Zend/Version.php delete mode 100644 lib/Zend/View.php delete mode 100644 lib/Zend/View/Abstract.php delete mode 100644 lib/Zend/View/Exception.php delete mode 100644 lib/Zend/View/Helper/Abstract.php delete mode 100644 lib/Zend/View/Helper/Action.php delete mode 100644 lib/Zend/View/Helper/BaseUrl.php delete mode 100644 lib/Zend/View/Helper/Currency.php delete mode 100644 lib/Zend/View/Helper/Cycle.php delete mode 100644 lib/Zend/View/Helper/DeclareVars.php delete mode 100644 lib/Zend/View/Helper/Doctype.php delete mode 100644 lib/Zend/View/Helper/Fieldset.php delete mode 100644 lib/Zend/View/Helper/Form.php delete mode 100644 lib/Zend/View/Helper/FormButton.php delete mode 100644 lib/Zend/View/Helper/FormCheckbox.php delete mode 100644 lib/Zend/View/Helper/FormElement.php delete mode 100644 lib/Zend/View/Helper/FormErrors.php delete mode 100644 lib/Zend/View/Helper/FormFile.php delete mode 100644 lib/Zend/View/Helper/FormHidden.php delete mode 100644 lib/Zend/View/Helper/FormImage.php delete mode 100644 lib/Zend/View/Helper/FormLabel.php delete mode 100644 lib/Zend/View/Helper/FormMultiCheckbox.php delete mode 100644 lib/Zend/View/Helper/FormNote.php delete mode 100644 lib/Zend/View/Helper/FormPassword.php delete mode 100644 lib/Zend/View/Helper/FormRadio.php delete mode 100644 lib/Zend/View/Helper/FormReset.php delete mode 100644 lib/Zend/View/Helper/FormSelect.php delete mode 100644 lib/Zend/View/Helper/FormSubmit.php delete mode 100644 lib/Zend/View/Helper/FormText.php delete mode 100644 lib/Zend/View/Helper/FormTextarea.php delete mode 100644 lib/Zend/View/Helper/Gravatar.php delete mode 100644 lib/Zend/View/Helper/HeadLink.php delete mode 100644 lib/Zend/View/Helper/HeadMeta.php delete mode 100644 lib/Zend/View/Helper/HeadScript.php delete mode 100644 lib/Zend/View/Helper/HeadStyle.php delete mode 100644 lib/Zend/View/Helper/HeadTitle.php delete mode 100644 lib/Zend/View/Helper/HtmlElement.php delete mode 100644 lib/Zend/View/Helper/HtmlFlash.php delete mode 100644 lib/Zend/View/Helper/HtmlList.php delete mode 100644 lib/Zend/View/Helper/HtmlObject.php delete mode 100644 lib/Zend/View/Helper/HtmlPage.php delete mode 100644 lib/Zend/View/Helper/HtmlQuicktime.php delete mode 100644 lib/Zend/View/Helper/InlineScript.php delete mode 100644 lib/Zend/View/Helper/Interface.php delete mode 100644 lib/Zend/View/Helper/Json.php delete mode 100644 lib/Zend/View/Helper/Layout.php delete mode 100644 lib/Zend/View/Helper/Navigation.php delete mode 100644 lib/Zend/View/Helper/Navigation/Breadcrumbs.php delete mode 100644 lib/Zend/View/Helper/Navigation/Helper.php delete mode 100644 lib/Zend/View/Helper/Navigation/HelperAbstract.php delete mode 100644 lib/Zend/View/Helper/Navigation/Links.php delete mode 100644 lib/Zend/View/Helper/Navigation/Menu.php delete mode 100644 lib/Zend/View/Helper/Navigation/Sitemap.php delete mode 100644 lib/Zend/View/Helper/PaginationControl.php delete mode 100644 lib/Zend/View/Helper/Partial.php delete mode 100644 lib/Zend/View/Helper/Partial/Exception.php delete mode 100644 lib/Zend/View/Helper/PartialLoop.php delete mode 100644 lib/Zend/View/Helper/Placeholder.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Container.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Container/Abstract.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Container/Exception.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Container/Standalone.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Registry.php delete mode 100644 lib/Zend/View/Helper/Placeholder/Registry/Exception.php delete mode 100644 lib/Zend/View/Helper/RenderToPlaceholder.php delete mode 100644 lib/Zend/View/Helper/ServerUrl.php delete mode 100644 lib/Zend/View/Helper/Translate.php delete mode 100644 lib/Zend/View/Helper/Url.php delete mode 100644 lib/Zend/View/Helper/UserAgent.php delete mode 100644 lib/Zend/View/Interface.php delete mode 100644 lib/Zend/View/Stream.php delete mode 100644 lib/Zend/Wildfire/Channel/HttpHeaders.php delete mode 100644 lib/Zend/Wildfire/Channel/Interface.php delete mode 100644 lib/Zend/Wildfire/Exception.php delete mode 100644 lib/Zend/Wildfire/Plugin/FirePhp.php delete mode 100644 lib/Zend/Wildfire/Plugin/FirePhp/Message.php delete mode 100644 lib/Zend/Wildfire/Plugin/FirePhp/TableMessage.php delete mode 100644 lib/Zend/Wildfire/Plugin/Interface.php delete mode 100644 lib/Zend/Wildfire/Protocol/JsonStream.php delete mode 100644 lib/Zend/Xml/Exception.php delete mode 100644 lib/Zend/Xml/Security.php delete mode 100644 lib/Zend/XmlRpc/Client.php delete mode 100644 lib/Zend/XmlRpc/Client/Exception.php delete mode 100644 lib/Zend/XmlRpc/Client/FaultException.php delete mode 100644 lib/Zend/XmlRpc/Client/HttpException.php delete mode 100644 lib/Zend/XmlRpc/Client/IntrospectException.php delete mode 100644 lib/Zend/XmlRpc/Client/ServerIntrospection.php delete mode 100644 lib/Zend/XmlRpc/Client/ServerProxy.php delete mode 100644 lib/Zend/XmlRpc/Exception.php delete mode 100644 lib/Zend/XmlRpc/Fault.php delete mode 100644 lib/Zend/XmlRpc/Generator/DomDocument.php delete mode 100644 lib/Zend/XmlRpc/Generator/GeneratorAbstract.php delete mode 100644 lib/Zend/XmlRpc/Generator/XmlWriter.php delete mode 100644 lib/Zend/XmlRpc/Request.php delete mode 100644 lib/Zend/XmlRpc/Request/Http.php delete mode 100644 lib/Zend/XmlRpc/Request/Stdin.php delete mode 100644 lib/Zend/XmlRpc/Response.php delete mode 100644 lib/Zend/XmlRpc/Response/Http.php delete mode 100644 lib/Zend/XmlRpc/Server.php delete mode 100644 lib/Zend/XmlRpc/Server/Cache.php delete mode 100644 lib/Zend/XmlRpc/Server/Exception.php delete mode 100644 lib/Zend/XmlRpc/Server/Fault.php delete mode 100644 lib/Zend/XmlRpc/Server/System.php delete mode 100644 lib/Zend/XmlRpc/Value.php delete mode 100644 lib/Zend/XmlRpc/Value/Array.php delete mode 100644 lib/Zend/XmlRpc/Value/Base64.php delete mode 100644 lib/Zend/XmlRpc/Value/BigInteger.php delete mode 100644 lib/Zend/XmlRpc/Value/Boolean.php delete mode 100644 lib/Zend/XmlRpc/Value/Collection.php delete mode 100644 lib/Zend/XmlRpc/Value/DateTime.php delete mode 100644 lib/Zend/XmlRpc/Value/Double.php delete mode 100644 lib/Zend/XmlRpc/Value/Exception.php delete mode 100644 lib/Zend/XmlRpc/Value/Integer.php delete mode 100644 lib/Zend/XmlRpc/Value/Nil.php delete mode 100644 lib/Zend/XmlRpc/Value/Scalar.php delete mode 100644 lib/Zend/XmlRpc/Value/String.php delete mode 100644 lib/Zend/XmlRpc/Value/Struct.php delete mode 100644 lib/Zend/replace_recursive.php diff --git a/lib/Zend/Acl.php b/lib/Zend/Acl.php deleted file mode 100644 index d1c88021827..00000000000 --- a/lib/Zend/Acl.php +++ /dev/null @@ -1,1242 +0,0 @@ - array( - 'allRoles' => array( - 'allPrivileges' => array( - 'type' => self::TYPE_DENY, - 'assert' => null - ), - 'byPrivilegeId' => array() - ), - 'byRoleId' => array() - ), - 'byResourceId' => array() - ); - - /** - * Adds a Role having an identifier unique to the registry - * - * The $parents parameter may be a reference to, or the string identifier for, - * a Role existing in the registry, or $parents may be passed as an array of - * these - mixing string identifiers and objects is ok - to indicate the Roles - * from which the newly added Role will directly inherit. - * - * In order to resolve potential ambiguities with conflicting rules inherited - * from different parents, the most recently added parent takes precedence over - * parents that were previously added. In other words, the first parent added - * will have the least priority, and the last parent added will have the - * highest priority. - * - * @param Zend_Acl_Role_Interface|string $role - * @param Zend_Acl_Role_Interface|string|array $parents - * @uses Zend_Acl_Role_Registry::add() - * @return Zend_Acl Provides a fluent interface - */ - public function addRole($role, $parents = null) - { - if (is_string($role)) { - $role = new Zend_Acl_Role($role); - } - - if (!$role instanceof Zend_Acl_Role_Interface) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('addRole() expects $role to be of type Zend_Acl_Role_Interface'); - } - - - $this->_getRoleRegistry()->add($role, $parents); - - return $this; - } - - /** - * Returns the identified Role - * - * The $role parameter can either be a Role or Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @uses Zend_Acl_Role_Registry::get() - * @return Zend_Acl_Role_Interface - */ - public function getRole($role) - { - return $this->_getRoleRegistry()->get($role); - } - - /** - * Returns true if and only if the Role exists in the registry - * - * The $role parameter can either be a Role or a Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @uses Zend_Acl_Role_Registry::has() - * @return boolean - */ - public function hasRole($role) - { - return $this->_getRoleRegistry()->has($role); - } - - /** - * Returns true if and only if $role inherits from $inherit - * - * Both parameters may be either a Role or a Role identifier. If - * $onlyParents is true, then $role must inherit directly from - * $inherit in order to return true. By default, this method looks - * through the entire inheritance DAG to determine whether $role - * inherits from $inherit through its ancestor Roles. - * - * @param Zend_Acl_Role_Interface|string $role - * @param Zend_Acl_Role_Interface|string $inherit - * @param boolean $onlyParents - * @uses Zend_Acl_Role_Registry::inherits() - * @return boolean - */ - public function inheritsRole($role, $inherit, $onlyParents = false) - { - return $this->_getRoleRegistry()->inherits($role, $inherit, $onlyParents); - } - - /** - * Removes the Role from the registry - * - * The $role parameter can either be a Role or a Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @uses Zend_Acl_Role_Registry::remove() - * @return Zend_Acl Provides a fluent interface - */ - public function removeRole($role) - { - $this->_getRoleRegistry()->remove($role); - - if ($role instanceof Zend_Acl_Role_Interface) { - $roleId = $role->getRoleId(); - } else { - $roleId = $role; - } - - foreach ($this->_rules['allResources']['byRoleId'] as $roleIdCurrent => $rules) { - if ($roleId === $roleIdCurrent) { - unset($this->_rules['allResources']['byRoleId'][$roleIdCurrent]); - } - } - foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $visitor) { - if (array_key_exists('byRoleId', $visitor)) { - foreach ($visitor['byRoleId'] as $roleIdCurrent => $rules) { - if ($roleId === $roleIdCurrent) { - unset($this->_rules['byResourceId'][$resourceIdCurrent]['byRoleId'][$roleIdCurrent]); - } - } - } - } - - return $this; - } - - /** - * Removes all Roles from the registry - * - * @uses Zend_Acl_Role_Registry::removeAll() - * @return Zend_Acl Provides a fluent interface - */ - public function removeRoleAll() - { - $this->_getRoleRegistry()->removeAll(); - - foreach ($this->_rules['allResources']['byRoleId'] as $roleIdCurrent => $rules) { - unset($this->_rules['allResources']['byRoleId'][$roleIdCurrent]); - } - foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $visitor) { - foreach ($visitor['byRoleId'] as $roleIdCurrent => $rules) { - unset($this->_rules['byResourceId'][$resourceIdCurrent]['byRoleId'][$roleIdCurrent]); - } - } - - return $this; - } - - /** - * Adds a Resource having an identifier unique to the ACL - * - * The $parent parameter may be a reference to, or the string identifier for, - * the existing Resource from which the newly added Resource will inherit. - * - * @param Zend_Acl_Resource_Interface|string $resource - * @param Zend_Acl_Resource_Interface|string $parent - * @throws Zend_Acl_Exception - * @return Zend_Acl Provides a fluent interface - */ - public function addResource($resource, $parent = null) - { - if (is_string($resource)) { - $resource = new Zend_Acl_Resource($resource); - } - - if (!$resource instanceof Zend_Acl_Resource_Interface) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('addResource() expects $resource to be of type Zend_Acl_Resource_Interface'); - } - - $resourceId = $resource->getResourceId(); - - if ($this->has($resourceId)) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception("Resource id '$resourceId' already exists in the ACL"); - } - - $resourceParent = null; - - if (null !== $parent) { - try { - if ($parent instanceof Zend_Acl_Resource_Interface) { - $resourceParentId = $parent->getResourceId(); - } else { - $resourceParentId = $parent; - } - $resourceParent = $this->get($resourceParentId); - } catch (Zend_Acl_Exception $e) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception("Parent Resource id '$resourceParentId' does not exist", 0, $e); - } - $this->_resources[$resourceParentId]['children'][$resourceId] = $resource; - } - - $this->_resources[$resourceId] = array( - 'instance' => $resource, - 'parent' => $resourceParent, - 'children' => array() - ); - - return $this; - } - - /** - * Adds a Resource having an identifier unique to the ACL - * - * The $parent parameter may be a reference to, or the string identifier for, - * the existing Resource from which the newly added Resource will inherit. - * - * @deprecated in version 1.9.1 and will be available till 2.0. New code - * should use addResource() instead. - * - * @param Zend_Acl_Resource_Interface $resource - * @param Zend_Acl_Resource_Interface|string $parent - * @throws Zend_Acl_Exception - * @return Zend_Acl Provides a fluent interface - */ - public function add(Zend_Acl_Resource_Interface $resource, $parent = null) - { - return $this->addResource($resource, $parent); - } - - /** - * Returns the identified Resource - * - * The $resource parameter can either be a Resource or a Resource identifier. - * - * @param Zend_Acl_Resource_Interface|string $resource - * @throws Zend_Acl_Exception - * @return Zend_Acl_Resource_Interface - */ - public function get($resource) - { - if ($resource instanceof Zend_Acl_Resource_Interface) { - $resourceId = $resource->getResourceId(); - } else { - $resourceId = (string) $resource; - } - - if (!$this->has($resource)) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception("Resource '$resourceId' not found"); - } - - return $this->_resources[$resourceId]['instance']; - } - - /** - * Returns true if and only if the Resource exists in the ACL - * - * The $resource parameter can either be a Resource or a Resource identifier. - * - * @param Zend_Acl_Resource_Interface|string $resource - * @return boolean - */ - public function has($resource) - { - if ($resource instanceof Zend_Acl_Resource_Interface) { - $resourceId = $resource->getResourceId(); - } else { - $resourceId = (string) $resource; - } - - return isset($this->_resources[$resourceId]); - } - - /** - * Returns true if and only if $resource inherits from $inherit - * - * Both parameters may be either a Resource or a Resource identifier. If - * $onlyParent is true, then $resource must inherit directly from - * $inherit in order to return true. By default, this method looks - * through the entire inheritance tree to determine whether $resource - * inherits from $inherit through its ancestor Resources. - * - * @param Zend_Acl_Resource_Interface|string $resource - * @param Zend_Acl_Resource_Interface|string $inherit - * @param boolean $onlyParent - * @throws Zend_Acl_Resource_Registry_Exception - * @return boolean - */ - public function inherits($resource, $inherit, $onlyParent = false) - { - try { - $resourceId = $this->get($resource)->getResourceId(); - $inheritId = $this->get($inherit)->getResourceId(); - } catch (Zend_Acl_Exception $e) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception($e->getMessage(), $e->getCode(), $e); - } - - if (null !== $this->_resources[$resourceId]['parent']) { - $parentId = $this->_resources[$resourceId]['parent']->getResourceId(); - if ($inheritId === $parentId) { - return true; - } else if ($onlyParent) { - return false; - } - } else { - return false; - } - - while (null !== $this->_resources[$parentId]['parent']) { - $parentId = $this->_resources[$parentId]['parent']->getResourceId(); - if ($inheritId === $parentId) { - return true; - } - } - - return false; - } - - /** - * Removes a Resource and all of its children - * - * The $resource parameter can either be a Resource or a Resource identifier. - * - * @param Zend_Acl_Resource_Interface|string $resource - * @throws Zend_Acl_Exception - * @return Zend_Acl Provides a fluent interface - */ - public function remove($resource) - { - try { - $resourceId = $this->get($resource)->getResourceId(); - } catch (Zend_Acl_Exception $e) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception($e->getMessage(), $e->getCode(), $e); - } - - $resourcesRemoved = array($resourceId); - if (null !== ($resourceParent = $this->_resources[$resourceId]['parent'])) { - unset($this->_resources[$resourceParent->getResourceId()]['children'][$resourceId]); - } - foreach ($this->_resources[$resourceId]['children'] as $childId => $child) { - $this->remove($childId); - $resourcesRemoved[] = $childId; - } - - foreach ($resourcesRemoved as $resourceIdRemoved) { - foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $rules) { - if ($resourceIdRemoved === $resourceIdCurrent) { - unset($this->_rules['byResourceId'][$resourceIdCurrent]); - } - } - } - - unset($this->_resources[$resourceId]); - - return $this; - } - - /** - * Removes all Resources - * - * @return Zend_Acl Provides a fluent interface - */ - public function removeAll() - { - foreach ($this->_resources as $resourceId => $resource) { - foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $rules) { - if ($resourceId === $resourceIdCurrent) { - unset($this->_rules['byResourceId'][$resourceIdCurrent]); - } - } - } - - $this->_resources = array(); - - return $this; - } - - /** - * Adds an "allow" rule to the ACL - * - * @param Zend_Acl_Role_Interface|string|array $roles - * @param Zend_Acl_Resource_Interface|string|array $resources - * @param string|array $privileges - * @param Zend_Acl_Assert_Interface $assert - * @uses Zend_Acl::setRule() - * @return Zend_Acl Provides a fluent interface - */ - public function allow($roles = null, $resources = null, $privileges = null, Zend_Acl_Assert_Interface $assert = null) - { - return $this->setRule(self::OP_ADD, self::TYPE_ALLOW, $roles, $resources, $privileges, $assert); - } - - /** - * Adds a "deny" rule to the ACL - * - * @param Zend_Acl_Role_Interface|string|array $roles - * @param Zend_Acl_Resource_Interface|string|array $resources - * @param string|array $privileges - * @param Zend_Acl_Assert_Interface $assert - * @uses Zend_Acl::setRule() - * @return Zend_Acl Provides a fluent interface - */ - public function deny($roles = null, $resources = null, $privileges = null, Zend_Acl_Assert_Interface $assert = null) - { - return $this->setRule(self::OP_ADD, self::TYPE_DENY, $roles, $resources, $privileges, $assert); - } - - /** - * Removes "allow" permissions from the ACL - * - * @param Zend_Acl_Role_Interface|string|array $roles - * @param Zend_Acl_Resource_Interface|string|array $resources - * @param string|array $privileges - * @uses Zend_Acl::setRule() - * @return Zend_Acl Provides a fluent interface - */ - public function removeAllow($roles = null, $resources = null, $privileges = null) - { - return $this->setRule(self::OP_REMOVE, self::TYPE_ALLOW, $roles, $resources, $privileges); - } - - /** - * Removes "deny" restrictions from the ACL - * - * @param Zend_Acl_Role_Interface|string|array $roles - * @param Zend_Acl_Resource_Interface|string|array $resources - * @param string|array $privileges - * @uses Zend_Acl::setRule() - * @return Zend_Acl Provides a fluent interface - */ - public function removeDeny($roles = null, $resources = null, $privileges = null) - { - return $this->setRule(self::OP_REMOVE, self::TYPE_DENY, $roles, $resources, $privileges); - } - - /** - * Performs operations on ACL rules - * - * The $operation parameter may be either OP_ADD or OP_REMOVE, depending on whether the - * user wants to add or remove a rule, respectively: - * - * OP_ADD specifics: - * - * A rule is added that would allow one or more Roles access to [certain $privileges - * upon] the specified Resource(s). - * - * OP_REMOVE specifics: - * - * The rule is removed only in the context of the given Roles, Resources, and privileges. - * Existing rules to which the remove operation does not apply would remain in the - * ACL. - * - * The $type parameter may be either TYPE_ALLOW or TYPE_DENY, depending on whether the - * rule is intended to allow or deny permission, respectively. - * - * The $roles and $resources parameters may be references to, or the string identifiers for, - * existing Resources/Roles, or they may be passed as arrays of these - mixing string identifiers - * and objects is ok - to indicate the Resources and Roles to which the rule applies. If either - * $roles or $resources is null, then the rule applies to all Roles or all Resources, respectively. - * Both may be null in order to work with the default rule of the ACL. - * - * The $privileges parameter may be used to further specify that the rule applies only - * to certain privileges upon the Resource(s) in question. This may be specified to be a single - * privilege with a string, and multiple privileges may be specified as an array of strings. - * - * If $assert is provided, then its assert() method must return true in order for - * the rule to apply. If $assert is provided with $roles, $resources, and $privileges all - * equal to null, then a rule having a type of: - * - * TYPE_ALLOW will imply a type of TYPE_DENY, and - * - * TYPE_DENY will imply a type of TYPE_ALLOW - * - * when the rule's assertion fails. This is because the ACL needs to provide expected - * behavior when an assertion upon the default ACL rule fails. - * - * @param string $operation - * @param string $type - * @param Zend_Acl_Role_Interface|string|array $roles - * @param Zend_Acl_Resource_Interface|string|array $resources - * @param string|array $privileges - * @param Zend_Acl_Assert_Interface $assert - * @throws Zend_Acl_Exception - * @uses Zend_Acl_Role_Registry::get() - * @uses Zend_Acl::get() - * @return Zend_Acl Provides a fluent interface - */ - public function setRule($operation, $type, $roles = null, $resources = null, $privileges = null, - Zend_Acl_Assert_Interface $assert = null) - { - // ensure that the rule type is valid; normalize input to uppercase - $type = strtoupper($type); - if (self::TYPE_ALLOW !== $type && self::TYPE_DENY !== $type) { - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception("Unsupported rule type; must be either '" . self::TYPE_ALLOW . "' or '" - . self::TYPE_DENY . "'"); - } - - // ensure that all specified Roles exist; normalize input to array of Role objects or null - if (!is_array($roles)) { - $roles = array($roles); - } else if (0 === count($roles)) { - $roles = array(null); - } - $rolesTemp = $roles; - $roles = array(); - foreach ($rolesTemp as $role) { - if (null !== $role) { - $roles[] = $this->_getRoleRegistry()->get($role); - } else { - $roles[] = null; - } - } - unset($rolesTemp); - - // ensure that all specified Resources exist; normalize input to array of Resource objects or null - if ($resources !== null) { - if (!is_array($resources)) { - $resources = array($resources); - } else if (0 === count($resources)) { - $resources = array(null); - } - $resourcesTemp = $resources; - $resources = array(); - foreach ($resourcesTemp as $resource) { - if (null !== $resource) { - $resources[] = $this->get($resource); - } else { - $resources[] = null; - } - } - unset($resourcesTemp, $resource); - } else { - $allResources = array(); // this might be used later if resource iteration is required - foreach ($this->_resources as $rTarget) { - $allResources[] = $rTarget['instance']; - } - unset($rTarget); - } - - // normalize privileges to array - if (null === $privileges) { - $privileges = array(); - } else if (!is_array($privileges)) { - $privileges = array($privileges); - } - - switch ($operation) { - - // add to the rules - case self::OP_ADD: - if ($resources !== null) { - // this block will iterate the provided resources - foreach ($resources as $resource) { - foreach ($roles as $role) { - $rules =& $this->_getRules($resource, $role, true); - if (0 === count($privileges)) { - $rules['allPrivileges']['type'] = $type; - $rules['allPrivileges']['assert'] = $assert; - if (!isset($rules['byPrivilegeId'])) { - $rules['byPrivilegeId'] = array(); - } - } else { - foreach ($privileges as $privilege) { - $rules['byPrivilegeId'][$privilege]['type'] = $type; - $rules['byPrivilegeId'][$privilege]['assert'] = $assert; - } - } - } - } - } else { - // this block will apply to all resources in a global rule - foreach ($roles as $role) { - $rules =& $this->_getRules(null, $role, true); - if (0 === count($privileges)) { - $rules['allPrivileges']['type'] = $type; - $rules['allPrivileges']['assert'] = $assert; - } else { - foreach ($privileges as $privilege) { - $rules['byPrivilegeId'][$privilege]['type'] = $type; - $rules['byPrivilegeId'][$privilege]['assert'] = $assert; - } - } - } - } - break; - - // remove from the rules - case self::OP_REMOVE: - if ($resources !== null) { - // this block will iterate the provided resources - foreach ($resources as $resource) { - foreach ($roles as $role) { - $rules =& $this->_getRules($resource, $role); - if (null === $rules) { - continue; - } - if (0 === count($privileges)) { - if (null === $resource && null === $role) { - if ($type === $rules['allPrivileges']['type']) { - $rules = array( - 'allPrivileges' => array( - 'type' => self::TYPE_DENY, - 'assert' => null - ), - 'byPrivilegeId' => array() - ); - } - continue; - } - - if (isset($rules['allPrivileges']['type']) && - $type === $rules['allPrivileges']['type']) - { - unset($rules['allPrivileges']); - } - } else { - foreach ($privileges as $privilege) { - if (isset($rules['byPrivilegeId'][$privilege]) && - $type === $rules['byPrivilegeId'][$privilege]['type']) - { - unset($rules['byPrivilegeId'][$privilege]); - } - } - } - } - } - } else { - // this block will apply to all resources in a global rule - foreach ($roles as $role) { - /** - * since null (all resources) was passed to this setRule() call, we need - * clean up all the rules for the global allResources, as well as the indivually - * set resources (per privilege as well) - */ - foreach (array_merge(array(null), $allResources) as $resource) { - $rules =& $this->_getRules($resource, $role, true); - if (null === $rules) { - continue; - } - if (0 === count($privileges)) { - if (null === $role) { - if ($type === $rules['allPrivileges']['type']) { - $rules = array( - 'allPrivileges' => array( - 'type' => self::TYPE_DENY, - 'assert' => null - ), - 'byPrivilegeId' => array() - ); - } - continue; - } - - if (isset($rules['allPrivileges']['type']) && $type === $rules['allPrivileges']['type']) { - unset($rules['allPrivileges']); - } - } else { - foreach ($privileges as $privilege) { - if (isset($rules['byPrivilegeId'][$privilege]) && - $type === $rules['byPrivilegeId'][$privilege]['type']) - { - unset($rules['byPrivilegeId'][$privilege]); - } - } - } - } - } - } - break; - - default: - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception("Unsupported operation; must be either '" . self::OP_ADD . "' or '" - . self::OP_REMOVE . "'"); - } - - return $this; - } - - /** - * Returns true if and only if the Role has access to the Resource - * - * The $role and $resource parameters may be references to, or the string identifiers for, - * an existing Resource and Role combination. - * - * If either $role or $resource is null, then the query applies to all Roles or all Resources, - * respectively. Both may be null to query whether the ACL has a "blacklist" rule - * (allow everything to all). By default, Zend_Acl creates a "whitelist" rule (deny - * everything to all), and this method would return false unless this default has - * been overridden (i.e., by executing $acl->allow()). - * - * If a $privilege is not provided, then this method returns false if and only if the - * Role is denied access to at least one privilege upon the Resource. In other words, this - * method returns true if and only if the Role is allowed all privileges on the Resource. - * - * This method checks Role inheritance using a depth-first traversal of the Role registry. - * The highest priority parent (i.e., the parent most recently added) is checked first, - * and its respective parents are checked similarly before the lower-priority parents of - * the Role are checked. - * - * @param Zend_Acl_Role_Interface|string $role - * @param Zend_Acl_Resource_Interface|string $resource - * @param string $privilege - * @uses Zend_Acl::get() - * @uses Zend_Acl_Role_Registry::get() - * @return boolean - */ - public function isAllowed($role = null, $resource = null, $privilege = null) - { - // reset role & resource to null - $this->_isAllowedRole = null; - $this->_isAllowedResource = null; - $this->_isAllowedPrivilege = null; - - if (null !== $role) { - // keep track of originally called role - $this->_isAllowedRole = $role; - $role = $this->_getRoleRegistry()->get($role); - if (!$this->_isAllowedRole instanceof Zend_Acl_Role_Interface) { - $this->_isAllowedRole = $role; - } - } - - if (null !== $resource) { - // keep track of originally called resource - $this->_isAllowedResource = $resource; - $resource = $this->get($resource); - if (!$this->_isAllowedResource instanceof Zend_Acl_Resource_Interface) { - $this->_isAllowedResource = $resource; - } - } - - if (null === $privilege) { - // query on all privileges - do { - // depth-first search on $role if it is not 'allRoles' pseudo-parent - if (null !== $role && null !== ($result = $this->_roleDFSAllPrivileges($role, $resource, $privilege))) { - return $result; - } - - // look for rule on 'allRoles' psuedo-parent - if (null !== ($rules = $this->_getRules($resource, null))) { - foreach ($rules['byPrivilegeId'] as $privilege => $rule) { - if (self::TYPE_DENY === ($ruleTypeOnePrivilege = $this->_getRuleType($resource, null, $privilege))) { - return false; - } - } - if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, null, null))) { - return self::TYPE_ALLOW === $ruleTypeAllPrivileges; - } - } - - // try next Resource - $resource = $this->_resources[$resource->getResourceId()]['parent']; - - } while (true); // loop terminates at 'allResources' pseudo-parent - } else { - $this->_isAllowedPrivilege = $privilege; - // query on one privilege - do { - // depth-first search on $role if it is not 'allRoles' pseudo-parent - if (null !== $role && null !== ($result = $this->_roleDFSOnePrivilege($role, $resource, $privilege))) { - return $result; - } - - // look for rule on 'allRoles' pseudo-parent - if (null !== ($ruleType = $this->_getRuleType($resource, null, $privilege))) { - return self::TYPE_ALLOW === $ruleType; - } else if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, null, null))) { - return self::TYPE_ALLOW === $ruleTypeAllPrivileges; - } - - // try next Resource - $resource = $this->_resources[$resource->getResourceId()]['parent']; - - } while (true); // loop terminates at 'allResources' pseudo-parent - } - } - - /** - * Returns the Role registry for this ACL - * - * If no Role registry has been created yet, a new default Role registry - * is created and returned. - * - * @return Zend_Acl_Role_Registry - */ - protected function _getRoleRegistry() - { - if (null === $this->_roleRegistry) { - $this->_roleRegistry = new Zend_Acl_Role_Registry(); - } - return $this->_roleRegistry; - } - - /** - * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule - * allowing/denying $role access to all privileges upon $resource - * - * This method returns true if a rule is found and allows access. If a rule exists and denies access, - * then this method returns false. If no applicable rule is found, then this method returns null. - * - * @param Zend_Acl_Role_Interface $role - * @param Zend_Acl_Resource_Interface $resource - * @return boolean|null - */ - protected function _roleDFSAllPrivileges(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null) - { - $dfs = array( - 'visited' => array(), - 'stack' => array() - ); - - if (null !== ($result = $this->_roleDFSVisitAllPrivileges($role, $resource, $dfs))) { - return $result; - } - - while (null !== ($role = array_pop($dfs['stack']))) { - if (!isset($dfs['visited'][$role->getRoleId()])) { - if (null !== ($result = $this->_roleDFSVisitAllPrivileges($role, $resource, $dfs))) { - return $result; - } - } - } - - return null; - } - - /** - * Visits an $role in order to look for a rule allowing/denying $role access to all privileges upon $resource - * - * This method returns true if a rule is found and allows access. If a rule exists and denies access, - * then this method returns false. If no applicable rule is found, then this method returns null. - * - * This method is used by the internal depth-first search algorithm and may modify the DFS data structure. - * - * @param Zend_Acl_Role_Interface $role - * @param Zend_Acl_Resource_Interface $resource - * @param array $dfs - * @return boolean|null - * @throws Zend_Acl_Exception - */ - protected function _roleDFSVisitAllPrivileges(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, - &$dfs = null) - { - if (null === $dfs) { - /** - * @see Zend_Acl_Exception - */ - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('$dfs parameter may not be null'); - } - - if (null !== ($rules = $this->_getRules($resource, $role))) { - foreach ($rules['byPrivilegeId'] as $privilege => $rule) { - if (self::TYPE_DENY === ($ruleTypeOnePrivilege = $this->_getRuleType($resource, $role, $privilege))) { - return false; - } - } - if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, $role, null))) { - return self::TYPE_ALLOW === $ruleTypeAllPrivileges; - } - } - - $dfs['visited'][$role->getRoleId()] = true; - foreach ($this->_getRoleRegistry()->getParents($role) as $roleParentId => $roleParent) { - $dfs['stack'][] = $roleParent; - } - - return null; - } - - /** - * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule - * allowing/denying $role access to a $privilege upon $resource - * - * This method returns true if a rule is found and allows access. If a rule exists and denies access, - * then this method returns false. If no applicable rule is found, then this method returns null. - * - * @param Zend_Acl_Role_Interface $role - * @param Zend_Acl_Resource_Interface $resource - * @param string $privilege - * @return boolean|null - * @throws Zend_Acl_Exception - */ - protected function _roleDFSOnePrivilege(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, - $privilege = null) - { - if (null === $privilege) { - /** - * @see Zend_Acl_Exception - */ - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('$privilege parameter may not be null'); - } - - $dfs = array( - 'visited' => array(), - 'stack' => array() - ); - - if (null !== ($result = $this->_roleDFSVisitOnePrivilege($role, $resource, $privilege, $dfs))) { - return $result; - } - - while (null !== ($role = array_pop($dfs['stack']))) { - if (!isset($dfs['visited'][$role->getRoleId()])) { - if (null !== ($result = $this->_roleDFSVisitOnePrivilege($role, $resource, $privilege, $dfs))) { - return $result; - } - } - } - - return null; - } - - /** - * Visits an $role in order to look for a rule allowing/denying $role access to a $privilege upon $resource - * - * This method returns true if a rule is found and allows access. If a rule exists and denies access, - * then this method returns false. If no applicable rule is found, then this method returns null. - * - * This method is used by the internal depth-first search algorithm and may modify the DFS data structure. - * - * @param Zend_Acl_Role_Interface $role - * @param Zend_Acl_Resource_Interface $resource - * @param string $privilege - * @param array $dfs - * @return boolean|null - * @throws Zend_Acl_Exception - */ - protected function _roleDFSVisitOnePrivilege(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, - $privilege = null, &$dfs = null) - { - if (null === $privilege) { - /** - * @see Zend_Acl_Exception - */ - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('$privilege parameter may not be null'); - } - - if (null === $dfs) { - /** - * @see Zend_Acl_Exception - */ - #require_once 'Zend/Acl/Exception.php'; - throw new Zend_Acl_Exception('$dfs parameter may not be null'); - } - - if (null !== ($ruleTypeOnePrivilege = $this->_getRuleType($resource, $role, $privilege))) { - return self::TYPE_ALLOW === $ruleTypeOnePrivilege; - } else if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, $role, null))) { - return self::TYPE_ALLOW === $ruleTypeAllPrivileges; - } - - $dfs['visited'][$role->getRoleId()] = true; - foreach ($this->_getRoleRegistry()->getParents($role) as $roleParentId => $roleParent) { - $dfs['stack'][] = $roleParent; - } - - return null; - } - - /** - * Returns the rule type associated with the specified Resource, Role, and privilege - * combination. - * - * If a rule does not exist or its attached assertion fails, which means that - * the rule is not applicable, then this method returns null. Otherwise, the - * rule type applies and is returned as either TYPE_ALLOW or TYPE_DENY. - * - * If $resource or $role is null, then this means that the rule must apply to - * all Resources or Roles, respectively. - * - * If $privilege is null, then the rule must apply to all privileges. - * - * If all three parameters are null, then the default ACL rule type is returned, - * based on whether its assertion method passes. - * - * @param Zend_Acl_Resource_Interface $resource - * @param Zend_Acl_Role_Interface $role - * @param string $privilege - * @return string|null - */ - protected function _getRuleType(Zend_Acl_Resource_Interface $resource = null, Zend_Acl_Role_Interface $role = null, - $privilege = null) - { - // get the rules for the $resource and $role - if (null === ($rules = $this->_getRules($resource, $role))) { - return null; - } - - // follow $privilege - if (null === $privilege) { - if (isset($rules['allPrivileges'])) { - $rule = $rules['allPrivileges']; - } else { - return null; - } - } else if (!isset($rules['byPrivilegeId'][$privilege])) { - return null; - } else { - $rule = $rules['byPrivilegeId'][$privilege]; - } - - // check assertion first - if ($rule['assert']) { - $assertion = $rule['assert']; - $assertionValue = $assertion->assert( - $this, - ($this->_isAllowedRole instanceof Zend_Acl_Role_Interface) ? $this->_isAllowedRole : $role, - ($this->_isAllowedResource instanceof Zend_Acl_Resource_Interface) ? $this->_isAllowedResource : $resource, - $this->_isAllowedPrivilege - ); - } - - if (null === $rule['assert'] || $assertionValue) { - return $rule['type']; - } else if (null !== $resource || null !== $role || null !== $privilege) { - return null; - } else if (self::TYPE_ALLOW === $rule['type']) { - return self::TYPE_DENY; - } else { - return self::TYPE_ALLOW; - } - } - - /** - * Returns the rules associated with a Resource and a Role, or null if no such rules exist - * - * If either $resource or $role is null, this means that the rules returned are for all Resources or all Roles, - * respectively. Both can be null to return the default rule set for all Resources and all Roles. - * - * If the $create parameter is true, then a rule set is first created and then returned to the caller. - * - * @param Zend_Acl_Resource_Interface $resource - * @param Zend_Acl_Role_Interface $role - * @param boolean $create - * @return array|null - */ - protected function &_getRules(Zend_Acl_Resource_Interface $resource = null, Zend_Acl_Role_Interface $role = null, - $create = false) - { - // create a reference to null - $null = null; - $nullRef =& $null; - - // follow $resource - do { - if (null === $resource) { - $visitor =& $this->_rules['allResources']; - break; - } - $resourceId = $resource->getResourceId(); - if (!isset($this->_rules['byResourceId'][$resourceId])) { - if (!$create) { - return $nullRef; - } - $this->_rules['byResourceId'][$resourceId] = array(); - } - $visitor =& $this->_rules['byResourceId'][$resourceId]; - } while (false); - - - // follow $role - if (null === $role) { - if (!isset($visitor['allRoles'])) { - if (!$create) { - return $nullRef; - } - $visitor['allRoles']['byPrivilegeId'] = array(); - } - return $visitor['allRoles']; - } - $roleId = $role->getRoleId(); - if (!isset($visitor['byRoleId'][$roleId])) { - if (!$create) { - return $nullRef; - } - $visitor['byRoleId'][$roleId]['byPrivilegeId'] = array(); - $visitor['byRoleId'][$roleId]['allPrivileges'] = array('type' => null, 'assert' => null); - } - return $visitor['byRoleId'][$roleId]; - } - - - /** - * @return array of registered roles (Deprecated) - * @deprecated Deprecated since version 1.10 (December 2009) - */ - public function getRegisteredRoles() - { - trigger_error('The method getRegisteredRoles() was deprecated as of ' - . 'version 1.0, and may be removed. You\'re encouraged ' - . 'to use getRoles() instead.'); - - return $this->_getRoleRegistry()->getRoles(); - } - - /** - * Returns an array of registered roles. - * - * Note that this method does not return instances of registered roles, - * but only the role identifiers. - * - * @return array of registered roles - */ - public function getRoles() - { - return array_keys($this->_getRoleRegistry()->getRoles()); - } - - /** - * @return array of registered resources - */ - public function getResources() - { - return array_keys($this->_resources); - } - -} - diff --git a/lib/Zend/Acl/Assert/Interface.php b/lib/Zend/Acl/Assert/Interface.php deleted file mode 100644 index 34dc222bf1b..00000000000 --- a/lib/Zend/Acl/Assert/Interface.php +++ /dev/null @@ -1,64 +0,0 @@ -_resourceId = (string) $resourceId; - } - - /** - * Defined by Zend_Acl_Resource_Interface; returns the Resource identifier - * - * @return string - */ - public function getResourceId() - { - return $this->_resourceId; - } - - /** - * Defined by Zend_Acl_Resource_Interface; returns the Resource identifier - * Proxies to getResourceId() - * - * @return string - */ - public function __toString() - { - return $this->getResourceId(); - } -} diff --git a/lib/Zend/Acl/Resource/Interface.php b/lib/Zend/Acl/Resource/Interface.php deleted file mode 100644 index dcf10586d51..00000000000 --- a/lib/Zend/Acl/Resource/Interface.php +++ /dev/null @@ -1,37 +0,0 @@ -_roleId = (string) $roleId; - } - - /** - * Defined by Zend_Acl_Role_Interface; returns the Role identifier - * - * @return string - */ - public function getRoleId() - { - return $this->_roleId; - } - - /** - * Defined by Zend_Acl_Role_Interface; returns the Role identifier - * Proxies to getRoleId() - * - * @return string - */ - public function __toString() - { - return $this->getRoleId(); - } -} diff --git a/lib/Zend/Acl/Role/Interface.php b/lib/Zend/Acl/Role/Interface.php deleted file mode 100644 index e2510003ce5..00000000000 --- a/lib/Zend/Acl/Role/Interface.php +++ /dev/null @@ -1,37 +0,0 @@ -getRoleId(); - - if ($this->has($roleId)) { - /** - * @see Zend_Acl_Role_Registry_Exception - */ - #require_once 'Zend/Acl/Role/Registry/Exception.php'; - throw new Zend_Acl_Role_Registry_Exception("Role id '$roleId' already exists in the registry"); - } - - $roleParents = array(); - - if (null !== $parents) { - if (!is_array($parents)) { - $parents = array($parents); - } - /** - * @see Zend_Acl_Role_Registry_Exception - */ - #require_once 'Zend/Acl/Role/Registry/Exception.php'; - foreach ($parents as $parent) { - try { - if ($parent instanceof Zend_Acl_Role_Interface) { - $roleParentId = $parent->getRoleId(); - } else { - $roleParentId = $parent; - } - $roleParent = $this->get($roleParentId); - } catch (Zend_Acl_Role_Registry_Exception $e) { - throw new Zend_Acl_Role_Registry_Exception("Parent Role id '$roleParentId' does not exist", 0, $e); - } - $roleParents[$roleParentId] = $roleParent; - $this->_roles[$roleParentId]['children'][$roleId] = $role; - } - } - - $this->_roles[$roleId] = array( - 'instance' => $role, - 'parents' => $roleParents, - 'children' => array() - ); - - return $this; - } - - /** - * Returns the identified Role - * - * The $role parameter can either be a Role or a Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @throws Zend_Acl_Role_Registry_Exception - * @return Zend_Acl_Role_Interface - */ - public function get($role) - { - if ($role instanceof Zend_Acl_Role_Interface) { - $roleId = $role->getRoleId(); - } else { - $roleId = (string) $role; - } - - if (!$this->has($role)) { - /** - * @see Zend_Acl_Role_Registry_Exception - */ - #require_once 'Zend/Acl/Role/Registry/Exception.php'; - throw new Zend_Acl_Role_Registry_Exception("Role '$roleId' not found"); - } - - return $this->_roles[$roleId]['instance']; - } - - /** - * Returns true if and only if the Role exists in the registry - * - * The $role parameter can either be a Role or a Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @return boolean - */ - public function has($role) - { - if ($role instanceof Zend_Acl_Role_Interface) { - $roleId = $role->getRoleId(); - } else { - $roleId = (string) $role; - } - - return isset($this->_roles[$roleId]); - } - - /** - * Returns an array of an existing Role's parents - * - * The array keys are the identifiers of the parent Roles, and the values are - * the parent Role instances. The parent Roles are ordered in this array by - * ascending priority. The highest priority parent Role, last in the array, - * corresponds with the parent Role most recently added. - * - * If the Role does not have any parents, then an empty array is returned. - * - * @param Zend_Acl_Role_Interface|string $role - * @uses Zend_Acl_Role_Registry::get() - * @return array - */ - public function getParents($role) - { - $roleId = $this->get($role)->getRoleId(); - - return $this->_roles[$roleId]['parents']; - } - - /** - * Returns true if and only if $role inherits from $inherit - * - * Both parameters may be either a Role or a Role identifier. If - * $onlyParents is true, then $role must inherit directly from - * $inherit in order to return true. By default, this method looks - * through the entire inheritance DAG to determine whether $role - * inherits from $inherit through its ancestor Roles. - * - * @param Zend_Acl_Role_Interface|string $role - * @param Zend_Acl_Role_Interface|string $inherit - * @param boolean $onlyParents - * @throws Zend_Acl_Role_Registry_Exception - * @return boolean - */ - public function inherits($role, $inherit, $onlyParents = false) - { - /** - * @see Zend_Acl_Role_Registry_Exception - */ - #require_once 'Zend/Acl/Role/Registry/Exception.php'; - try { - $roleId = $this->get($role)->getRoleId(); - $inheritId = $this->get($inherit)->getRoleId(); - } catch (Zend_Acl_Role_Registry_Exception $e) { - throw new Zend_Acl_Role_Registry_Exception($e->getMessage(), $e->getCode(), $e); - } - - $inherits = isset($this->_roles[$roleId]['parents'][$inheritId]); - - if ($inherits || $onlyParents) { - return $inherits; - } - - foreach ($this->_roles[$roleId]['parents'] as $parentId => $parent) { - if ($this->inherits($parentId, $inheritId)) { - return true; - } - } - - return false; - } - - /** - * Removes the Role from the registry - * - * The $role parameter can either be a Role or a Role identifier. - * - * @param Zend_Acl_Role_Interface|string $role - * @throws Zend_Acl_Role_Registry_Exception - * @return Zend_Acl_Role_Registry Provides a fluent interface - */ - public function remove($role) - { - /** - * @see Zend_Acl_Role_Registry_Exception - */ - #require_once 'Zend/Acl/Role/Registry/Exception.php'; - try { - $roleId = $this->get($role)->getRoleId(); - } catch (Zend_Acl_Role_Registry_Exception $e) { - throw new Zend_Acl_Role_Registry_Exception($e->getMessage(), $e->getCode(), $e); - } - - foreach ($this->_roles[$roleId]['children'] as $childId => $child) { - unset($this->_roles[$childId]['parents'][$roleId]); - } - foreach ($this->_roles[$roleId]['parents'] as $parentId => $parent) { - unset($this->_roles[$parentId]['children'][$roleId]); - } - - unset($this->_roles[$roleId]); - - return $this; - } - - /** - * Removes all Roles from the registry - * - * @return Zend_Acl_Role_Registry Provides a fluent interface - */ - public function removeAll() - { - $this->_roles = array(); - - return $this; - } - - public function getRoles() - { - return $this->_roles; - } - -} diff --git a/lib/Zend/Acl/Role/Registry/Exception.php b/lib/Zend/Acl/Role/Registry/Exception.php deleted file mode 100644 index c4e135ee030..00000000000 --- a/lib/Zend/Acl/Role/Registry/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -_acl = new Zend_Acl(); - $xml = Zend_Xml_Security::scanFile($rolefile); -/* -Roles file format: - - - - - - - - -*/ - foreach($xml->role as $role) { - $this->_acl->addRole(new Zend_Acl_Role((string)$role["id"])); - foreach($role->user as $user) { - $this->_users[(string)$user["name"]] = array("password" => (string)$user["password"], - "role" => (string)$role["id"]); - } - } - } - - /** - * Get ACL with roles from XML file - * - * @return Zend_Acl - */ - public function getAcl() - { - return $this->_acl; - } - - /** - * Perform authentication - * - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result - * @see Zend_Auth_Adapter_Interface#authenticate() - */ - public function authenticate() - { - if (empty($this->_username) || - empty($this->_password)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Username/password should be set'); - } - - if(!isset($this->_users[$this->_username])) { - return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, - null, - array('Username not found') - ); - } - - $user = $this->_users[$this->_username]; - if($user["password"] != $this->_password) { - return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, - null, - array('Authentication failed') - ); - } - - $id = new stdClass(); - $id->role = $user["role"]; - $id->name = $this->_username; - return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $id); - } -} diff --git a/lib/Zend/Amf/Adobe/DbInspector.php b/lib/Zend/Amf/Adobe/DbInspector.php deleted file mode 100644 index a25c3a2b165..00000000000 --- a/lib/Zend/Amf/Adobe/DbInspector.php +++ /dev/null @@ -1,103 +0,0 @@ -describeTable('Pdo_Mysql', - * array( - * 'host' => '127.0.0.1', - * 'username' => 'webuser', - * 'password' => 'xxxxxxxx', - * 'dbname' => 'test' - * ), - * 'mytable' - * ); - * - * @param string $dbType Database adapter type for Zend_Db - * @param array|object $dbDescription Adapter-specific connection settings - * @param string $tableName Table name - * @return array Table description - * @see Zend_Db::describeTable() - * @see Zend_Db::factory() - */ - public function describeTable($dbType, $dbDescription, $tableName) - { - $db = $this->_connect($dbType, $dbDescription); - return $db->describeTable($tableName); - } - - /** - * Test database connection - * - * @param string $dbType Database adapter type for Zend_Db - * @param array|object $dbDescription Adapter-specific connection settings - * @return bool - * @see Zend_Db::factory() - */ - public function connect($dbType, $dbDescription) - { - $db = $this->_connect($dbType, $dbDescription); - $db->listTables(); - return true; - } - - /** - * Get the list of database tables - * - * @param string $dbType Database adapter type for Zend_Db - * @param array|object $dbDescription Adapter-specific connection settings - * @return array List of the tables - */ - public function getTables($dbType, $dbDescription) - { - $db = $this->_connect($dbType, $dbDescription); - return $db->listTables(); - } -} diff --git a/lib/Zend/Amf/Adobe/Introspector.php b/lib/Zend/Amf/Adobe/Introspector.php deleted file mode 100644 index c25828d5f80..00000000000 --- a/lib/Zend/Amf/Adobe/Introspector.php +++ /dev/null @@ -1,318 +0,0 @@ -_xml = new DOMDocument('1.0', 'utf-8'); - } - - /** - * Create XML definition on an AMF service class - * - * @param string $serviceClass Service class name - * @param array $options invocation options - * @return string XML with service class introspection - */ - public function introspect($serviceClass, $options = array()) - { - $this->_options = $options; - - if (strpbrk($serviceClass, '\\/<>')) { - return $this->_returnError('Invalid service name'); - } - - // Transform com.foo.Bar into com_foo_Bar - $serviceClass = str_replace('.' , '_', $serviceClass); - - // Introspect! - if (!class_exists($serviceClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($serviceClass, $this->_getServicePath()); - } - - $serv = $this->_xml->createElement('service-description'); - $serv->setAttribute('xmlns', 'http://ns.adobe.com/flex/service-description/2008'); - - $this->_types = $this->_xml->createElement('types'); - $this->_ops = $this->_xml->createElement('operations'); - - $r = Zend_Server_Reflection::reflectClass($serviceClass); - $this->_addService($r, $this->_ops); - - $serv->appendChild($this->_types); - $serv->appendChild($this->_ops); - $this->_xml->appendChild($serv); - - return $this->_xml->saveXML(); - } - - /** - * Authentication handler - * - * @param Zend_Acl $acl - * @return unknown_type - */ - public function initAcl(Zend_Acl $acl) - { - return false; // we do not need auth for this class - } - - /** - * Generate map of public class attributes - * - * @param string $typename type name - * @param DOMElement $typexml target XML element - * @return void - */ - protected function _addClassAttributes($typename, DOMElement $typexml) - { - // Do not try to autoload here because _phpTypeToAS should - // have already attempted to load this class - if (!class_exists($typename, false)) { - return; - } - - $rc = new Zend_Reflection_Class($typename); - foreach ($rc->getProperties() as $prop) { - if (!$prop->isPublic()) { - continue; - } - - $propxml = $this->_xml->createElement('property'); - $propxml->setAttribute('name', $prop->getName()); - - $type = $this->_registerType($this->_getPropertyType($prop)); - $propxml->setAttribute('type', $type); - - $typexml->appendChild($propxml); - } - } - - /** - * Build XML service description from reflection class - * - * @param Zend_Server_Reflection_Class $refclass - * @param DOMElement $target target XML element - * @return void - */ - protected function _addService(Zend_Server_Reflection_Class $refclass, DOMElement $target) - { - foreach ($refclass->getMethods() as $method) { - if (!$method->isPublic() - || $method->isConstructor() - || ('__' == substr($method->name, 0, 2)) - ) { - continue; - } - - foreach ($method->getPrototypes() as $proto) { - $op = $this->_xml->createElement('operation'); - $op->setAttribute('name', $method->getName()); - - $rettype = $this->_registerType($proto->getReturnType()); - $op->setAttribute('returnType', $rettype); - - foreach ($proto->getParameters() as $param) { - $arg = $this->_xml->createElement('argument'); - $arg->setAttribute('name', $param->getName()); - - $type = $param->getType(); - if ($type == 'mixed' && ($pclass = $param->getClass())) { - $type = $pclass->getName(); - } - - $ptype = $this->_registerType($type); - $arg->setAttribute('type', $ptype); - - if($param->isDefaultValueAvailable()) { - $arg->setAttribute('defaultvalue', $param->getDefaultValue()); - } - - $op->appendChild($arg); - } - - $target->appendChild($op); - } - } - } - - /** - * Extract type of the property from DocBlock - * - * @param Zend_Reflection_Property $prop reflection property object - * @return string Property type - */ - protected function _getPropertyType(Zend_Reflection_Property $prop) - { - $docBlock = $prop->getDocComment(); - - if (!$docBlock) { - return 'Unknown'; - } - - if (!$docBlock->hasTag('var')) { - return 'Unknown'; - } - - $tag = $docBlock->getTag('var'); - return trim($tag->getDescription()); - } - - /** - * Get the array of service directories - * - * @return array Service class directories - */ - protected function _getServicePath() - { - if (isset($this->_options['server'])) { - return $this->_options['server']->getDirectory(); - } - - if (isset($this->_options['directories'])) { - return $this->_options['directories']; - } - - return array(); - } - - /** - * Map from PHP type name to AS type name - * - * @param string $typename PHP type name - * @return string AS type name - */ - protected function _phpTypeToAS($typename) - { - if (class_exists($typename)) { - $vars = get_class_vars($typename); - - if (isset($vars['_explicitType'])) { - return $vars['_explicitType']; - } - } - - if (false !== ($asname = Zend_Amf_Parse_TypeLoader::getMappedClassName($typename))) { - return $asname; - } - - return $typename; - } - - /** - * Register new type on the system - * - * @param string $typename type name - * @return string New type name - */ - protected function _registerType($typename) - { - // Known type - return its AS name - if (isset($this->_typesMap[$typename])) { - return $this->_typesMap[$typename]; - } - - // Standard types - if (in_array($typename, array('void', 'null', 'mixed', 'unknown_type'))) { - return 'Unknown'; - } - - // Arrays - if ('array' == $typename) { - return 'Unknown[]'; - } - - if (in_array($typename, array('int', 'integer', 'bool', 'boolean', 'float', 'string', 'object', 'Unknown', 'stdClass'))) { - return $typename; - } - - // Resolve and store AS name - $asTypeName = $this->_phpTypeToAS($typename); - $this->_typesMap[$typename] = $asTypeName; - - // Create element for the name - $typeEl = $this->_xml->createElement('type'); - $typeEl->setAttribute('name', $asTypeName); - $this->_addClassAttributes($typename, $typeEl); - $this->_types->appendChild($typeEl); - - return $asTypeName; - } - - /** - * Return error with error message - * - * @param string $msg Error message - * @return string - */ - protected function _returnError($msg) - { - return 'ERROR: $msg'; - } -} diff --git a/lib/Zend/Amf/Auth/Abstract.php b/lib/Zend/Amf/Auth/Abstract.php deleted file mode 100644 index 643c927e5be..00000000000 --- a/lib/Zend/Amf/Auth/Abstract.php +++ /dev/null @@ -1,42 +0,0 @@ -_username = $username; - $this->_password = $password; - } -} diff --git a/lib/Zend/Amf/Constants.php b/lib/Zend/Amf/Constants.php deleted file mode 100644 index 723d8ba4fd3..00000000000 --- a/lib/Zend/Amf/Constants.php +++ /dev/null @@ -1,87 +0,0 @@ -_stream->readByte(); - } - - switch($typeMarker) { - // number - case Zend_Amf_Constants::AMF0_NUMBER: - return $this->_stream->readDouble(); - - // boolean - case Zend_Amf_Constants::AMF0_BOOLEAN: - return (boolean) $this->_stream->readByte(); - - // string - case Zend_Amf_Constants::AMF0_STRING: - return $this->_stream->readUTF(); - - // object - case Zend_Amf_Constants::AMF0_OBJECT: - return $this->readObject(); - - // null - case Zend_Amf_Constants::AMF0_NULL: - return null; - - // undefined - case Zend_Amf_Constants::AMF0_UNDEFINED: - return null; - - // Circular references are returned here - case Zend_Amf_Constants::AMF0_REFERENCE: - return $this->readReference(); - - // mixed array with numeric and string keys - case Zend_Amf_Constants::AMF0_MIXEDARRAY: - return $this->readMixedArray(); - - // array - case Zend_Amf_Constants::AMF0_ARRAY: - return $this->readArray(); - - // date - case Zend_Amf_Constants::AMF0_DATE: - return $this->readDate(); - - // longString strlen(string) > 2^16 - case Zend_Amf_Constants::AMF0_LONGSTRING: - return $this->_stream->readLongUTF(); - - //internal AS object, not supported - case Zend_Amf_Constants::AMF0_UNSUPPORTED: - return null; - - // XML - case Zend_Amf_Constants::AMF0_XML: - return $this->readXmlString(); - - // typed object ie Custom Class - case Zend_Amf_Constants::AMF0_TYPEDOBJECT: - return $this->readTypedObject(); - - //AMF3-specific - case Zend_Amf_Constants::AMF0_AMF3: - return $this->readAmf3TypeMarker(); - - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unsupported marker type: ' . $typeMarker); - } - } - - /** - * Read AMF objects and convert to PHP objects - * - * Read the name value pair objects form the php message and convert them to - * a php object class. - * - * Called when the marker type is 3. - * - * @param array|null $object - * @return object - */ - public function readObject($object = null) - { - if ($object === null) { - $object = array(); - } - - while (true) { - $key = $this->_stream->readUTF(); - $typeMarker = $this->_stream->readByte(); - if ($typeMarker != Zend_Amf_Constants::AMF0_OBJECTTERM ){ - //Recursivly call readTypeMarker to get the types of properties in the object - $object[$key] = $this->readTypeMarker($typeMarker); - } else { - //encountered AMF object terminator - break; - } - } - $this->_reference[] = $object; - return (object) $object; - } - - /** - * Read reference objects - * - * Used to gain access to the private array of reference objects. - * Called when marker type is 7. - * - * @return object - * @throws Zend_Amf_Exception for invalid reference keys - */ - public function readReference() - { - $key = $this->_stream->readInt(); - if (!array_key_exists($key, $this->_reference)) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Invalid reference key: '. $key); - } - return $this->_reference[$key]; - } - - /** - * Reads an array with numeric and string indexes. - * - * Called when marker type is 8 - * - * @todo As of Flash Player 9 there is not support for mixed typed arrays - * so we handle this as an object. With the introduction of vectors - * in Flash Player 10 this may need to be reconsidered. - * @return array - */ - public function readMixedArray() - { - $length = $this->_stream->readLong(); - return $this->readObject(); - } - - /** - * Converts numerically indexed actiosncript arrays into php arrays. - * - * Called when marker type is 10 - * - * @return array - */ - public function readArray() - { - $length = $this->_stream->readLong(); - $array = array(); - while ($length--) { - $array[] = $this->readTypeMarker(); - } - return $array; - } - - /** - * Convert AS Date to Zend_Date - * - * @return Zend_Date - */ - public function readDate() - { - // get the unix time stamp. Not sure why ActionScript does not use - // milliseconds - $timestamp = floor($this->_stream->readDouble() / 1000); - - // The timezone offset is never returned to the server; it is always 0, - // so read and ignore. - $offset = $this->_stream->readInt(); - - #require_once 'Zend/Date.php'; - $date = new Zend_Date($timestamp); - return $date; - } - - /** - * Convert XML to SimpleXml - * If user wants DomDocument they can use dom_import_simplexml - * - * @return SimpleXml Object - */ - public function readXmlString() - { - $string = $this->_stream->readLongUTF(); - return Zend_Xml_Security::scan($string); //simplexml_load_string($string); - } - - /** - * Read Class that is to be mapped to a server class. - * - * Commonly used for Value Objects on the server - * - * @todo implement Typed Class mapping - * @return object|array - * @throws Zend_Amf_Exception if unable to load type - */ - public function readTypedObject() - { - #require_once 'Zend/Amf/Parse/TypeLoader.php'; - // get the remote class name - $className = $this->_stream->readUTF(); - $loader = Zend_Amf_Parse_TypeLoader::loadType($className); - $returnObject = new $loader(); - $properties = get_object_vars($this->readObject()); - foreach($properties as $key=>$value) { - if($key) { - $returnObject->$key = $value; - } - } - if($returnObject instanceof Zend_Amf_Value_Messaging_ArrayCollection) { - $returnObject = get_object_vars($returnObject); - } - return $returnObject; - } - - /** - * AMF3 data type encountered load AMF3 Deserializer to handle - * type markers. - * - * @return string - */ - public function readAmf3TypeMarker() - { - #require_once 'Zend/Amf/Parse/Amf3/Deserializer.php'; - $deserializer = new Zend_Amf_Parse_Amf3_Deserializer($this->_stream); - $this->_objectEncoding = Zend_Amf_Constants::AMF3_OBJECT_ENCODING; - return $deserializer->readTypeMarker(); - } - - /** - * Return the object encoding to check if an AMF3 object - * is going to be return. - * - * @return int - */ - public function getObjectEncoding() - { - return $this->_objectEncoding; - } -} diff --git a/lib/Zend/Amf/Parse/Amf0/Serializer.php b/lib/Zend/Amf/Parse/Amf0/Serializer.php deleted file mode 100644 index 8748cf0a350..00000000000 --- a/lib/Zend/Amf/Parse/Amf0/Serializer.php +++ /dev/null @@ -1,362 +0,0 @@ -writeObjectReference($data, $markerType)) { - // Write the Type Marker to denote the following action script data type - $this->_stream->writeByte($markerType); - switch($markerType) { - case Zend_Amf_Constants::AMF0_NUMBER: - $this->_stream->writeDouble($data); - break; - case Zend_Amf_Constants::AMF0_BOOLEAN: - $this->_stream->writeByte($data); - break; - case Zend_Amf_Constants::AMF0_STRING: - $this->_stream->writeUTF($data); - break; - case Zend_Amf_Constants::AMF0_OBJECT: - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF0_NULL: - break; - case Zend_Amf_Constants::AMF0_REFERENCE: - $this->_stream->writeInt($data); - break; - case Zend_Amf_Constants::AMF0_MIXEDARRAY: - // Write length of numeric keys as zero. - $this->_stream->writeLong(0); - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF0_ARRAY: - $this->writeArray($data); - break; - case Zend_Amf_Constants::AMF0_DATE: - $this->writeDate($data); - break; - case Zend_Amf_Constants::AMF0_LONGSTRING: - $this->_stream->writeLongUTF($data); - break; - case Zend_Amf_Constants::AMF0_TYPEDOBJECT: - $this->writeTypedObject($data); - break; - case Zend_Amf_Constants::AMF0_AMF3: - $this->writeAmf3TypeMarker($data); - break; - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception("Unknown Type Marker: " . $markerType); - } - } - } else { - if (is_resource($data)) { - $data = Zend_Amf_Parse_TypeLoader::handleResource($data); - } - switch (true) { - case (is_int($data) || is_float($data)): - $markerType = Zend_Amf_Constants::AMF0_NUMBER; - break; - case (is_bool($data)): - $markerType = Zend_Amf_Constants::AMF0_BOOLEAN; - break; - case (is_string($data) && (($this->_mbStringFunctionsOverloaded ? mb_strlen($data, '8bit') : strlen($data)) > 65536)): - $markerType = Zend_Amf_Constants::AMF0_LONGSTRING; - break; - case (is_string($data)): - $markerType = Zend_Amf_Constants::AMF0_STRING; - break; - case (is_object($data)): - if (($data instanceof DateTime) || ($data instanceof Zend_Date)) { - $markerType = Zend_Amf_Constants::AMF0_DATE; - } else { - - if($className = $this->getClassName($data)){ - //Object is a Typed object set classname - $markerType = Zend_Amf_Constants::AMF0_TYPEDOBJECT; - $this->_className = $className; - } else { - // Object is a generic classname - $markerType = Zend_Amf_Constants::AMF0_OBJECT; - } - break; - } - break; - case (null === $data): - $markerType = Zend_Amf_Constants::AMF0_NULL; - break; - case (is_array($data)): - // check if it is an associative array - $i = 0; - foreach (array_keys($data) as $key) { - // check if it contains non-integer keys - if (!is_numeric($key) || intval($key) != $key) { - $markerType = Zend_Amf_Constants::AMF0_OBJECT; - break; - // check if it is a sparse indexed array - } else if ($key != $i) { - $markerType = Zend_Amf_Constants::AMF0_MIXEDARRAY; - break; - } - $i++; - } - // Dealing with a standard numeric array - if(!$markerType){ - $markerType = Zend_Amf_Constants::AMF0_ARRAY; - break; - } - break; - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data)); - } - - $this->writeTypeMarker($data, $markerType); - } - return $this; - } - - /** - * Check if the given object is in the reference table, write the reference if it exists, - * otherwise add the object to the reference table - * - * @param mixed $object object reference to check for reference - * @param string $markerType AMF type of the object to write - * @param mixed $objectByVal object to check for reference - * @return Boolean true, if the reference was written, false otherwise - */ - protected function writeObjectReference(&$object, $markerType, $objectByVal = false) - { - // Workaround for PHP5 with E_STRICT enabled complaining about "Only - // variables should be passed by reference" - if ((null === $object) && ($objectByVal !== false)) { - $object = &$objectByVal; - } - - if ($markerType == Zend_Amf_Constants::AMF0_OBJECT - || $markerType == Zend_Amf_Constants::AMF0_MIXEDARRAY - || $markerType == Zend_Amf_Constants::AMF0_ARRAY - || $markerType == Zend_Amf_Constants::AMF0_TYPEDOBJECT - ) { - $ref = array_search($object, $this->_referenceObjects, true); - //handle object reference - if($ref !== false){ - $this->writeTypeMarker($ref,Zend_Amf_Constants::AMF0_REFERENCE); - return true; - } - - $this->_referenceObjects[] = $object; - } - - return false; - } - - /** - * Write a PHP array with string or mixed keys. - * - * @param object $data - * @return Zend_Amf_Parse_Amf0_Serializer - */ - public function writeObject($object) - { - // Loop each element and write the name of the property. - foreach ($object as $key => &$value) { - // skip variables starting with an _ private transient - if( $key[0] == "_") continue; - $this->_stream->writeUTF($key); - $this->writeTypeMarker($value); - } - - // Write the end object flag - $this->_stream->writeInt(0); - $this->_stream->writeByte(Zend_Amf_Constants::AMF0_OBJECTTERM); - return $this; - } - - /** - * Write a standard numeric array to the output stream. If a mixed array - * is encountered call writeTypeMarker with mixed array. - * - * @param array $array - * @return Zend_Amf_Parse_Amf0_Serializer - */ - public function writeArray(&$array) - { - $length = count($array); - if (!$length < 0) { - // write the length of the array - $this->_stream->writeLong(0); - } else { - // Write the length of the numeric array - $this->_stream->writeLong($length); - for ($i=0; $i<$length; $i++) { - $value = isset($array[$i]) ? $array[$i] : null; - $this->writeTypeMarker($value); - } - } - return $this; - } - - /** - * Convert the DateTime into an AMF Date - * - * @param DateTime|Zend_Date $data - * @return Zend_Amf_Parse_Amf0_Serializer - */ - public function writeDate($data) - { - if ($data instanceof DateTime) { - $dateString = $data->format('U'); - } elseif ($data instanceof Zend_Date) { - $dateString = $data->toString('U'); - } else { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Invalid date specified; must be a DateTime or Zend_Date object'); - } - $dateString *= 1000; - - // Make the conversion and remove milliseconds. - $this->_stream->writeDouble($dateString); - - // Flash does not respect timezone but requires it. - $this->_stream->writeInt(0); - - return $this; - } - - /** - * Write a class mapped object to the output stream. - * - * @param object $data - * @return Zend_Amf_Parse_Amf0_Serializer - */ - public function writeTypedObject($data) - { - $this->_stream->writeUTF($this->_className); - $this->writeObject($data); - return $this; - } - - /** - * Encountered and AMF3 Type Marker use AMF3 serializer. Once AMF3 is - * encountered it will not return to AMf0. - * - * @param string $data - * @return Zend_Amf_Parse_Amf0_Serializer - */ - public function writeAmf3TypeMarker(&$data) - { - #require_once 'Zend/Amf/Parse/Amf3/Serializer.php'; - $serializer = new Zend_Amf_Parse_Amf3_Serializer($this->_stream); - $serializer->writeTypeMarker($data); - return $this; - } - - /** - * Find if the class name is a class mapped name and return the - * respective classname if it is. - * - * @param object $object - * @return false|string $className - */ - protected function getClassName($object) - { - #require_once 'Zend/Amf/Parse/TypeLoader.php'; - //Check to see if the object is a typed object and we need to change - $className = ''; - switch (true) { - // the return class mapped name back to actionscript class name. - case Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object)): - $className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object)); - break; - // Check to see if the user has defined an explicit Action Script type. - case isset($object->_explicitType): - $className = $object->_explicitType; - break; - // Check if user has defined a method for accessing the Action Script type - case method_exists($object, 'getASClassName'): - $className = $object->getASClassName(); - break; - // No return class name is set make it a generic object - case ($object instanceof stdClass): - $className = ''; - break; - // By default, use object's class name - default: - $className = get_class($object); - break; - } - if(!$className == '') { - return $className; - } else { - return false; - } - } -} diff --git a/lib/Zend/Amf/Parse/Amf3/Deserializer.php b/lib/Zend/Amf/Parse/Amf3/Deserializer.php deleted file mode 100644 index a058fa19c58..00000000000 --- a/lib/Zend/Amf/Parse/Amf3/Deserializer.php +++ /dev/null @@ -1,425 +0,0 @@ -_stream->readByte(); - } - - switch($typeMarker) { - case Zend_Amf_Constants::AMF3_UNDEFINED: - return null; - case Zend_Amf_Constants::AMF3_NULL: - return null; - case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE: - return false; - case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE: - return true; - case Zend_Amf_Constants::AMF3_INTEGER: - return $this->readInteger(); - case Zend_Amf_Constants::AMF3_NUMBER: - return $this->_stream->readDouble(); - case Zend_Amf_Constants::AMF3_STRING: - return $this->readString(); - case Zend_Amf_Constants::AMF3_DATE: - return $this->readDate(); - case Zend_Amf_Constants::AMF3_ARRAY: - return $this->readArray(); - case Zend_Amf_Constants::AMF3_OBJECT: - return $this->readObject(); - case Zend_Amf_Constants::AMF3_XML: - case Zend_Amf_Constants::AMF3_XMLSTRING: - return $this->readXmlString(); - case Zend_Amf_Constants::AMF3_BYTEARRAY: - return $this->readString(); - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unsupported type marker: ' . $typeMarker); - } - } - - /** - * Read and deserialize an integer - * - * AMF 3 represents smaller integers with fewer bytes using the most - * significant bit of each byte. The worst case uses 32-bits - * to represent a 29-bit number, which is what we would have - * done with no compression. - * - 0x00000000 - 0x0000007F : 0xxxxxxx - * - 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx - * - 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx - * - 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx - * - 0x40000000 - 0xFFFFFFFF : throw range exception - * - * 0x04 -> integer type code, followed by up to 4 bytes of data. - * - * Parsing integers on OSFlash for the AMF3 integer data format: - * @link http://osflash.org/amf3/parsing_integers - * @return int|float - */ - public function readInteger() - { - $count = 1; - $intReference = $this->_stream->readByte(); - $result = 0; - while ((($intReference & 0x80) != 0) && $count < 4) { - $result <<= 7; - $result |= ($intReference & 0x7f); - $intReference = $this->_stream->readByte(); - $count++; - } - if ($count < 4) { - $result <<= 7; - $result |= $intReference; - } else { - // Use all 8 bits from the 4th byte - $result <<= 8; - $result |= $intReference; - - // Check if the integer should be negative - if (($result & 0x10000000) != 0) { - //and extend the sign bit - $result |= ~0xFFFFFFF; - } - } - return $result; - } - - /** - * Read and deserialize a string - * - * Strings can be sent as a reference to a previously - * occurring String by using an index to the implicit string reference table. - * Strings are encoding using UTF-8 - however the header may either - * describe a string literal or a string reference. - * - * - string = 0x06 string-data - * - string-data = integer-data [ modified-utf-8 ] - * - modified-utf-8 = *OCTET - * - * @return String - */ - public function readString() - { - $stringReference = $this->readInteger(); - - //Check if this is a reference string - if (($stringReference & 0x01) == 0) { - // reference string - $stringReference = $stringReference >> 1; - if ($stringReference >= count($this->_referenceStrings)) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Undefined string reference: ' . $stringReference); - } - // reference string found - return $this->_referenceStrings[$stringReference]; - } - - $length = $stringReference >> 1; - if ($length) { - $string = $this->_stream->readBytes($length); - $this->_referenceStrings[] = $string; - } else { - $string = ""; - } - return $string; - } - - /** - * Read and deserialize a date - * - * Data is the number of milliseconds elapsed since the epoch - * of midnight, 1st Jan 1970 in the UTC time zone. - * Local time zone information is not sent to flash. - * - * - date = 0x08 integer-data [ number-data ] - * - * @return Zend_Date - */ - public function readDate() - { - $dateReference = $this->readInteger(); - if (($dateReference & 0x01) == 0) { - $dateReference = $dateReference >> 1; - if ($dateReference>=count($this->_referenceObjects)) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Undefined date reference: ' . $dateReference); - } - return $this->_referenceObjects[$dateReference]; - } - - $timestamp = floor($this->_stream->readDouble() / 1000); - - #require_once 'Zend/Date.php'; - $dateTime = new Zend_Date($timestamp); - $this->_referenceObjects[] = $dateTime; - return $dateTime; - } - - /** - * Read amf array to PHP array - * - * - array = 0x09 integer-data ( [ 1OCTET *amf3-data ] | [OCTET *amf3-data 1] | [ OCTET *amf-data ] ) - * - * @return array - */ - public function readArray() - { - $arrayReference = $this->readInteger(); - if (($arrayReference & 0x01)==0){ - $arrayReference = $arrayReference >> 1; - if ($arrayReference>=count($this->_referenceObjects)) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknow array reference: ' . $arrayReference); - } - return $this->_referenceObjects[$arrayReference]; - } - - // Create a holder for the array in the reference list - $data = array(); - $this->_referenceObjects[] =& $data; - $key = $this->readString(); - - // Iterating for string based keys. - while ($key != '') { - $data[$key] = $this->readTypeMarker(); - $key = $this->readString(); - } - - $arrayReference = $arrayReference >>1; - - //We have a dense array - for ($i=0; $i < $arrayReference; $i++) { - $data[] = $this->readTypeMarker(); - } - - return $data; - } - - /** - * Read an object from the AMF stream and convert it into a PHP object - * - * @todo Rather than using an array of traitsInfo create Zend_Amf_Value_TraitsInfo - * @return object|array - */ - public function readObject() - { - $traitsInfo = $this->readInteger(); - $storedObject = ($traitsInfo & 0x01)==0; - $traitsInfo = $traitsInfo >> 1; - - // Check if the Object is in the stored Objects reference table - if ($storedObject) { - $ref = $traitsInfo; - if (!isset($this->_referenceObjects[$ref])) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknown Object reference: ' . $ref); - } - $returnObject = $this->_referenceObjects[$ref]; - } else { - // Check if the Object is in the stored Definitions reference table - $storedClass = ($traitsInfo & 0x01) == 0; - $traitsInfo = $traitsInfo >> 1; - if ($storedClass) { - $ref = $traitsInfo; - if (!isset($this->_referenceDefinitions[$ref])) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknows Definition reference: '. $ref); - } - // Populate the reference attributes - $className = $this->_referenceDefinitions[$ref]['className']; - $encoding = $this->_referenceDefinitions[$ref]['encoding']; - $propertyNames = $this->_referenceDefinitions[$ref]['propertyNames']; - } else { - // The class was not in the reference tables. Start reading rawdata to build traits. - // Create a traits table. Zend_Amf_Value_TraitsInfo would be ideal - $className = $this->readString(); - $encoding = $traitsInfo & 0x03; - $propertyNames = array(); - $traitsInfo = $traitsInfo >> 2; - } - - // We now have the object traits defined in variables. Time to go to work: - if (!$className) { - // No class name generic object - $returnObject = new stdClass(); - } else { - // Defined object - // Typed object lookup against registered classname maps - if ($loader = Zend_Amf_Parse_TypeLoader::loadType($className)) { - $returnObject = new $loader(); - } else { - //user defined typed object - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Typed object not found: '. $className . ' '); - } - } - - // Add the Object to the reference table - $this->_referenceObjects[] = $returnObject; - - $properties = array(); // clear value - // Check encoding types for additional processing. - switch ($encoding) { - case (Zend_Amf_Constants::ET_EXTERNAL): - // Externalizable object such as {ArrayCollection} and {ObjectProxy} - if (!$storedClass) { - $this->_referenceDefinitions[] = array( - 'className' => $className, - 'encoding' => $encoding, - 'propertyNames' => $propertyNames, - ); - } - $returnObject->externalizedData = $this->readTypeMarker(); - break; - case (Zend_Amf_Constants::ET_DYNAMIC): - // used for Name-value encoding - if (!$storedClass) { - $this->_referenceDefinitions[] = array( - 'className' => $className, - 'encoding' => $encoding, - 'propertyNames' => $propertyNames, - ); - } - // not a reference object read name value properties from byte stream - do { - $property = $this->readString(); - if ($property != "") { - $propertyNames[] = $property; - $properties[$property] = $this->readTypeMarker(); - } - } while ($property !=""); - break; - default: - // basic property list object. - if (!$storedClass) { - $count = $traitsInfo; // Number of properties in the list - for($i=0; $i< $count; $i++) { - $propertyNames[] = $this->readString(); - } - // Add a reference to the class. - $this->_referenceDefinitions[] = array( - 'className' => $className, - 'encoding' => $encoding, - 'propertyNames' => $propertyNames, - ); - } - foreach ($propertyNames as $property) { - $properties[$property] = $this->readTypeMarker(); - } - break; - } - - // Add properties back to the return object. - if (!is_array($properties)) $properties = array(); - foreach($properties as $key=>$value) { - if($key) { - $returnObject->$key = $value; - } - } - - - } - - if ($returnObject instanceof Zend_Amf_Value_Messaging_ArrayCollection) { - if (isset($returnObject->externalizedData)) { - $returnObject = $returnObject->externalizedData; - } else { - $returnObject = get_object_vars($returnObject); - } - } - - return $returnObject; - } - - /** - * Convert XML to SimpleXml - * If user wants DomDocument they can use dom_import_simplexml - * - * @return SimpleXml Object - */ - public function readXmlString() - { - $xmlReference = $this->readInteger(); - $length = $xmlReference >> 1; - $string = $this->_stream->readBytes($length); - return Zend_Xml_Security::scan($string); - } -} diff --git a/lib/Zend/Amf/Parse/Amf3/Serializer.php b/lib/Zend/Amf/Parse/Amf3/Serializer.php deleted file mode 100644 index 8e00e62e4d4..00000000000 --- a/lib/Zend/Amf/Parse/Amf3/Serializer.php +++ /dev/null @@ -1,534 +0,0 @@ -_stream->writeByte($markerType); - - switch ($markerType) { - case Zend_Amf_Constants::AMF3_NULL: - break; - case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE: - break; - case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE: - break; - case Zend_Amf_Constants::AMF3_INTEGER: - $this->writeInteger($data); - break; - case Zend_Amf_Constants::AMF3_NUMBER: - $this->_stream->writeDouble($data); - break; - case Zend_Amf_Constants::AMF3_STRING: - $this->writeString($data); - break; - case Zend_Amf_Constants::AMF3_DATE: - $this->writeDate($data); - break; - case Zend_Amf_Constants::AMF3_ARRAY: - $this->writeArray($data); - break; - case Zend_Amf_Constants::AMF3_OBJECT: - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF3_BYTEARRAY: - $this->writeByteArray($data); - break; - case Zend_Amf_Constants::AMF3_XMLSTRING; - $this->writeXml($data); - break; - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknown Type Marker: ' . $markerType); - } - } else { - // Detect Type Marker - if (is_resource($data)) { - $data = Zend_Amf_Parse_TypeLoader::handleResource($data); - } - switch (true) { - case (null === $data): - $markerType = Zend_Amf_Constants::AMF3_NULL; - break; - case (is_bool($data)): - if ($data){ - $markerType = Zend_Amf_Constants::AMF3_BOOLEAN_TRUE; - } else { - $markerType = Zend_Amf_Constants::AMF3_BOOLEAN_FALSE; - } - break; - case (is_int($data)): - if (($data > 0xFFFFFFF) || ($data < -268435456)) { - $markerType = Zend_Amf_Constants::AMF3_NUMBER; - } else { - $markerType = Zend_Amf_Constants::AMF3_INTEGER; - } - break; - case (is_float($data)): - $markerType = Zend_Amf_Constants::AMF3_NUMBER; - break; - case (is_string($data)): - $markerType = Zend_Amf_Constants::AMF3_STRING; - break; - case (is_array($data)): - $markerType = Zend_Amf_Constants::AMF3_ARRAY; - break; - case (is_object($data)): - // Handle object types. - if (($data instanceof DateTime) || ($data instanceof Zend_Date)) { - $markerType = Zend_Amf_Constants::AMF3_DATE; - } else if ($data instanceof Zend_Amf_Value_ByteArray) { - $markerType = Zend_Amf_Constants::AMF3_BYTEARRAY; - } else if (($data instanceof DOMDocument) || ($data instanceof SimpleXMLElement)) { - $markerType = Zend_Amf_Constants::AMF3_XMLSTRING; - } else { - $markerType = Zend_Amf_Constants::AMF3_OBJECT; - } - break; - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data)); - } - $this->writeTypeMarker($data, $markerType); - } - } - - /** - * Write an AMF3 integer - * - * @param int|float $data - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeInteger($int) - { - if (($int & 0xffffff80) == 0) { - $this->_stream->writeByte($int & 0x7f); - return $this; - } - - if (($int & 0xffffc000) == 0 ) { - $this->_stream->writeByte(($int >> 7 ) | 0x80); - $this->_stream->writeByte($int & 0x7f); - return $this; - } - - if (($int & 0xffe00000) == 0) { - $this->_stream->writeByte(($int >> 14 ) | 0x80); - $this->_stream->writeByte(($int >> 7 ) | 0x80); - $this->_stream->writeByte($int & 0x7f); - return $this; - } - - $this->_stream->writeByte(($int >> 22 ) | 0x80); - $this->_stream->writeByte(($int >> 15 ) | 0x80); - $this->_stream->writeByte(($int >> 8 ) | 0x80); - $this->_stream->writeByte($int & 0xff); - return $this; - } - - /** - * Send string to output stream, without trying to reference it. - * The string is prepended with strlen($string) << 1 | 0x01 - * - * @param string $string - * @return Zend_Amf_Parse_Amf3_Serializer - */ - protected function writeBinaryString(&$string){ - $ref = ($this->_mbStringFunctionsOverloaded ? mb_strlen($string, '8bit') : strlen($string)) << 1 | 0x01; - $this->writeInteger($ref); - $this->_stream->writeBytes($string); - - return $this; - } - - /** - * Send string to output stream - * - * @param string $string - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeString(&$string) - { - $len = $this->_mbStringFunctionsOverloaded ? mb_strlen($string, '8bit') : strlen($string); - if(!$len){ - $this->writeInteger(0x01); - return $this; - } - - $ref = array_key_exists($string, $this->_referenceStrings) - ? $this->_referenceStrings[$string] - : false; - if ($ref === false){ - $this->_referenceStrings[$string] = count($this->_referenceStrings); - $this->writeBinaryString($string); - } else { - $ref <<= 1; - $this->writeInteger($ref); - } - - return $this; - } - - /** - * Send ByteArray to output stream - * - * @param string|Zend_Amf_Value_ByteArray $data - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeByteArray(&$data) - { - if ($this->writeObjectReference($data)) { - return $this; - } - - if (is_string($data)) { - //nothing to do - } else if ($data instanceof Zend_Amf_Value_ByteArray) { - $data = $data->getData(); - } else { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Invalid ByteArray specified; must be a string or Zend_Amf_Value_ByteArray'); - } - - $this->writeBinaryString($data); - - return $this; - } - - /** - * Send xml to output stream - * - * @param DOMDocument|SimpleXMLElement $xml - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeXml($xml) - { - if ($this->writeObjectReference($xml)) { - return $this; - } - - if(is_string($xml)) { - //nothing to do - } else if ($xml instanceof DOMDocument) { - $xml = $xml->saveXml(); - } else if ($xml instanceof SimpleXMLElement) { - $xml = $xml->asXML(); - } else { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Invalid xml specified; must be a DOMDocument or SimpleXMLElement'); - } - - $this->writeBinaryString($xml); - - return $this; - } - - /** - * Convert DateTime/Zend_Date to AMF date - * - * @param DateTime|Zend_Date $date - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeDate($date) - { - if ($this->writeObjectReference($date)) { - return $this; - } - - if ($date instanceof DateTime) { - $dateString = $date->format('U') * 1000; - } elseif ($date instanceof Zend_Date) { - $dateString = $date->toString('U') * 1000; - } else { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Invalid date specified; must be a string DateTime or Zend_Date object'); - } - - $this->writeInteger(0x01); - // write time to stream minus milliseconds - $this->_stream->writeDouble($dateString); - return $this; - } - - /** - * Write a PHP array back to the amf output stream - * - * @param array $array - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeArray(&$array) - { - // arrays aren't reference here but still counted - $this->_referenceObjects[] = $array; - - // have to seperate mixed from numberic keys. - $numeric = array(); - $string = array(); - foreach ($array as $key => &$value) { - if (is_int($key)) { - $numeric[] = $value; - } else { - $string[$key] = $value; - } - } - - // write the preamble id of the array - $length = count($numeric); - $id = ($length << 1) | 0x01; - $this->writeInteger($id); - - //Write the mixed type array to the output stream - foreach($string as $key => &$value) { - $this->writeString($key) - ->writeTypeMarker($value); - } - $this->writeString($this->_strEmpty); - - // Write the numeric array to ouput stream - foreach($numeric as &$value) { - $this->writeTypeMarker($value); - } - return $this; - } - - /** - * Check if the given object is in the reference table, write the reference if it exists, - * otherwise add the object to the reference table - * - * @param mixed $object object reference to check for reference - * @param mixed $objectByVal object to check for reference - * @return Boolean true, if the reference was written, false otherwise - */ - protected function writeObjectReference(&$object, $objectByVal = false) - { - // Workaround for PHP5 with E_STRICT enabled complaining about "Only - // variables should be passed by reference" - if ((null === $object) && ($objectByVal !== false)) { - $object = &$objectByVal; - } - - $hash = spl_object_hash($object); - $ref = array_key_exists($hash, $this->_referenceObjects) - ? $this->_referenceObjects[$hash] - : false; - - // quickly handle object references - if ($ref !== false){ - $ref <<= 1; - $this->writeInteger($ref); - return true; - } - $this->_referenceObjects[$hash] = count($this->_referenceObjects); - return false; - } - - /** - * Write object to ouput stream - * - * @param mixed $data - * @return Zend_Amf_Parse_Amf3_Serializer - */ - public function writeObject($object) - { - if($this->writeObjectReference($object)){ - return $this; - } - - $className = ''; - - //Check to see if the object is a typed object and we need to change - switch (true) { - // the return class mapped name back to actionscript class name. - case ($className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object))): - break; - - // Check to see if the user has defined an explicit Action Script type. - case isset($object->_explicitType): - $className = $object->_explicitType; - break; - - // Check if user has defined a method for accessing the Action Script type - case method_exists($object, 'getASClassName'): - $className = $object->getASClassName(); - break; - - // No return class name is set make it a generic object - case ($object instanceof stdClass): - $className = ''; - break; - - // By default, use object's class name - default: - $className = get_class($object); - break; - } - - $writeTraits = true; - - //check to see, if we have a corresponding definition - if(array_key_exists($className, $this->_referenceDefinitions)){ - $traitsInfo = $this->_referenceDefinitions[$className]['id']; - $encoding = $this->_referenceDefinitions[$className]['encoding']; - $propertyNames = $this->_referenceDefinitions[$className]['propertyNames']; - - $traitsInfo = ($traitsInfo << 2) | 0x01; - - $writeTraits = false; - } else { - $propertyNames = array(); - - if($className == ''){ - //if there is no className, we interpret the class as dynamic without any sealed members - $encoding = Zend_Amf_Constants::ET_DYNAMIC; - } else { - $encoding = Zend_Amf_Constants::ET_PROPLIST; - - foreach($object as $key => $value) { - if( $key[0] != "_") { - $propertyNames[] = $key; - } - } - } - - $this->_referenceDefinitions[$className] = array( - 'id' => count($this->_referenceDefinitions), - 'encoding' => $encoding, - 'propertyNames' => $propertyNames, - ); - - $traitsInfo = Zend_Amf_Constants::AMF3_OBJECT_ENCODING; - $traitsInfo |= $encoding << 2; - $traitsInfo |= (count($propertyNames) << 4); - } - - $this->writeInteger($traitsInfo); - - if($writeTraits){ - $this->writeString($className); - foreach ($propertyNames as $value) { - $this->writeString($value); - } - } - - try { - switch($encoding) { - case Zend_Amf_Constants::ET_PROPLIST: - //Write the sealed values to the output stream. - foreach ($propertyNames as $key) { - $this->writeTypeMarker($object->$key); - } - break; - case Zend_Amf_Constants::ET_DYNAMIC: - //Write the sealed values to the output stream. - foreach ($propertyNames as $key) { - $this->writeTypeMarker($object->$key); - } - - //Write remaining properties - foreach($object as $key => $value){ - if(!in_array($key,$propertyNames) && $key[0] != "_"){ - $this->writeString($key); - $this->writeTypeMarker($value); - } - } - - //Write an empty string to end the dynamic part - $this->writeString($this->_strEmpty); - break; - case Zend_Amf_Constants::ET_EXTERNAL: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('External Object Encoding not implemented'); - break; - default: - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknown Object Encoding type: ' . $encoding); - } - } catch (Exception $e) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unable to writeObject output: ' . $e->getMessage(), 0, $e); - } - - return $this; - } -} diff --git a/lib/Zend/Amf/Parse/Deserializer.php b/lib/Zend/Amf/Parse/Deserializer.php deleted file mode 100644 index e6d4b1a853d..00000000000 --- a/lib/Zend/Amf/Parse/Deserializer.php +++ /dev/null @@ -1,65 +0,0 @@ -_stream = $stream; - } - - /** - * Checks for AMF marker types and calls the appropriate methods - * for deserializing those marker types. Markers are the data type of - * the following value. - * - * @param int $typeMarker - * @return mixed Whatever the data type is of the marker in php - */ - public abstract function readTypeMarker($markerType = null); -} diff --git a/lib/Zend/Amf/Parse/InputStream.php b/lib/Zend/Amf/Parse/InputStream.php deleted file mode 100644 index 180a465b068..00000000000 --- a/lib/Zend/Amf/Parse/InputStream.php +++ /dev/null @@ -1,39 +0,0 @@ - Value is Mysql type (exact string) => PHP type - */ - static public $fieldTypes = array( - "int" => "int", - "timestamp" => "int", - "year" => "int", - "real" => "float", - ); - /** - * Parse resource into array - * - * @param resource $resource - * @return array - */ - public function parse($resource) { - $result = array(); - $fieldcnt = mysql_num_fields($resource); - $fields_transform = array(); - for($i=0;$i<$fieldcnt;$i++) { - $type = mysql_field_type($resource, $i); - if(isset(self::$fieldTypes[$type])) { - $fields_transform[mysql_field_name($resource, $i)] = self::$fieldTypes[$type]; - } - } - - while($row = mysql_fetch_object($resource)) { - foreach($fields_transform as $fieldname => $fieldtype) { - settype($row->$fieldname, $fieldtype); - } - $result[] = $row; - } - return $result; - } -} diff --git a/lib/Zend/Amf/Parse/Resource/MysqliResult.php b/lib/Zend/Amf/Parse/Resource/MysqliResult.php deleted file mode 100644 index 45f53d4b73d..00000000000 --- a/lib/Zend/Amf/Parse/Resource/MysqliResult.php +++ /dev/null @@ -1,128 +0,0 @@ - "MYSQLI_TYPE_DECIMAL", - 1 => "MYSQLI_TYPE_TINYINT", - 2 => "MYSQLI_TYPE_SMALLINT", - 3 => "MYSQLI_TYPE_INTEGER", - 4 => "MYSQLI_TYPE_FLOAT", - 5 => "MYSQLI_TYPE_DOUBLE", - 7 => "MYSQLI_TYPE_TIMESTAMP", - 8 => "MYSQLI_TYPE_BIGINT", - 9 => "MYSQLI_TYPE_MEDIUMINT", - 10 => "MYSQLI_TYPE_DATE", - 11 => "MYSQLI_TYPE_TIME", - 12 => "MYSQLI_TYPE_DATETIME", - 13 => "MYSQLI_TYPE_YEAR", - 14 => "MYSQLI_TYPE_DATE", - 16 => "MYSQLI_TYPE_BIT", - 246 => "MYSQLI_TYPE_DECIMAL", - 247 => "MYSQLI_TYPE_ENUM", - 248 => "MYSQLI_TYPE_SET", - 249 => "MYSQLI_TYPE_TINYBLOB", - 250 => "MYSQLI_TYPE_MEDIUMBLOB", - 251 => "MYSQLI_TYPE_LONGBLOB", - 252 => "MYSQLI_TYPE_BLOB", - 253 => "MYSQLI_TYPE_VARCHAR", - 254 => "MYSQLI_TYPE_CHAR", - 255 => "MYSQLI_TYPE_GEOMETRY", - ); - - // Build an associative array for a type look up - static $mysqli_to_php = array( - "MYSQLI_TYPE_DECIMAL" => 'float', - "MYSQLI_TYPE_NEWDECIMAL" => 'float', - "MYSQLI_TYPE_BIT" => 'integer', - "MYSQLI_TYPE_TINYINT" => 'integer', - "MYSQLI_TYPE_SMALLINT" => 'integer', - "MYSQLI_TYPE_MEDIUMINT" => 'integer', - "MYSQLI_TYPE_BIGINT" => 'integer', - "MYSQLI_TYPE_INTEGER" => 'integer', - "MYSQLI_TYPE_FLOAT" => 'float', - "MYSQLI_TYPE_DOUBLE" => 'float', - "MYSQLI_TYPE_NULL" => 'null', - "MYSQLI_TYPE_TIMESTAMP" => 'string', - "MYSQLI_TYPE_INT24" => 'integer', - "MYSQLI_TYPE_DATE" => 'string', - "MYSQLI_TYPE_TIME" => 'string', - "MYSQLI_TYPE_DATETIME" => 'string', - "MYSQLI_TYPE_YEAR" => 'string', - "MYSQLI_TYPE_NEWDATE" => 'string', - "MYSQLI_TYPE_ENUM" => 'string', - "MYSQLI_TYPE_SET" => 'string', - "MYSQLI_TYPE_TINYBLOB" => 'object', - "MYSQLI_TYPE_MEDIUMBLOB" => 'object', - "MYSQLI_TYPE_LONGBLOB" => 'object', - "MYSQLI_TYPE_BLOB" => 'object', - "MYSQLI_TYPE_CHAR" => 'string', - "MYSQLI_TYPE_VARCHAR" => 'string', - "MYSQLI_TYPE_GEOMETRY" => 'object', - "MYSQLI_TYPE_BIT" => 'integer', - ); - - /** - * Parse resource into array - * - * @param resource $resource - * @return array - */ - public function parse($resource) { - - $result = array(); - $fieldcnt = mysqli_num_fields($resource); - - - $fields_transform = array(); - - for($i=0;$i<$fieldcnt;$i++) { - $finfo = mysqli_fetch_field_direct($resource, $i); - - if(isset(self::$mysqli_type[$finfo->type])) { - $fields_transform[$finfo->name] = self::$mysqli_to_php[self::$mysqli_type[$finfo->type]]; - } - } - - while($row = mysqli_fetch_assoc($resource)) { - foreach($fields_transform as $fieldname => $fieldtype) { - settype($row[$fieldname], $fieldtype); - } - $result[] = $row; - } - return $result; - } -} diff --git a/lib/Zend/Amf/Parse/Resource/Stream.php b/lib/Zend/Amf/Parse/Resource/Stream.php deleted file mode 100644 index b8afa148ac2..00000000000 --- a/lib/Zend/Amf/Parse/Resource/Stream.php +++ /dev/null @@ -1,42 +0,0 @@ -_stream = $stream; - $this->_mbStringFunctionsOverloaded = function_exists('mb_strlen') && (ini_get('mbstring.func_overload') !== '') && ((int)ini_get('mbstring.func_overload') & 2); - } - - /** - * Find the PHP object type and convert it into an AMF object type - * - * @param mixed $content - * @param int $markerType - * @param mixed $contentByVal - * @return void - */ - public abstract function writeTypeMarker(&$content, $markerType = null, $contentByVal = false); -} diff --git a/lib/Zend/Amf/Parse/TypeLoader.php b/lib/Zend/Amf/Parse/TypeLoader.php deleted file mode 100644 index 6be80cf079f..00000000000 --- a/lib/Zend/Amf/Parse/TypeLoader.php +++ /dev/null @@ -1,231 +0,0 @@ - 'Zend_Amf_Value_Messaging_AcknowledgeMessage', - 'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_AsyncMessage', - 'flex.messaging.messages.CommandMessage' => 'Zend_Amf_Value_Messaging_CommandMessage', - 'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_ErrorMessage', - 'flex.messaging.messages.RemotingMessage' => 'Zend_Amf_Value_Messaging_RemotingMessage', - 'flex.messaging.io.ArrayCollection' => 'Zend_Amf_Value_Messaging_ArrayCollection', - ); - - /** - * @var array Default class map - */ - protected static $_defaultClassMap = array( - 'flex.messaging.messages.AcknowledgeMessage' => 'Zend_Amf_Value_Messaging_AcknowledgeMessage', - 'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_AsyncMessage', - 'flex.messaging.messages.CommandMessage' => 'Zend_Amf_Value_Messaging_CommandMessage', - 'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_ErrorMessage', - 'flex.messaging.messages.RemotingMessage' => 'Zend_Amf_Value_Messaging_RemotingMessage', - 'flex.messaging.io.ArrayCollection' => 'Zend_Amf_Value_Messaging_ArrayCollection', - ); - - /** - * @var Zend_Loader_PluginLoader_Interface - */ - protected static $_resourceLoader = null; - - - /** - * Load the mapped class type into a callback. - * - * @param string $className - * @return object|false - */ - public static function loadType($className) - { - $class = self::getMappedClassName($className); - if(!$class) { - $class = str_replace('.', '_', $className); - } - if (!class_exists($class)) { - return "stdClass"; - } - return $class; - } - - /** - * Looks up the supplied call name to its mapped class name - * - * @param string $className - * @return string - */ - public static function getMappedClassName($className) - { - $mappedName = array_search($className, self::$classMap); - - if ($mappedName) { - return $mappedName; - } - - $mappedName = array_search($className, array_flip(self::$classMap)); - - if ($mappedName) { - return $mappedName; - } - - return false; - } - - /** - * Map PHP class names to ActionScript class names - * - * Allows users to map the class names of there action script classes - * to the equivelent php class name. Used in deserialization to load a class - * and serialiation to set the class name of the returned object. - * - * @param string $asClassName - * @param string $phpClassName - * @return void - */ - public static function setMapping($asClassName, $phpClassName) - { - self::$classMap[$asClassName] = $phpClassName; - } - - /** - * Reset type map - * - * @return void - */ - public static function resetMap() - { - self::$classMap = self::$_defaultClassMap; - } - - /** - * Set loader for resource type handlers - * - * @param Zend_Loader_PluginLoader_Interface $loader - */ - public static function setResourceLoader(Zend_Loader_PluginLoader_Interface $loader) - { - self::$_resourceLoader = $loader; - } - - /** - * Add directory to the list of places where to look for resource handlers - * - * @param string $prefix - * @param string $dir - */ - public static function addResourceDirectory($prefix, $dir) - { - if(self::$_resourceLoader) { - self::$_resourceLoader->addPrefixPath($prefix, $dir); - } - } - - /** - * Get plugin class that handles this resource - * - * @param resource $resource Resource type - * @return string Class name - */ - public static function getResourceParser($resource) - { - if(self::$_resourceLoader) { - $type = preg_replace("/[^A-Za-z0-9_]/", " ", get_resource_type($resource)); - $type = str_replace(" ","", ucwords($type)); - return self::$_resourceLoader->load($type); - } - return false; - } - - /** - * Convert resource to a serializable object - * - * @param resource $resource - * @return mixed - */ - public static function handleResource($resource) - { - if(!self::$_resourceLoader) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unable to handle resources - resource plugin loader not set'); - } - try { - while(is_resource($resource)) { - $resclass = self::getResourceParser($resource); - if(!$resclass) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Can not serialize resource type: '. get_resource_type($resource)); - } - $parser = new $resclass(); - if(is_callable(array($parser, 'parse'))) { - $resource = $parser->parse($resource); - } else { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception("Could not call parse() method on class $resclass"); - } - } - return $resource; - } catch(Zend_Amf_Exception $e) { - throw new Zend_Amf_Exception($e->getMessage(), $e->getCode(), $e); - } catch(Exception $e) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Can not serialize resource type: '. get_resource_type($resource), 0, $e); - } - } -} diff --git a/lib/Zend/Amf/Request.php b/lib/Zend/Amf/Request.php deleted file mode 100644 index 38cc4c879dd..00000000000 --- a/lib/Zend/Amf/Request.php +++ /dev/null @@ -1,251 +0,0 @@ -_inputStream = new Zend_Amf_Parse_InputStream($request); - $this->_deserializer = new Zend_Amf_Parse_Amf0_Deserializer($this->_inputStream); - $this->readMessage($this->_inputStream); - return $this; - } - - /** - * Takes the raw AMF input stream and converts it into valid PHP objects - * - * @param Zend_Amf_Parse_InputStream - * @return Zend_Amf_Request - */ - public function readMessage(Zend_Amf_Parse_InputStream $stream) - { - $clientVersion = $stream->readUnsignedShort(); - if (($clientVersion != Zend_Amf_Constants::AMF0_OBJECT_ENCODING) - && ($clientVersion != Zend_Amf_Constants::AMF3_OBJECT_ENCODING) - && ($clientVersion != Zend_Amf_Constants::FMS_OBJECT_ENCODING) - ) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknown Player Version ' . $clientVersion); - } - - $this->_bodies = array(); - $this->_headers = array(); - $headerCount = $stream->readInt(); - - // Iterate through the AMF envelope header - while ($headerCount--) { - $this->_headers[] = $this->readHeader(); - } - - // Iterate through the AMF envelope body - $bodyCount = $stream->readInt(); - while ($bodyCount--) { - $this->_bodies[] = $this->readBody(); - } - - return $this; - } - - /** - * Deserialize a message header from the input stream. - * - * A message header is structured as: - * - NAME String - * - MUST UNDERSTAND Boolean - * - LENGTH Int - * - DATA Object - * - * @return Zend_Amf_Value_MessageHeader - */ - public function readHeader() - { - $name = $this->_inputStream->readUTF(); - $mustRead = (bool)$this->_inputStream->readByte(); - $length = $this->_inputStream->readLong(); - - try { - $data = $this->_deserializer->readTypeMarker(); - } catch (Exception $e) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unable to parse ' . $name . ' header data: ' . $e->getMessage() . ' '. $e->getLine(), 0, $e); - } - - $header = new Zend_Amf_Value_MessageHeader($name, $mustRead, $data, $length); - return $header; - } - - /** - * Deserialize a message body from the input stream - * - * @return Zend_Amf_Value_MessageBody - */ - public function readBody() - { - $targetURI = $this->_inputStream->readUTF(); - $responseURI = $this->_inputStream->readUTF(); - $length = $this->_inputStream->readLong(); - - try { - $data = $this->_deserializer->readTypeMarker(); - } catch (Exception $e) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unable to parse ' . $targetURI . ' body data ' . $e->getMessage(), 0, $e); - } - - // Check for AMF3 objectEncoding - if ($this->_deserializer->getObjectEncoding() == Zend_Amf_Constants::AMF3_OBJECT_ENCODING) { - /* - * When and AMF3 message is sent to the server it is nested inside - * an AMF0 array called Content. The following code gets the object - * out of the content array and sets it as the message data. - */ - if(is_array($data) && $data[0] instanceof Zend_Amf_Value_Messaging_AbstractMessage){ - $data = $data[0]; - } - - // set the encoding so we return our message in AMF3 - $this->_objectEncoding = Zend_Amf_Constants::AMF3_OBJECT_ENCODING; - } - - $body = new Zend_Amf_Value_MessageBody($targetURI, $responseURI, $data); - return $body; - } - - /** - * Return an array of the body objects that were found in the amf request. - * - * @return array {target, response, length, content} - */ - public function getAmfBodies() - { - return $this->_bodies; - } - - /** - * Accessor to private array of message bodies. - * - * @param Zend_Amf_Value_MessageBody $message - * @return Zend_Amf_Request - */ - public function addAmfBody(Zend_Amf_Value_MessageBody $message) - { - $this->_bodies[] = $message; - return $this; - } - - /** - * Return an array of headers that were found in the amf request. - * - * @return array {operation, mustUnderstand, length, param} - */ - public function getAmfHeaders() - { - return $this->_headers; - } - - /** - * Return the either 0 or 3 for respect AMF version - * - * @return int - */ - public function getObjectEncoding() - { - return $this->_objectEncoding; - } - - /** - * Set the object response encoding - * - * @param mixed $int - * @return Zend_Amf_Request - */ - public function setObjectEncoding($int) - { - $this->_objectEncoding = $int; - return $this; - } -} diff --git a/lib/Zend/Amf/Request/Http.php b/lib/Zend/Amf/Request/Http.php deleted file mode 100644 index c8e4dfaca56..00000000000 --- a/lib/Zend/Amf/Request/Http.php +++ /dev/null @@ -1,80 +0,0 @@ -_rawRequest = $amfRequest; - $this->initialize($amfRequest); - } else { - echo '

Zend Amf Endpoint

' ; - } - } - - /** - * Retrieve raw AMF Request - * - * @return string - */ - public function getRawRequest() - { - return $this->_rawRequest; - } -} diff --git a/lib/Zend/Amf/Response.php b/lib/Zend/Amf/Response.php deleted file mode 100644 index 280556ceed9..00000000000 --- a/lib/Zend/Amf/Response.php +++ /dev/null @@ -1,205 +0,0 @@ -_outputStream = new Zend_Amf_Parse_OutputStream(); - $this->writeMessage($this->_outputStream); - return $this; - } - - /** - * Serialize the PHP data types back into Actionscript and - * create and AMF stream. - * - * @param Zend_Amf_Parse_OutputStream $stream - * @return Zend_Amf_Response - */ - public function writeMessage(Zend_Amf_Parse_OutputStream $stream) - { - $objectEncoding = $this->_objectEncoding; - - //Write encoding to start of stream. Preamble byte is written of two byte Unsigned Short - $stream->writeByte(0x00); - $stream->writeByte($objectEncoding); - - // Loop through the AMF Headers that need to be returned. - $headerCount = count($this->_headers); - $stream->writeInt($headerCount); - foreach ($this->getAmfHeaders() as $header) { - $serializer = new Zend_Amf_Parse_Amf0_Serializer($stream); - $stream->writeUTF($header->name); - $stream->writeByte($header->mustRead); - $stream->writeLong(Zend_Amf_Constants::UNKNOWN_CONTENT_LENGTH); - if (is_object($header->data)) { - // Workaround for PHP5 with E_STRICT enabled complaining about - // "Only variables should be passed by reference" - $placeholder = null; - $serializer->writeTypeMarker($placeholder, null, $header->data); - } else { - $serializer->writeTypeMarker($header->data); - } - } - - // loop through the AMF bodies that need to be returned. - $bodyCount = count($this->_bodies); - $stream->writeInt($bodyCount); - foreach ($this->_bodies as $body) { - $serializer = new Zend_Amf_Parse_Amf0_Serializer($stream); - $stream->writeUTF($body->getTargetURI()); - $stream->writeUTF($body->getResponseURI()); - $stream->writeLong(Zend_Amf_Constants::UNKNOWN_CONTENT_LENGTH); - $bodyData = $body->getData(); - $markerType = ($this->_objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) ? null : Zend_Amf_Constants::AMF0_AMF3; - if (is_object($bodyData)) { - // Workaround for PHP5 with E_STRICT enabled complaining about - // "Only variables should be passed by reference" - $placeholder = null; - $serializer->writeTypeMarker($placeholder, $markerType, $bodyData); - } else { - $serializer->writeTypeMarker($bodyData, $markerType); - } - } - - return $this; - } - - /** - * Return the output stream content - * - * @return string The contents of the output stream - */ - public function getResponse() - { - return $this->_outputStream->getStream(); - } - - /** - * Return the output stream content - * - * @return string - */ - public function __toString() - { - return $this->getResponse(); - } - - /** - * Add an AMF body to be sent to the Flash Player - * - * @param Zend_Amf_Value_MessageBody $body - * @return Zend_Amf_Response - */ - public function addAmfBody(Zend_Amf_Value_MessageBody $body) - { - $this->_bodies[] = $body; - return $this; - } - - /** - * Return an array of AMF bodies to be serialized - * - * @return array - */ - public function getAmfBodies() - { - return $this->_bodies; - } - - /** - * Add an AMF Header to be sent back to the flash player - * - * @param Zend_Amf_Value_MessageHeader $header - * @return Zend_Amf_Response - */ - public function addAmfHeader(Zend_Amf_Value_MessageHeader $header) - { - $this->_headers[] = $header; - return $this; - } - - /** - * Retrieve attached AMF message headers - * - * @return array Array of Zend_Amf_Value_MessageHeader objects - */ - public function getAmfHeaders() - { - return $this->_headers; - } - - /** - * Set the AMF encoding that will be used for serialization - * - * @param int $encoding - * @return Zend_Amf_Response - */ - public function setObjectEncoding($encoding) - { - $this->_objectEncoding = $encoding; - return $this; - } -} diff --git a/lib/Zend/Amf/Response/Http.php b/lib/Zend/Amf/Response/Http.php deleted file mode 100644 index d9afaf4dcb6..00000000000 --- a/lib/Zend/Amf/Response/Http.php +++ /dev/null @@ -1,73 +0,0 @@ -isIeOverSsl()) { - header('Cache-Control: cache, must-revalidate'); - header('Pragma: public'); - } else { - header('Cache-Control: no-cache, must-revalidate'); - header('Pragma: no-cache'); - } - header('Expires: Thu, 19 Nov 1981 08:52:00 GMT'); - header('Content-Type: application/x-amf'); - } - return parent::getResponse(); - } - - protected function isIeOverSsl() - { - $ssl = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : false; - if (!$ssl || ($ssl == 'off')) { - // IIS reports "off", whereas other browsers simply don't populate - return false; - } - - $ua = $_SERVER['HTTP_USER_AGENT']; - if (!preg_match('/; MSIE \d+\.\d+;/', $ua)) { - // Not MicroSoft Internet Explorer - return false; - } - - return true; - } -} diff --git a/lib/Zend/Amf/Server.php b/lib/Zend/Amf/Server.php deleted file mode 100644 index e8f429bfc1a..00000000000 --- a/lib/Zend/Amf/Server.php +++ /dev/null @@ -1,1048 +0,0 @@ - method pairs - * @var array - */ - protected $_table = array(); - - /** - * - * @var bool session flag; whether or not to add a session to each response. - */ - protected $_session = false; - - /** - * Namespace allows all AMF calls to not clobber other PHP session variables - * @var Zend_Session_NameSpace default session namespace zend_amf - */ - protected $_sesionNamespace = 'zend_amf'; - - /** - * Set the default session.name if php_ - * @var string - */ - protected $_sessionName = 'PHPSESSID'; - - /** - * Authentication handler object - * - * @var Zend_Amf_Auth_Abstract - */ - protected $_auth; - /** - * ACL handler object - * - * @var Zend_Acl - */ - protected $_acl; - /** - * The server constructor - */ - public function __construct() - { - Zend_Amf_Parse_TypeLoader::setResourceLoader(new Zend_Loader_PluginLoader(array("Zend_Amf_Parse_Resource" => "Zend/Amf/Parse/Resource"))); - } - - /** - * Set authentication adapter - * - * If the authentication adapter implements a "getAcl()" method, populate - * the ACL of this instance with it (if none exists already). - * - * @param Zend_Amf_Auth_Abstract $auth - * @return Zend_Amf_Server - */ - public function setAuth(Zend_Amf_Auth_Abstract $auth) - { - $this->_auth = $auth; - if ((null === $this->getAcl()) && method_exists($auth, 'getAcl')) { - $this->setAcl($auth->getAcl()); - } - return $this; - } - /** - * Get authentication adapter - * - * @return Zend_Amf_Auth_Abstract - */ - public function getAuth() - { - return $this->_auth; - } - - /** - * Set ACL adapter - * - * @param Zend_Acl $acl - * @return Zend_Amf_Server - */ - public function setAcl(Zend_Acl $acl) - { - $this->_acl = $acl; - return $this; - } - /** - * Get ACL adapter - * - * @return Zend_Acl - */ - public function getAcl() - { - return $this->_acl; - } - - /** - * Set production flag - * - * @param bool $flag - * @return Zend_Amf_Server - */ - public function setProduction($flag) - { - $this->_production = (bool) $flag; - return $this; - } - - /** - * Whether or not the server is in production - * - * @return bool - */ - public function isProduction() - { - return $this->_production; - } - - /** - * @param namespace of all incoming sessions defaults to Zend_Amf - * @return Zend_Amf_Server - */ - public function setSession($namespace = 'Zend_Amf') - { - #require_once 'Zend/Session.php'; - $this->_session = true; - $this->_sesionNamespace = new Zend_Session_Namespace($namespace); - return $this; - } - - /** - * Whether of not the server is using sessions - * @return bool - */ - public function isSession() - { - return $this->_session; - } - - /** - * Check if the ACL allows accessing the function or method - * - * @param string|object $object Object or class being accessed - * @param string $function Function or method being accessed - * @return unknown_type - */ - protected function _checkAcl($object, $function) - { - if(!$this->_acl) { - return true; - } - if($object) { - $class = is_object($object)?get_class($object):$object; - if(!$this->_acl->has($class)) { - #require_once 'Zend/Acl/Resource.php'; - $this->_acl->add(new Zend_Acl_Resource($class)); - } - $call = array($object, "initAcl"); - if(is_callable($call) && !call_user_func($call, $this->_acl)) { - // if initAcl returns false, no ACL check - return true; - } - } else { - $class = null; - } - - $auth = Zend_Auth::getInstance(); - if($auth->hasIdentity()) { - $role = $auth->getIdentity()->role; - } else { - if($this->_acl->hasRole(Zend_Amf_Constants::GUEST_ROLE)) { - $role = Zend_Amf_Constants::GUEST_ROLE; - } else { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception("Unauthenticated access not allowed"); - } - } - if($this->_acl->isAllowed($role, $class, $function)) { - return true; - } else { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception("Access not allowed"); - } - } - - /** - * Get PluginLoader for the Server - * - * @return Zend_Loader_PluginLoader - */ - protected function getLoader() - { - if(empty($this->_loader)) { - #require_once 'Zend/Loader/PluginLoader.php'; - $this->_loader = new Zend_Loader_PluginLoader(); - } - return $this->_loader; - } - - /** - * Loads a remote class or method and executes the function and returns - * the result - * - * @param string $method Is the method to execute - * @param mixed $param values for the method - * @return mixed $response the result of executing the method - * @throws Zend_Amf_Server_Exception - */ - protected function _dispatch($method, $params = null, $source = null) - { - if($source) { - if(($mapped = Zend_Amf_Parse_TypeLoader::getMappedClassName($source)) !== false) { - $source = $mapped; - } - } - $qualifiedName = empty($source) ? $method : $source . '.' . $method; - - if (!isset($this->_table[$qualifiedName])) { - // if source is null a method that was not defined was called. - if ($source) { - $className = str_replace('.', '_', $source); - if(class_exists($className, false) && !isset($this->_classAllowed[$className])) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Can not call "' . $className . '" - use setClass()'); - } - try { - $this->getLoader()->load($className); - } catch (Exception $e) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Class "' . $className . '" does not exist: '.$e->getMessage(), 0, $e); - } - // Add the new loaded class to the server. - #require_once 'Zend/Amf/Server/Exception.php'; - $this->setClass($className, $source); - } - - if (!isset($this->_table[$qualifiedName])) { - // Source is null or doesn't contain specified method - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Method "' . $method . '" does not exist'); - } - } - - $info = $this->_table[$qualifiedName]; - $argv = $info->getInvokeArguments(); - - if (0 < count($argv)) { - $params = array_merge($params, $argv); - } - - $params = $this->_castParameters($info, $params); - - if ($info instanceof Zend_Server_Reflection_Function) { - $func = $info->getName(); - $this->_checkAcl(null, $func); - $return = call_user_func_array($func, $params); - } elseif ($info instanceof Zend_Server_Reflection_Method) { - // Get class - $class = $info->getDeclaringClass()->getName(); - if ('static' == $info->isStatic()) { - // for some reason, invokeArgs() does not work the same as - // invoke(), and expects the first argument to be an object. - // So, using a callback if the method is static. - $this->_checkAcl($class, $info->getName()); - $return = call_user_func_array(array($class, $info->getName()), $params); - } else { - // Object methods - try { - $object = $info->getDeclaringClass()->newInstance(); - } catch (Exception $e) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Error instantiating class ' . $class . ' to invoke method ' . $info->getName() . ': '.$e->getMessage(), 621, $e); - } - $this->_checkAcl($object, $info->getName()); - $return = $info->invokeArgs($object, $params); - } - } else { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Method missing implementation ' . get_class($info)); - } - - return $return; - } - - /** - * Handles each of the 11 different command message types. - * - * A command message is a flex.messaging.messages.CommandMessage - * - * @see Zend_Amf_Value_Messaging_CommandMessage - * @param Zend_Amf_Value_Messaging_CommandMessage $message - * @return Zend_Amf_Value_Messaging_AcknowledgeMessage - */ - protected function _loadCommandMessage(Zend_Amf_Value_Messaging_CommandMessage $message) - { - #require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php'; - switch($message->operation) { - case Zend_Amf_Value_Messaging_CommandMessage::DISCONNECT_OPERATION : - case Zend_Amf_Value_Messaging_CommandMessage::CLIENT_PING_OPERATION : - $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message); - break; - case Zend_Amf_Value_Messaging_CommandMessage::LOGIN_OPERATION : - $data = explode(':', base64_decode($message->body)); - $userid = $data[0]; - $password = isset($data[1])?$data[1]:""; - if(empty($userid)) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Login failed: username not supplied'); - } - if(!$this->_handleAuth($userid, $password)) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Authentication failed'); - } - $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message); - break; - case Zend_Amf_Value_Messaging_CommandMessage::LOGOUT_OPERATION : - if($this->_auth) { - Zend_Auth::getInstance()->clearIdentity(); - } - $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message); - break; - default : - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('CommandMessage::' . $message->operation . ' not implemented'); - break; - } - return $return; - } - - /** - * Create appropriate error message - * - * @param int $objectEncoding Current AMF encoding - * @param string $message Message that was being processed when error happened - * @param string $description Error description - * @param mixed $detail Detailed data about the error - * @param int $code Error code - * @param int $line Error line - * @return Zend_Amf_Value_Messaging_ErrorMessage|array - */ - protected function _errorMessage($objectEncoding, $message, $description, $detail, $code, $line) - { - $return = null; - switch ($objectEncoding) { - case Zend_Amf_Constants::AMF0_OBJECT_ENCODING : - return array ( - 'description' => ($this->isProduction ()) ? '' : $description, - 'detail' => ($this->isProduction ()) ? '' : $detail, - 'line' => ($this->isProduction ()) ? 0 : $line, - 'code' => $code - ); - case Zend_Amf_Constants::AMF3_OBJECT_ENCODING : - #require_once 'Zend/Amf/Value/Messaging/ErrorMessage.php'; - $return = new Zend_Amf_Value_Messaging_ErrorMessage ( $message ); - $return->faultString = $this->isProduction () ? '' : $description; - $return->faultCode = $code; - $return->faultDetail = $this->isProduction () ? '' : $detail; - break; - } - return $return; - } - - /** - * Handle AMF authentication - * - * @param string $userid - * @param string $password - * @return boolean - */ - protected function _handleAuth( $userid, $password) - { - if (!$this->_auth) { - return true; - } - $this->_auth->setCredentials($userid, $password); - $auth = Zend_Auth::getInstance(); - $result = $auth->authenticate($this->_auth); - if ($result->isValid()) { - if (!$this->isSession()) { - $this->setSession(); - } - return true; - } else { - // authentication failed, good bye - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception( - "Authentication failed: " . join("\n", - $result->getMessages()), $result->getCode()); - } - - } - - /** - * Takes the deserialized AMF request and performs any operations. - * - * @todo should implement and SPL observer pattern for custom AMF headers - * @todo DescribeService support - * @param Zend_Amf_Request $request - * @return Zend_Amf_Response - * @throws Zend_Amf_server_Exception|Exception - */ - protected function _handle(Zend_Amf_Request $request) - { - // Get the object encoding of the request. - $objectEncoding = $request->getObjectEncoding(); - - // create a response object to place the output from the services. - $response = $this->getResponse(); - - // set response encoding - $response->setObjectEncoding($objectEncoding); - - // Authenticate, if we have credential headers - $error = false; - $headers = $request->getAmfHeaders(); - if (isset($headers[Zend_Amf_Constants::CREDENTIALS_HEADER]) - && isset($headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->userid) - && isset($headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->password) - ) { - try { - if ($this->_handleAuth( - $headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->userid, - $headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->password - )) { - // use RequestPersistentHeader to clear credentials - $response->addAmfHeader( - new Zend_Amf_Value_MessageHeader( - Zend_Amf_Constants::PERSISTENT_HEADER, - false, - new Zend_Amf_Value_MessageHeader( - Zend_Amf_Constants::CREDENTIALS_HEADER, - false, null - ) - ) - ); - } - } catch (Exception $e) { - // Error during authentication; report it - $error = $this->_errorMessage( - $objectEncoding, - '', - $e->getMessage(), - $e->getTraceAsString(), - $e->getCode(), - $e->getLine() - ); - $responseType = Zend_AMF_Constants::STATUS_METHOD; - } - } - - // Iterate through each of the service calls in the AMF request - foreach($request->getAmfBodies() as $body) - { - if ($error) { - // Error during authentication; just report it and be done - $responseURI = $body->getResponseURI() . $responseType; - $newBody = new Zend_Amf_Value_MessageBody($responseURI, null, $error); - $response->addAmfBody($newBody); - continue; - } - try { - switch ($objectEncoding) { - case Zend_Amf_Constants::AMF0_OBJECT_ENCODING: - // AMF0 Object Encoding - $targetURI = $body->getTargetURI(); - $message = ''; - - // Split the target string into its values. - $source = substr($targetURI, 0, strrpos($targetURI, '.')); - - if ($source) { - // Break off method name from namespace into source - $method = substr(strrchr($targetURI, '.'), 1); - $return = $this->_dispatch($method, $body->getData(), $source); - } else { - // Just have a method name. - $return = $this->_dispatch($targetURI, $body->getData()); - } - break; - case Zend_Amf_Constants::AMF3_OBJECT_ENCODING: - default: - // AMF3 read message type - $message = $body->getData(); - if ($message instanceof Zend_Amf_Value_Messaging_CommandMessage) { - // async call with command message - $return = $this->_loadCommandMessage($message); - } elseif ($message instanceof Zend_Amf_Value_Messaging_RemotingMessage) { - #require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php'; - $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message); - $return->body = $this->_dispatch($message->operation, $message->body, $message->source); - } else { - // Amf3 message sent with netConnection - $targetURI = $body->getTargetURI(); - - // Split the target string into its values. - $source = substr($targetURI, 0, strrpos($targetURI, '.')); - - if ($source) { - // Break off method name from namespace into source - $method = substr(strrchr($targetURI, '.'), 1); - $return = $this->_dispatch($method, $body->getData(), $source); - } else { - // Just have a method name. - $return = $this->_dispatch($targetURI, $body->getData()); - } - } - break; - } - $responseType = Zend_AMF_Constants::RESULT_METHOD; - } catch (Exception $e) { - $return = $this->_errorMessage($objectEncoding, $message, - $e->getMessage(), $e->getTraceAsString(),$e->getCode(), $e->getLine()); - $responseType = Zend_AMF_Constants::STATUS_METHOD; - } - - $responseURI = $body->getResponseURI() . $responseType; - $newBody = new Zend_Amf_Value_MessageBody($responseURI, null, $return); - $response->addAmfBody($newBody); - } - // Add a session header to the body if session is requested. - if($this->isSession()) { - $currentID = session_id(); - $joint = "?"; - if(isset($_SERVER['QUERY_STRING'])) { - if(!strpos($_SERVER['QUERY_STRING'], $currentID) !== FALSE) { - if(strrpos($_SERVER['QUERY_STRING'], "?") !== FALSE) { - $joint = "&"; - } - } - } - - // create a new AMF message header with the session id as a variable. - $sessionValue = $joint . $this->_sessionName . "=" . $currentID; - $sessionHeader = new Zend_Amf_Value_MessageHeader(Zend_Amf_Constants::URL_APPEND_HEADER, false, $sessionValue); - $response->addAmfHeader($sessionHeader); - } - - // serialize the response and return serialized body. - $response->finalize(); - } - - /** - * Handle an AMF call from the gateway. - * - * @param null|Zend_Amf_Request $request Optional - * @return Zend_Amf_Response - */ - public function handle($request = null) - { - // Check if request was passed otherwise get it from the server - if ($request === null || !$request instanceof Zend_Amf_Request) { - $request = $this->getRequest(); - } else { - $this->setRequest($request); - } - if ($this->isSession()) { - // Check if a session is being sent from the amf call - if (isset($_COOKIE[$this->_sessionName])) { - session_id($_COOKIE[$this->_sessionName]); - } - } - - // Check for errors that may have happend in deserialization of Request. - try { - // Take converted PHP objects and handle service call. - // Serialize to Zend_Amf_response for output stream - $this->_handle($request); - $response = $this->getResponse(); - } catch (Exception $e) { - // Handle any errors in the serialization and service calls. - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Handle error: ' . $e->getMessage() . ' ' . $e->getLine(), 0, $e); - } - - // Return the Amf serialized output string - return $response; - } - - /** - * Set request object - * - * @param string|Zend_Amf_Request $request - * @return Zend_Amf_Server - */ - public function setRequest($request) - { - if (is_string($request) && class_exists($request)) { - $request = new $request(); - if (!$request instanceof Zend_Amf_Request) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid request class'); - } - } elseif (!$request instanceof Zend_Amf_Request) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid request object'); - } - $this->_request = $request; - return $this; - } - - /** - * Return currently registered request object - * - * @return null|Zend_Amf_Request - */ - public function getRequest() - { - if (null === $this->_request) { - #require_once 'Zend/Amf/Request/Http.php'; - $this->setRequest(new Zend_Amf_Request_Http()); - } - - return $this->_request; - } - - /** - * Public access method to private Zend_Amf_Server_Response reference - * - * @param string|Zend_Amf_Server_Response $response - * @return Zend_Amf_Server - */ - public function setResponse($response) - { - if (is_string($response) && class_exists($response)) { - $response = new $response(); - if (!$response instanceof Zend_Amf_Response) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid response class'); - } - } elseif (!$response instanceof Zend_Amf_Response) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid response object'); - } - $this->_response = $response; - return $this; - } - - /** - * get a reference to the Zend_Amf_response instance - * - * @return Zend_Amf_Server_Response - */ - public function getResponse() - { - if (null === ($response = $this->_response)) { - #require_once 'Zend/Amf/Response/Http.php'; - $this->setResponse(new Zend_Amf_Response_Http()); - } - return $this->_response; - } - - /** - * Attach a class or object to the server - * - * Class may be either a class name or an instantiated object. Reflection - * is done on the class or object to determine the available public - * methods, and each is attached to the server as and available method. If - * a $namespace has been provided, that namespace is used to prefix - * AMF service call. - * - * @param string|object $class - * @param string $namespace Optional - * @param mixed $arg Optional arguments to pass to a method - * @return Zend_Amf_Server - * @throws Zend_Amf_Server_Exception on invalid input - */ - public function setClass($class, $namespace = '', $argv = null) - { - if (is_string($class) && !class_exists($class)){ - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid method or class'); - } elseif (!is_string($class) && !is_object($class)) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Invalid method or class; must be a classname or object'); - } - - $args = null; - if (2 < func_num_args()) { - $args = array_slice(func_get_args(), 2); - } - - // Use the class name as the name space by default. - - if ($namespace == '') { - $namespace = is_object($class) ? get_class($class) : $class; - } - - $this->_classAllowed[is_object($class) ? get_class($class) : $class] = true; - - $this->_methods[] = Zend_Server_Reflection::reflectClass($class, $args, $namespace); - $this->_buildDispatchTable(); - - return $this; - } - - /** - * Attach a function to the server - * - * Additional arguments to pass to the function at dispatch may be passed; - * any arguments following the namespace will be aggregated and passed at - * dispatch time. - * - * @param string|array $function Valid callback - * @param string $namespace Optional namespace prefix - * @return Zend_Amf_Server - * @throws Zend_Amf_Server_Exception - */ - public function addFunction($function, $namespace = '') - { - if (!is_string($function) && !is_array($function)) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Unable to attach function'); - } - - $argv = null; - if (2 < func_num_args()) { - $argv = array_slice(func_get_args(), 2); - } - - $function = (array) $function; - foreach ($function as $func) { - if (!is_string($func) || !function_exists($func)) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Unable to attach function'); - } - $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace); - } - - $this->_buildDispatchTable(); - return $this; - } - - - /** - * Creates an array of directories in which services can reside. - * TODO: add support for prefixes? - * - * @param string $dir - */ - public function addDirectory($dir) - { - $this->getLoader()->addPrefixPath("", $dir); - } - - /** - * Returns an array of directories that can hold services. - * - * @return array - */ - public function getDirectory() - { - return $this->getLoader()->getPaths(""); - } - - /** - * (Re)Build the dispatch table - * - * The dispatch table consists of a an array of method name => - * Zend_Server_Reflection_Function_Abstract pairs - * - * @return void - */ - protected function _buildDispatchTable() - { - $table = array(); - foreach ($this->_methods as $key => $dispatchable) { - if ($dispatchable instanceof Zend_Server_Reflection_Function_Abstract) { - $ns = $dispatchable->getNamespace(); - $name = $dispatchable->getName(); - $name = empty($ns) ? $name : $ns . '.' . $name; - - if (isset($table[$name])) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name); - } - $table[$name] = $dispatchable; - continue; - } - - if ($dispatchable instanceof Zend_Server_Reflection_Class) { - foreach ($dispatchable->getMethods() as $method) { - $ns = $method->getNamespace(); - $name = $method->getName(); - $name = empty($ns) ? $name : $ns . '.' . $name; - - if (isset($table[$name])) { - #require_once 'Zend/Amf/Server/Exception.php'; - throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name); - } - $table[$name] = $method; - continue; - } - } - } - $this->_table = $table; - } - - - - /** - * Raise a server fault - * - * Unimplemented - * - * @param string|Exception $fault - * @return void - */ - public function fault($fault = null, $code = 404) - { - } - - /** - * Returns a list of registered methods - * - * Returns an array of dispatchables (Zend_Server_Reflection_Function, - * _Method, and _Class items). - * - * @return array - */ - public function getFunctions() - { - return $this->_table; - } - - /** - * Set server persistence - * - * Unimplemented - * - * @param mixed $mode - * @return void - */ - public function setPersistence($mode) - { - } - - /** - * Load server definition - * - * Unimplemented - * - * @param array $definition - * @return void - */ - public function loadFunctions($definition) - { - } - - /** - * Map ActionScript classes to PHP classes - * - * @param string $asClass - * @param string $phpClass - * @return Zend_Amf_Server - */ - public function setClassMap($asClass, $phpClass) - { - #require_once 'Zend/Amf/Parse/TypeLoader.php'; - Zend_Amf_Parse_TypeLoader::setMapping($asClass, $phpClass); - return $this; - } - - /** - * List all available methods - * - * Returns an array of method names. - * - * @return array - */ - public function listMethods() - { - return array_keys($this->_table); - } - - /** - * Cast parameters - * - * Takes the provided parameters from the request, and attempts to cast them - * to objects, if the prototype defines any as explicit object types - * - * @param Reflection $reflectionMethod - * @param array $params - * @return array - */ - protected function _castParameters($reflectionMethod, array $params) - { - $prototypes = $reflectionMethod->getPrototypes(); - $nonObjectTypes = array( - 'null', - 'mixed', - 'void', - 'unknown', - 'bool', - 'boolean', - 'number', - 'int', - 'integer', - 'double', - 'float', - 'string', - 'array', - 'object', - 'stdclass', - ); - $types = array(); - foreach ($prototypes as $prototype) { - foreach ($prototype->getParameters() as $parameter) { - $type = $parameter->getType(); - if (in_array(strtolower($type), $nonObjectTypes)) { - continue; - } - $position = $parameter->getPosition(); - $types[$position] = $type; - } - } - - if (empty($types)) { - return $params; - } - - foreach ($params as $position => $value) { - if (!isset($types[$position])) { - // No specific type to cast to? done - continue; - } - - $type = $types[$position]; - - if (!class_exists($type)) { - // Not a class, apparently. done - continue; - } - - if ($value instanceof $type) { - // Already of the right type? done - continue; - } - - if (!is_array($value) && !is_object($value)) { - // Can't cast scalars to objects easily; done - continue; - } - - // Create instance, and loop through value to set - $object = new $type; - foreach ($value as $property => $defined) { - $object->{$property} = $defined; - } - - $params[$position] = $object; - } - - return $params; - } -} diff --git a/lib/Zend/Amf/Server/Exception.php b/lib/Zend/Amf/Server/Exception.php deleted file mode 100644 index 6ec77332b14..00000000000 --- a/lib/Zend/Amf/Server/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_stream = $stream; - $this->_needle = 0; - $this->_mbStringFunctionsOverloaded = function_exists('mb_strlen') && (ini_get('mbstring.func_overload') !== '') && ((int)ini_get('mbstring.func_overload') & 2); - $this->_streamLength = $this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream); - $this->_bigEndian = (pack('l', 1) === "\x00\x00\x00\x01"); - } - - /** - * Returns the current stream - * - * @return string - */ - public function getStream() - { - return $this->_stream; - } - - /** - * Read the number of bytes in a row for the length supplied. - * - * @todo Should check that there are enough bytes left in the stream we are about to read. - * @param int $length - * @return string - * @throws Zend_Amf_Exception for buffer underrun - */ - public function readBytes($length) - { - if (($length + $this->_needle) > $this->_streamLength) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Buffer underrun at needle position: ' . $this->_needle . ' while requesting length: ' . $length); - } - $bytes = $this->_mbStringFunctionsOverloaded ? mb_substr($this->_stream, $this->_needle, $length, '8bit') : substr($this->_stream, $this->_needle, $length); - $this->_needle+= $length; - return $bytes; - } - - /** - * Write any length of bytes to the stream - * - * Usually a string. - * - * @param string $bytes - * @return Zend_Amf_Util_BinaryStream - */ - public function writeBytes($bytes) - { - $this->_stream.= $bytes; - return $this; - } - - /** - * Reads a signed byte - * - * @return int Value is in the range of -128 to 127. - * @throws Zend_Amf_Exception - */ - public function readByte() - { - if (($this->_needle + 1) > $this->_streamLength) { - #require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception( - 'Buffer underrun at needle position: ' - . $this->_needle - . ' while requesting length: ' - . $this->_streamLength - ); - } - - return ord($this->_stream[$this->_needle++]); - } - - /** - * Writes the passed string into a signed byte on the stream. - * - * @param string $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeByte($stream) - { - $this->_stream.= pack('c', $stream); - return $this; - } - - /** - * Reads a signed 32-bit integer from the data stream. - * - * @return int Value is in the range of -2147483648 to 2147483647 - */ - public function readInt() - { - return ($this->readByte() << 8) + $this->readByte(); - } - - /** - * Write an the integer to the output stream as a 32 bit signed integer - * - * @param int $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeInt($stream) - { - $this->_stream.= pack('n', $stream); - return $this; - } - - /** - * Reads a UTF-8 string from the data stream - * - * @return string A UTF-8 string produced by the byte representation of characters - */ - public function readUtf() - { - $length = $this->readInt(); - return $this->readBytes($length); - } - - /** - * Wite a UTF-8 string to the outputstream - * - * @param string $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeUtf($stream) - { - $this->writeInt($this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream)); - $this->_stream.= $stream; - return $this; - } - - - /** - * Read a long UTF string - * - * @return string - */ - public function readLongUtf() - { - $length = $this->readLong(); - return $this->readBytes($length); - } - - /** - * Write a long UTF string to the buffer - * - * @param string $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeLongUtf($stream) - { - $this->writeLong($this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream)); - $this->_stream.= $stream; - } - - /** - * Read a long numeric value - * - * @return double - */ - public function readLong() - { - return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte(); - } - - /** - * Write long numeric value to output stream - * - * @param int|string $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeLong($stream) - { - $this->_stream.= pack('N', $stream); - return $this; - } - - /** - * Read a 16 bit unsigned short. - * - * @todo This could use the unpack() w/ S,n, or v - * @return double - */ - public function readUnsignedShort() - { - $byte1 = $this->readByte(); - $byte2 = $this->readByte(); - return (($byte1 << 8) | $byte2); - } - - /** - * Reads an IEEE 754 double-precision floating point number from the data stream. - * - * @return double Floating point number - */ - public function readDouble() - { - $bytes = $this->_mbStringFunctionsOverloaded ? mb_substr($this->_stream, $this->_needle, 8, '8bit') : substr($this->_stream, $this->_needle, 8); - $this->_needle+= 8; - - if (!$this->_bigEndian) { - $bytes = strrev($bytes); - } - - $double = unpack('dflt', $bytes); - return $double['flt']; - } - - /** - * Writes an IEEE 754 double-precision floating point number from the data stream. - * - * @param string|double $stream - * @return Zend_Amf_Util_BinaryStream - */ - public function writeDouble($stream) - { - $stream = pack('d', $stream); - if (!$this->_bigEndian) { - $stream = strrev($stream); - } - $this->_stream.= $stream; - return $this; - } - -} diff --git a/lib/Zend/Amf/Value/ByteArray.php b/lib/Zend/Amf/Value/ByteArray.php deleted file mode 100644 index 32ebf268b81..00000000000 --- a/lib/Zend/Amf/Value/ByteArray.php +++ /dev/null @@ -1,58 +0,0 @@ -_data = $data; - } - - /** - * Return the byte stream - * - * @return string - */ - public function getData() - { - return $this->_data; - } -} diff --git a/lib/Zend/Amf/Value/MessageBody.php b/lib/Zend/Amf/Value/MessageBody.php deleted file mode 100644 index 59cacba52be..00000000000 --- a/lib/Zend/Amf/Value/MessageBody.php +++ /dev/null @@ -1,182 +0,0 @@ - - * This Message structure defines how a local client would - * invoke a method/operation on a remote server. Additionally, - * the response from the Server is structured identically. - * - * @package Zend_Amf - * @subpackage Value - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Amf_Value_MessageBody -{ - /** - * A string describing which operation, function, or method - * is to be remotley invoked. - * @var string - */ - protected $_targetUri = ""; - - /** - * Universal Resource Identifier that uniquely targets the originator's - * Object that should receive the server's response. The server will - * use this path specification to target the "OnResult()" or "onStatus()" - * handlers within the client. For Flash, it specifies an ActionScript - * Object path only. The NetResponse object pointed to by the Response Uri - * contains the connection state information. Passing/specifying this - * provides a convenient mechanism for the client/server to share access - * to an object that is managing the state of the shared connection. - * - * Since the server will use this field in the event of an error, - * this field is required even if a successful server request would - * not be expected to return a value to the client. - * - * @var string - */ - protected $_responseUri = ""; - - /** - * Contains the actual data associated with the operation. It contains - * the client's parameter data that is passed to the server's operation/method. - * When serializing a root level data type or a parameter list array, no - * name field is included. That is, the data is anonomously represented - * as "Type Marker"/"Value" pairs. When serializing member data, the data is - * represented as a series of "Name"/"Type"/"Value" combinations. - * - * For server generated responses, it may contain any ActionScript - * data/objects that the server was expected to provide. - * - * @var string - */ - protected $_data; - - /** - * Constructor - * - * @param string $targetUri - * @param string $responseUri - * @param string $data - * @return void - */ - public function __construct($targetUri, $responseUri, $data) - { - $this->setTargetUri($targetUri); - $this->setResponseUri($responseUri); - $this->setData($data); - } - - /** - * Retrieve target Uri - * - * @return string - */ - public function getTargetUri() - { - return $this->_targetUri; - } - - /** - * Set target Uri - * - * @param string $targetUri - * @return Zend_Amf_Value_MessageBody - */ - public function setTargetUri($targetUri) - { - if (null === $targetUri) { - $targetUri = ''; - } - $this->_targetUri = (string) $targetUri; - return $this; - } - - /** - * Get target Uri - * - * @return string - */ - public function getResponseUri() - { - return $this->_responseUri; - } - - /** - * Set response Uri - * - * @param string $responseUri - * @return Zend_Amf_Value_MessageBody - */ - public function setResponseUri($responseUri) - { - if (null === $responseUri) { - $responseUri = ''; - } - $this->_responseUri = $responseUri; - return $this; - } - - /** - * Retrieve response data - * - * @return string - */ - public function getData() - { - return $this->_data; - } - - /** - * Set response data - * - * @param mixed $data - * @return Zend_Amf_Value_MessageBody - */ - public function setData($data) - { - $this->_data = $data; - return $this; - } - - /** - * Set reply method - * - * @param string $methodName - * @return Zend_Amf_Value_MessageBody - */ - public function setReplyMethod($methodName) - { - if (!preg_match('#^[/?]#', $methodName)) { - $this->_targetUri = rtrim($this->_targetUri, '/') . '/'; - } - $this->_targetUri = $this->_targetUri . $methodName; - return $this; - } -} diff --git a/lib/Zend/Amf/Value/MessageHeader.php b/lib/Zend/Amf/Value/MessageHeader.php deleted file mode 100644 index bdbbba2a7db..00000000000 --- a/lib/Zend/Amf/Value/MessageHeader.php +++ /dev/null @@ -1,81 +0,0 @@ -name = $name; - $this->mustRead = (bool) $mustRead; - $this->data = $data; - if (null !== $length) { - $this->length = (int) $length; - } - } -} diff --git a/lib/Zend/Amf/Value/Messaging/AbstractMessage.php b/lib/Zend/Amf/Value/Messaging/AbstractMessage.php deleted file mode 100644 index acb5a0c6c8e..00000000000 --- a/lib/Zend/Amf/Value/Messaging/AbstractMessage.php +++ /dev/null @@ -1,92 +0,0 @@ -clientId = $this->generateId(); - $this->destination = null; - $this->messageId = $this->generateId(); - $this->timestamp = time().'00'; - $this->timeToLive = 0; - $this->headers = new STDClass(); - $this->body = null; - - // correleate the two messages - if ($message && isset($message->messageId)) { - $this->correlationId = $message->messageId; - } - } -} diff --git a/lib/Zend/Amf/Value/Messaging/ArrayCollection.php b/lib/Zend/Amf/Value/Messaging/ArrayCollection.php deleted file mode 100644 index a759f58e53e..00000000000 --- a/lib/Zend/Amf/Value/Messaging/ArrayCollection.php +++ /dev/null @@ -1,35 +0,0 @@ -body - * of the message. - */ - const LOGIN_OPERATION = 8; - - /** - * This operation is used to log the user out of the current channel, and - * will invalidate the server session if the channel is HTTP based. - */ - const LOGOUT_OPERATION = 9; - - /** - * This operation is used to indicate that the client's subscription to a - * remote destination has been invalidated. - */ - const SESSION_INVALIDATE_OPERATION = 10; - - /** - * This operation is used by the MultiTopicConsumer to subscribe/unsubscribe - * from multiple subtopics/selectors in the same message. - */ - const MULTI_SUBSCRIBE_OPERATION = 11; - - /** - * This operation is used to indicate that a channel has disconnected - */ - const DISCONNECT_OPERATION = 12; - - /** - * This is the default operation for new CommandMessage instances. - */ - const UNKNOWN_OPERATION = 10000; - - /** - * The operation to execute for messages of this type - * @var int - */ - public $operation = self::UNKNOWN_OPERATION; -} diff --git a/lib/Zend/Amf/Value/Messaging/ErrorMessage.php b/lib/Zend/Amf/Value/Messaging/ErrorMessage.php deleted file mode 100644 index 87b3e384bb2..00000000000 --- a/lib/Zend/Amf/Value/Messaging/ErrorMessage.php +++ /dev/null @@ -1,67 +0,0 @@ -clientId = $this->generateId(); - $this->destination = null; - $this->messageId = $this->generateId(); - $this->timestamp = time().'00'; - $this->timeToLive = 0; - $this->headers = new stdClass(); - $this->body = null; - } -} diff --git a/lib/Zend/Amf/Value/TraitsInfo.php b/lib/Zend/Amf/Value/TraitsInfo.php deleted file mode 100644 index 64d3c990ea0..00000000000 --- a/lib/Zend/Amf/Value/TraitsInfo.php +++ /dev/null @@ -1,154 +0,0 @@ -_className = $className; - $this->_dynamic = $dynamic; - $this->_externalizable = $externalizable; - $this->_properties = $properties; - } - - /** - * Test if the class is a dynamic class - * - * @return boolean - */ - public function isDynamic() - { - return $this->_dynamic; - } - - /** - * Test if class is externalizable - * - * @return boolean - */ - public function isExternalizable() - { - return $this->_externalizable; - } - - /** - * Return the number of properties in the class - * - * @return int - */ - public function length() - { - return count($this->_properties); - } - - /** - * Return the class name - * - * @return string - */ - public function getClassName() - { - return $this->_className; - } - - /** - * Add an additional property - * - * @param string $name - * @return Zend_Amf_Value_TraitsInfo - */ - public function addProperty($name) - { - $this->_properties[] = $name; - return $this; - } - - /** - * Add all properties of the class. - * - * @param array $props - * @return Zend_Amf_Value_TraitsInfo - */ - public function addAllProperties(array $props) - { - $this->_properties = $props; - return $this; - } - - /** - * Get the property at a given index - * - * @param int $index - * @return string - */ - public function getProperty($index) - { - return $this->_properties[(int) $index]; - } - - /** - * Return all properties of the class. - * - * @return array - */ - public function getAllProperties() - { - return $this->_properties; - } -} diff --git a/lib/Zend/Application.php b/lib/Zend/Application.php deleted file mode 100644 index 51043107531..00000000000 --- a/lib/Zend/Application.php +++ /dev/null @@ -1,440 +0,0 @@ -_environment = (string) $environment; - - #require_once 'Zend/Loader/Autoloader.php'; - $this->_autoloader = Zend_Loader_Autoloader::getInstance(); - $this->_autoloader->suppressNotFoundWarnings($suppressNotFoundWarnings); - - if (null !== $options) { - if (is_string($options)) { - $options = $this->_loadConfig($options); - } elseif ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (!is_array($options)) { - throw new Zend_Application_Exception( - 'Invalid options provided; must be location of config file,' - . ' a config object, or an array' - ); - } - - $this->setOptions($options); - } - } - - /** - * Retrieve current environment - * - * @return string - */ - public function getEnvironment() - { - return $this->_environment; - } - - /** - * Retrieve autoloader instance - * - * @return Zend_Loader_Autoloader - */ - public function getAutoloader() - { - return $this->_autoloader; - } - - /** - * Set application options - * - * @param array $options - * @throws Zend_Application_Exception When no bootstrap path is provided - * @throws Zend_Application_Exception When invalid bootstrap information are provided - * @return Zend_Application - */ - public function setOptions(array $options) - { - if (!empty($options['config'])) { - if (is_array($options['config'])) { - $_options = array(); - foreach ($options['config'] as $tmp) { - $_options = $this->mergeOptions( - $_options, $this->_loadConfig($tmp) - ); - } - $options = $this->mergeOptions($_options, $options); - } else { - $options = $this->mergeOptions( - $this->_loadConfig($options['config']), $options - ); - } - } - - $this->_options = $options; - - $options = array_change_key_case($options, CASE_LOWER); - - $this->_optionKeys = array_keys($options); - - if (!empty($options['phpsettings'])) { - $this->setPhpSettings($options['phpsettings']); - } - - if (!empty($options['includepaths'])) { - $this->setIncludePaths($options['includepaths']); - } - - if (!empty($options['autoloadernamespaces'])) { - $this->setAutoloaderNamespaces($options['autoloadernamespaces']); - } - - if (!empty($options['autoloaderzfpath'])) { - $autoloader = $this->getAutoloader(); - if (method_exists($autoloader, 'setZfPath')) { - $zfPath = $options['autoloaderzfpath']; - $zfVersion = !empty($options['autoloaderzfversion']) - ? $options['autoloaderzfversion'] - : 'latest'; - $autoloader->setZfPath($zfPath, $zfVersion); - } - } - - if (!empty($options['bootstrap'])) { - $bootstrap = $options['bootstrap']; - - if (is_string($bootstrap)) { - $this->setBootstrap($bootstrap); - } elseif (is_array($bootstrap)) { - if (empty($bootstrap['path'])) { - throw new Zend_Application_Exception( - 'No bootstrap path provided' - ); - } - - $path = $bootstrap['path']; - $class = null; - - if (!empty($bootstrap['class'])) { - $class = $bootstrap['class']; - } - - $this->setBootstrap($path, $class); - } else { - throw new Zend_Application_Exception( - 'Invalid bootstrap information provided' - ); - } - } - - return $this; - } - - /** - * Retrieve application options (for caching) - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Is an option present? - * - * @param string $key - * @return bool - */ - public function hasOption($key) - { - return in_array(strtolower($key), $this->_optionKeys); - } - - /** - * Retrieve a single option - * - * @param string $key - * @return mixed - */ - public function getOption($key) - { - if ($this->hasOption($key)) { - $options = $this->getOptions(); - $options = array_change_key_case($options, CASE_LOWER); - return $options[strtolower($key)]; - } - return null; - } - - /** - * Merge options recursively - * - * @param array $array1 - * @param mixed $array2 - * @return array - */ - public function mergeOptions(array $array1, $array2 = null) - { - if (is_array($array2)) { - foreach ($array2 as $key => $val) { - if (is_array($array2[$key])) { - $array1[$key] = (array_key_exists($key, $array1) && is_array($array1[$key])) - ? $this->mergeOptions($array1[$key], $array2[$key]) - : $array2[$key]; - } else { - $array1[$key] = $val; - } - } - } - return $array1; - } - - /** - * Set PHP configuration settings - * - * @param array $settings - * @param string $prefix Key prefix to prepend to array values (used to map . separated INI values) - * @return Zend_Application - */ - public function setPhpSettings(array $settings, $prefix = '') - { - foreach ($settings as $key => $value) { - $key = empty($prefix) ? $key : $prefix . $key; - if (is_scalar($value)) { - ini_set($key, $value); - } elseif (is_array($value)) { - $this->setPhpSettings($value, $key . '.'); - } - } - - return $this; - } - - /** - * Set include path - * - * @param array $paths - * @return Zend_Application - */ - public function setIncludePaths(array $paths) - { - $path = implode(PATH_SEPARATOR, $paths); - set_include_path($path . PATH_SEPARATOR . get_include_path()); - return $this; - } - - /** - * Set autoloader namespaces - * - * @param array $namespaces - * @return Zend_Application - */ - public function setAutoloaderNamespaces(array $namespaces) - { - $autoloader = $this->getAutoloader(); - - foreach ($namespaces as $namespace) { - $autoloader->registerNamespace($namespace); - } - - return $this; - } - - /** - * Set bootstrap path/class - * - * @param string $path - * @param string $class - * @return Zend_Application - */ - public function setBootstrap($path, $class = null) - { - // setOptions() can potentially send a null value; specify default - // here - if (null === $class) { - $class = 'Bootstrap'; - } - - if (!class_exists($class, false)) { - require_once $path; - if (!class_exists($class, false)) { - throw new Zend_Application_Exception( - 'Bootstrap class not found' - ); - } - } - $this->_bootstrap = new $class($this); - - if (!$this->_bootstrap instanceof Zend_Application_Bootstrap_Bootstrapper) { - throw new Zend_Application_Exception( - 'Bootstrap class does not implement' - . ' Zend_Application_Bootstrap_Bootstrapper' - ); - } - - return $this; - } - - /** - * Get bootstrap object - * - * @return Zend_Application_Bootstrap_BootstrapAbstract - */ - public function getBootstrap() - { - if (null === $this->_bootstrap) { - $this->_bootstrap = new Zend_Application_Bootstrap_Bootstrap($this); - } - return $this->_bootstrap; - } - - /** - * Bootstrap application - * - * @param null|string|array $resource - * @return Zend_Application - */ - public function bootstrap($resource = null) - { - $this->getBootstrap()->bootstrap($resource); - return $this; - } - - /** - * Run the application - * - * @return void - */ - public function run() - { - $this->getBootstrap()->run(); - } - - /** - * Load configuration file of options - * - * @param string $file - * @throws Zend_Application_Exception When invalid configuration file is provided - * @return array - */ - protected function _loadConfig($file) - { - $environment = $this->getEnvironment(); - $suffix = pathinfo($file, PATHINFO_EXTENSION); - $suffix = ($suffix === 'dist') - ? pathinfo(basename($file, ".$suffix"), PATHINFO_EXTENSION) - : $suffix; - - switch (strtolower($suffix)) { - case 'ini': - $config = new Zend_Config_Ini($file, $environment); - break; - - case 'xml': - $config = new Zend_Config_Xml($file, $environment); - break; - - case 'json': - $config = new Zend_Config_Json($file, $environment); - break; - - case 'yaml': - case 'yml': - $config = new Zend_Config_Yaml($file, $environment); - break; - - case 'php': - case 'inc': - $config = include $file; - if (!is_array($config)) { - throw new Zend_Application_Exception( - 'Invalid configuration file provided; PHP file does not' - . ' return array value' - ); - } - return $config; - break; - - default: - throw new Zend_Application_Exception( - 'Invalid configuration file provided; unknown config type' - ); - } - - return $config->toArray(); - } -} diff --git a/lib/Zend/Application/Bootstrap/Bootstrap.php b/lib/Zend/Application/Bootstrap/Bootstrap.php deleted file mode 100644 index 6f09afbc208..00000000000 --- a/lib/Zend/Application/Bootstrap/Bootstrap.php +++ /dev/null @@ -1,168 +0,0 @@ -hasOption('resourceloader')) { - $this->setOptions( - array( - 'resourceloader' => $application->getOption( - 'resourceloader' - ) - ) - ); - } - $this->getResourceLoader(); - - if (!$this->hasPluginResource('FrontController')) { - $this->registerPluginResource('FrontController'); - } - } - - /** - * Run the application - * - * Checks to see that we have a default controller directory. If not, an - * exception is thrown. - * - * If so, it registers the bootstrap with the 'bootstrap' parameter of - * the front controller, and dispatches the front controller. - * - * @return mixed - * @throws Zend_Application_Bootstrap_Exception - */ - public function run() - { - $front = $this->getResource('FrontController'); - $default = $front->getDefaultModule(); - if (null === $front->getControllerDirectory($default)) { - throw new Zend_Application_Bootstrap_Exception( - 'No default controller directory registered with front controller' - ); - } - - $front->setParam('bootstrap', $this); - $response = $front->dispatch(); - if ($front->returnResponse()) { - return $response; - } - } - - /** - * Set module resource loader - * - * @param Zend_Loader_Autoloader_Resource $loader - * @return Zend_Application_Module_Bootstrap - */ - public function setResourceLoader(Zend_Loader_Autoloader_Resource $loader) - { - $this->_resourceLoader = $loader; - return $this; - } - - /** - * Retrieve module resource loader - * - * @return Zend_Loader_Autoloader_Resource - */ - public function getResourceLoader() - { - if ((null === $this->_resourceLoader) - && (false !== ($namespace = $this->getAppNamespace())) - ) { - $r = new ReflectionClass($this); - $path = $r->getFileName(); - $this->setResourceLoader( - new Zend_Application_Module_Autoloader( - array( - 'namespace' => $namespace, - 'basePath' => dirname($path), - ) - ) - ); - } - return $this->_resourceLoader; - } - - /** - * Get application namespace (used for module autoloading) - * - * @return string - */ - public function getAppNamespace() - { - return $this->_appNamespace; - } - - /** - * Set application namespace (for module autoloading) - * - * @param string - * @return Zend_Application_Bootstrap_Bootstrap - */ - public function setAppNamespace($value) - { - $this->_appNamespace = (string) $value; - return $this; - } -} diff --git a/lib/Zend/Application/Bootstrap/BootstrapAbstract.php b/lib/Zend/Application/Bootstrap/BootstrapAbstract.php deleted file mode 100644 index cec7c2e3c97..00000000000 --- a/lib/Zend/Application/Bootstrap/BootstrapAbstract.php +++ /dev/null @@ -1,784 +0,0 @@ -setApplication($application); - $options = $application->getOptions(); - $this->setOptions($options); - } - - /** - * Set class state - * - * @param array $options - * @return Zend_Application_Bootstrap_BootstrapAbstract - */ - public function setOptions(array $options) - { - $this->_options = $this->mergeOptions($this->_options, $options); - - $options = array_change_key_case($options, CASE_LOWER); - $this->_optionKeys = array_merge($this->_optionKeys, array_keys($options)); - - $methods = get_class_methods($this); - foreach ($methods as $key => $method) { - $methods[$key] = strtolower($method); - } - - if (array_key_exists('pluginpaths', $options)) { - $pluginLoader = $this->getPluginLoader(); - - foreach ($options['pluginpaths'] as $prefix => $path) { - $pluginLoader->addPrefixPath($prefix, $path); - } - unset($options['pluginpaths']); - } - - foreach ($options as $key => $value) { - $method = 'set' . strtolower($key); - - if (in_array($method, $methods)) { - $this->$method($value); - } elseif ('resources' == $key) { - foreach ($value as $resource => $resourceOptions) { - $this->registerPluginResource($resource, $resourceOptions); - } - } - } - return $this; - } - - /** - * Get current options from bootstrap - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Is an option present? - * - * @param string $key - * @return bool - */ - public function hasOption($key) - { - return in_array(strtolower($key), $this->_optionKeys); - } - - /** - * Retrieve a single option - * - * @param string $key - * @return mixed - */ - public function getOption($key) - { - if ($this->hasOption($key)) { - $options = $this->getOptions(); - $options = array_change_key_case($options, CASE_LOWER); - return $options[strtolower($key)]; - } - return null; - } - - /** - * Merge options recursively - * - * @param array $array1 - * @param mixed $array2 - * @return array - */ - public function mergeOptions(array $array1, $array2 = null) - { - if (is_array($array2)) { - foreach ($array2 as $key => $val) { - if (is_array($array2[$key])) { - $array1[$key] = (array_key_exists($key, $array1) && is_array($array1[$key])) - ? $this->mergeOptions($array1[$key], $array2[$key]) - : $array2[$key]; - } else { - $array1[$key] = $val; - } - } - } - return $array1; - } - - /** - * Get class resources (as resource/method pairs) - * - * Uses get_class_methods() by default, reflection on prior to 5.2.6, - * as a bug prevents the usage of get_class_methods() there. - * - * @return array - */ - public function getClassResources() - { - if (null === $this->_classResources) { - if (version_compare(PHP_VERSION, '5.2.6') === -1) { - $class = new ReflectionObject($this); - $classMethods = $class->getMethods(); - $methodNames = array(); - - foreach ($classMethods as $method) { - $methodNames[] = $method->getName(); - } - } else { - $methodNames = get_class_methods($this); - } - - $this->_classResources = array(); - foreach ($methodNames as $method) { - if (5 < strlen($method) && '_init' === substr($method, 0, 5)) { - $this->_classResources[strtolower(substr($method, 5))] = $method; - } - } - } - - return $this->_classResources; - } - - /** - * Get class resource names - * - * @return array - */ - public function getClassResourceNames() - { - $resources = $this->getClassResources(); - return array_keys($resources); - } - - /** - * Register a new resource plugin - * - * @param string|Zend_Application_Resource_Resource $resource - * @param mixed $options - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception When invalid resource is provided - */ - public function registerPluginResource($resource, $options = null) - { - if ($resource instanceof Zend_Application_Resource_Resource) { - $resource->setBootstrap($this); - $pluginName = $this->_resolvePluginResourceName($resource); - $this->_pluginResources[$pluginName] = $resource; - return $this; - } - - if (!is_string($resource)) { - throw new Zend_Application_Bootstrap_Exception('Invalid resource provided to ' . __METHOD__); - } - - $this->_pluginResources[$resource] = $options; - return $this; - } - - /** - * Unregister a resource from the bootstrap - * - * @param string|Zend_Application_Resource_Resource $resource - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception When unknown resource type is provided - */ - public function unregisterPluginResource($resource) - { - if ($resource instanceof Zend_Application_Resource_Resource) { - if ($index = array_search($resource, $this->_pluginResources, true)) { - unset($this->_pluginResources[$index]); - } - return $this; - } - - if (!is_string($resource)) { - throw new Zend_Application_Bootstrap_Exception('Unknown resource type provided to ' . __METHOD__); - } - - $resource = strtolower($resource); - if (array_key_exists($resource, $this->_pluginResources)) { - unset($this->_pluginResources[$resource]); - } - - return $this; - } - - /** - * Is the requested plugin resource registered? - * - * @param string $resource - * @return bool - */ - public function hasPluginResource($resource) - { - return (null !== $this->getPluginResource($resource)); - } - - /** - * Get a registered plugin resource - * - * @param string $resource - * @return Zend_Application_Resource_Resource - * @throws Zend_Application_Bootstrap_Exception - */ - public function getPluginResource($resource) - { - if (array_key_exists(strtolower($resource), $this->_pluginResources)) { - $resource = strtolower($resource); - if (!$this->_pluginResources[$resource] instanceof Zend_Application_Resource_Resource) { - $resourceName = $this->_loadPluginResource($resource, $this->_pluginResources[$resource]); - if (!$resourceName) { - throw new Zend_Application_Bootstrap_Exception(sprintf('Unable to resolve plugin "%s"; no corresponding plugin with that name', $resource)); - } - $resource = $resourceName; - } - return $this->_pluginResources[$resource]; - } - - foreach ($this->_pluginResources as $plugin => $spec) { - if ($spec instanceof Zend_Application_Resource_Resource) { - $pluginName = $this->_resolvePluginResourceName($spec); - if (0 === strcasecmp($resource, $pluginName)) { - unset($this->_pluginResources[$plugin]); - $this->_pluginResources[$pluginName] = $spec; - return $spec; - } - continue; - } - - if (false !== $pluginName = $this->_loadPluginResource($plugin, $spec)) { - if (0 === strcasecmp($resource, $pluginName)) { - return $this->_pluginResources[$pluginName]; - } - continue; - } - - if (class_exists($plugin) - && is_subclass_of($plugin, 'Zend_Application_Resource_Resource') - ) { //@SEE ZF-7550 - $spec = (array) $spec; - $spec['bootstrap'] = $this; - $instance = new $plugin($spec); - $pluginName = $this->_resolvePluginResourceName($instance); - unset($this->_pluginResources[$plugin]); - $this->_pluginResources[$pluginName] = $instance; - - if (0 === strcasecmp($resource, $pluginName)) { - return $instance; - } - } - } - - return null; - } - - /** - * Retrieve all plugin resources - * - * @return array - */ - public function getPluginResources() - { - foreach (array_keys($this->_pluginResources) as $resource) { - $this->getPluginResource($resource); - } - return $this->_pluginResources; - } - - /** - * Retrieve plugin resource names - * - * @return array - */ - public function getPluginResourceNames() - { - $this->getPluginResources(); - return array_keys($this->_pluginResources); - } - - /** - * Set plugin loader for loading resources - * - * @param Zend_Loader_PluginLoader_Interface $loader - * @return Zend_Application_Bootstrap_BootstrapAbstract - */ - public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader) - { - $this->_pluginLoader = $loader; - return $this; - } - - /** - * Get the plugin loader for resources - * - * @return Zend_Loader_PluginLoader_Interface - */ - public function getPluginLoader() - { - if ($this->_pluginLoader === null) { - $options = array( - 'Zend_Application_Resource' => 'Zend/Application/Resource', - 'ZendX_Application_Resource' => 'ZendX/Application/Resource' - ); - - $this->_pluginLoader = new Zend_Loader_PluginLoader($options); - } - - return $this->_pluginLoader; - } - - /** - * Set application/parent bootstrap - * - * @param Zend_Application|Zend_Application_Bootstrap_Bootstrapper $application - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception - */ - public function setApplication($application) - { - if (($application instanceof Zend_Application) - || ($application instanceof Zend_Application_Bootstrap_Bootstrapper) - ) { - if ($application === $this) { - throw new Zend_Application_Bootstrap_Exception('Cannot set application to same object; creates recursion'); - } - $this->_application = $application; - } else { - throw new Zend_Application_Bootstrap_Exception('Invalid application provided to bootstrap constructor (received "' . get_class($application) . '" instance)'); - } - return $this; - } - - /** - * Retrieve parent application instance - * - * @return Zend_Application|Zend_Application_Bootstrap_Bootstrapper - */ - public function getApplication() - { - return $this->_application; - } - - /** - * Retrieve application environment - * - * @return string - */ - public function getEnvironment() - { - if (null === $this->_environment) { - $this->_environment = $this->getApplication()->getEnvironment(); - } - return $this->_environment; - } - - /** - * Set resource container - * - * By default, if a resource callback has a non-null return value, this - * value will be stored in a container using the resource name as the - * key. - * - * Containers must be objects, and must allow setting public properties. - * - * @param object $container - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception - */ - public function setContainer($container) - { - if (!is_object($container)) { - throw new Zend_Application_Bootstrap_Exception('Resource containers must be objects'); - } - $this->_container = $container; - return $this; - } - - /** - * Retrieve resource container - * - * @return object - */ - public function getContainer() - { - if (null === $this->_container) { - $this->setContainer(new Zend_Registry()); - } - return $this->_container; - } - - /** - * Determine if a resource has been stored in the container - * - * During bootstrap resource initialization, you may return a value. If - * you do, it will be stored in the {@link setContainer() container}. - * You can use this method to determine if a value was stored. - * - * @param string $name - * @return bool - */ - public function hasResource($name) - { - $resource = strtolower($name); - $container = $this->getContainer(); - return isset($container->{$resource}); - } - - /** - * Retrieve a resource from the container - * - * During bootstrap resource initialization, you may return a value. If - * you do, it will be stored in the {@link setContainer() container}. - * You can use this method to retrieve that value. - * - * If no value was returned, this will return a null value. - * - * @param string $name - * @return null|mixed - */ - public function getResource($name) - { - $resource = strtolower($name); - $container = $this->getContainer(); - if ($this->hasResource($resource)) { - return $container->{$resource}; - } - return null; - } - - /** - * Implement PHP's magic to retrieve a resource - * in the bootstrap - * - * @param string $prop - * @return null|mixed - */ - public function __get($prop) - { - return $this->getResource($prop); - } - - /** - * Implement PHP's magic to ask for the - * existence of a resource in the bootstrap - * - * @param string $prop - * @return bool - */ - public function __isset($prop) - { - return $this->hasResource($prop); - } - - /** - * Bootstrap individual, all, or multiple resources - * - * Marked as final to prevent issues when subclassing and naming the - * child class 'Bootstrap' (in which case, overriding this method - * would result in it being treated as a constructor). - * - * If you need to override this functionality, override the - * {@link _bootstrap()} method. - * - * @param null|string|array $resource - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception When invalid argument was passed - */ - final public function bootstrap($resource = null) - { - $this->_bootstrap($resource); - return $this; - } - - /** - * Overloading: intercept calls to bootstrap() methods - * - * @param string $method - * @param array $args - * @return Zend_Application_Bootstrap_BootstrapAbstract - * @throws Zend_Application_Bootstrap_Exception On invalid method name - */ - public function __call($method, $args) - { - if (9 < strlen($method) && 'bootstrap' === substr($method, 0, 9)) { - $resource = substr($method, 9); - return $this->bootstrap($resource); - } - - throw new Zend_Application_Bootstrap_Exception('Invalid method "' . $method . '"'); - } - - /** - * Bootstrap implementation - * - * This method may be overridden to provide custom bootstrapping logic. - * It is the sole method called by {@link bootstrap()}. - * - * @param null|string|array $resource - * @return void - * @throws Zend_Application_Bootstrap_Exception When invalid argument was passed - */ - protected function _bootstrap($resource = null) - { - if (null === $resource) { - foreach ($this->getClassResourceNames() as $resource) { - $this->_executeResource($resource); - } - - foreach ($this->getPluginResourceNames() as $resource) { - $this->_executeResource($resource); - } - } elseif (is_string($resource)) { - $this->_executeResource($resource); - } elseif (is_array($resource)) { - foreach ($resource as $r) { - $this->_executeResource($r); - } - } else { - throw new Zend_Application_Bootstrap_Exception('Invalid argument passed to ' . __METHOD__); - } - } - - /** - * Execute a resource - * - * Checks to see if the resource has already been run. If not, it searches - * first to see if a local method matches the resource, and executes that. - * If not, it checks to see if a plugin resource matches, and executes that - * if found. - * - * Finally, if not found, it throws an exception. - * - * @param string $resource - * @return void - * @throws Zend_Application_Bootstrap_Exception When resource not found - */ - protected function _executeResource($resource) - { - $resourceName = strtolower($resource); - - if (in_array($resourceName, $this->_run)) { - return; - } - - if (isset($this->_started[$resourceName]) && $this->_started[$resourceName]) { - throw new Zend_Application_Bootstrap_Exception('Circular resource dependency detected'); - } - - $classResources = $this->getClassResources(); - if (array_key_exists($resourceName, $classResources)) { - $this->_started[$resourceName] = true; - $method = $classResources[$resourceName]; - $return = $this->$method(); - unset($this->_started[$resourceName]); - $this->_markRun($resourceName); - - if (null !== $return) { - $this->getContainer()->{$resourceName} = $return; - } - - return; - } - - if ($this->hasPluginResource($resource)) { - $this->_started[$resourceName] = true; - $plugin = $this->getPluginResource($resource); - $return = $plugin->init(); - unset($this->_started[$resourceName]); - $this->_markRun($resourceName); - - if (null !== $return) { - $this->getContainer()->{$resourceName} = $return; - } - - return; - } - - throw new Zend_Application_Bootstrap_Exception('Resource matching "' . $resource . '" not found'); - } - - /** - * Load a plugin resource - * - * @param string $resource - * @param array|object|null $options - * @return string|false - */ - protected function _loadPluginResource($resource, $options) - { - $options = (array) $options; - $options['bootstrap'] = $this; - $className = $this->getPluginLoader()->load(strtolower($resource), false); - - if (!$className) { - return false; - } - - $instance = new $className($options); - - unset($this->_pluginResources[$resource]); - - if (isset($instance->_explicitType)) { - $resource = $instance->_explicitType; - } - $resource = strtolower($resource); - $this->_pluginResources[$resource] = $instance; - - return $resource; - } - - /** - * Mark a resource as having run - * - * @param string $resource - * @return void - */ - protected function _markRun($resource) - { - if (!in_array($resource, $this->_run)) { - $this->_run[] = $resource; - } - } - - /** - * Resolve a plugin resource name - * - * Uses, in order of preference - * - $_explicitType property of resource - * - Short name of resource (if a matching prefix path is found) - * - class name (if none of the above are true) - * - * The name is then cast to lowercase. - * - * @param Zend_Application_Resource_Resource $resource - * @return string - */ - protected function _resolvePluginResourceName($resource) - { - if (isset($resource->_explicitType)) { - $pluginName = $resource->_explicitType; - } else { - $className = get_class($resource); - $pluginName = $className; - $loader = $this->getPluginLoader(); - foreach ($loader->getPaths() as $prefix => $paths) { - if (0 === strpos($className, $prefix)) { - $pluginName = substr($className, strlen($prefix)); - $pluginName = trim($pluginName, '_'); - break; - } - } - } - $pluginName = strtolower($pluginName); - return $pluginName; - } -} diff --git a/lib/Zend/Application/Bootstrap/Bootstrapper.php b/lib/Zend/Application/Bootstrap/Bootstrapper.php deleted file mode 100644 index edf56d15e22..00000000000 --- a/lib/Zend/Application/Bootstrap/Bootstrapper.php +++ /dev/null @@ -1,93 +0,0 @@ -initDefaultResourceTypes(); - } - - /** - * Initialize default resource types for module resource classes - * - * @return void - */ - public function initDefaultResourceTypes() - { - $basePath = $this->getBasePath(); - $this->addResourceTypes( - array( - 'dbtable' => array( - 'namespace' => 'Model_DbTable', - 'path' => 'models/DbTable', - ), - 'mappers' => array( - 'namespace' => 'Model_Mapper', - 'path' => 'models/mappers', - ), - 'form' => array( - 'namespace' => 'Form', - 'path' => 'forms', - ), - 'model' => array( - 'namespace' => 'Model', - 'path' => 'models', - ), - 'plugin' => array( - 'namespace' => 'Plugin', - 'path' => 'plugins', - ), - 'service' => array( - 'namespace' => 'Service', - 'path' => 'services', - ), - 'viewhelper' => array( - 'namespace' => 'View_Helper', - 'path' => 'views/helpers', - ), - 'viewfilter' => array( - 'namespace' => 'View_Filter', - 'path' => 'views/filters', - ), - ) - ); - $this->setDefaultResourceType('model'); - } -} diff --git a/lib/Zend/Application/Module/Bootstrap.php b/lib/Zend/Application/Module/Bootstrap.php deleted file mode 100644 index bbadb95a70a..00000000000 --- a/lib/Zend/Application/Module/Bootstrap.php +++ /dev/null @@ -1,127 +0,0 @@ -setApplication($application); - - // Use same plugin loader as parent bootstrap - if ($application instanceof Zend_Application_Bootstrap_ResourceBootstrapper) { - $this->setPluginLoader($application->getPluginLoader()); - } - - $key = strtolower($this->getModuleName()); - if ($application->hasOption($key)) { - // Don't run via setOptions() to prevent duplicate initialization - $this->setOptions($application->getOption($key)); - } - - if ($application->hasOption('resourceloader')) { - $this->setOptions(array( - 'resourceloader' => $application->getOption('resourceloader') - )); - } - $this->initResourceLoader(); - - // ZF-6545: ensure front controller resource is loaded - if (!$this->hasPluginResource('FrontController')) { - $this->registerPluginResource('FrontController'); - } - - // ZF-6545: prevent recursive registration of modules - if ($this->hasPluginResource('modules')) { - $this->unregisterPluginResource('modules'); - } - } - - /** - * Ensure resource loader is loaded - * - * @return void - */ - public function initResourceLoader() - { - $this->getResourceLoader(); - } - - /** - * Get default application namespace - * - * Proxies to {@link getModuleName()}, and returns the current module - * name - * - * @return string - */ - public function getAppNamespace() - { - return $this->getModuleName(); - } - - /** - * Retrieve module name - * - * @return string - */ - public function getModuleName() - { - if (empty($this->_moduleName)) { - $class = get_class($this); - if (preg_match('/^([a-z][a-z0-9]*)_/i', $class, $matches)) { - $prefix = $matches[1]; - } else { - $prefix = $class; - } - $this->_moduleName = $prefix; - } - return $this->_moduleName; - } -} diff --git a/lib/Zend/Application/Resource/Cachemanager.php b/lib/Zend/Application/Resource/Cachemanager.php deleted file mode 100644 index aa1bdc308d2..00000000000 --- a/lib/Zend/Application/Resource/Cachemanager.php +++ /dev/null @@ -1,82 +0,0 @@ -getCacheManager(); - } - - /** - * Retrieve Zend_Cache_Manager instance - * - * @return Zend_Cache_Manager - */ - public function getCacheManager() - { - if (null === $this->_manager) { - $this->_manager = new Zend_Cache_Manager; - - $options = $this->getOptions(); - foreach ($options as $key => $value) { - // Logger - if (isset($value['frontend']['options']['logger'])) { - $logger = $value['frontend']['options']['logger']; - if (is_array($logger)) { - $value['frontend']['options']['logger'] = Zend_Log::factory($logger); - } - } - - // Cache templates - if ($this->_manager->hasCacheTemplate($key)) { - $this->_manager->setTemplateOptions($key, $value); - } else { - $this->_manager->setCacheTemplate($key, $value); - } - } - } - - return $this->_manager; - } -} diff --git a/lib/Zend/Application/Resource/Db.php b/lib/Zend/Application/Resource/Db.php deleted file mode 100644 index 2747368758e..00000000000 --- a/lib/Zend/Application/Resource/Db.php +++ /dev/null @@ -1,198 +0,0 @@ -_adapter = $adapter; - return $this; - } - - /** - * Adapter type to use - * - * @return string - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Set the adapter params - * - * @param array $params - * @return Zend_Application_Resource_Db - */ - public function setParams(array $params) - { - $this->_params = $params; - return $this; - } - - /** - * Adapter parameters - * - * @return array - */ - public function getParams() - { - return $this->_params; - } - - /** - * Set whether to use this as default table adapter - * - * @param bool $isDefaultTableAdapter - * @return Zend_Application_Resource_Db - */ - public function setIsDefaultTableAdapter($isDefaultTableAdapter) - { - $this->_isDefaultTableAdapter = $isDefaultTableAdapter; - return $this; - } - - /** - * Is this adapter the default table adapter? - * - * @return bool - */ - public function isDefaultTableAdapter() - { - return $this->_isDefaultTableAdapter; - } - - /** - * Retrieve initialized DB connection - * - * @return null|Zend_Db_Adapter_Abstract - */ - public function getDbAdapter() - { - if ((null === $this->_db) - && (null !== ($adapter = $this->getAdapter())) - ) { - $this->_db = Zend_Db::factory($adapter, $this->getParams()); - - if ($this->_db instanceof Zend_Db_Adapter_Abstract - && $this->isDefaultTableAdapter() - ) { - Zend_Db_Table::setDefaultAdapter($this->_db); - } - } - return $this->_db; - } - - /** - * Defined by Zend_Application_Resource_Resource - * - * @return Zend_Db_Adapter_Abstract|null - */ - public function init() - { - if (null !== ($db = $this->getDbAdapter())) { - return $db; - } - - return null; - } - - /** - * Set the default metadata cache - * - * @param string|Zend_Cache_Core $cache - * @return Zend_Application_Resource_Db - */ - public function setDefaultMetadataCache($cache) - { - $metadataCache = null; - - if (is_string($cache)) { - $bootstrap = $this->getBootstrap(); - if ($bootstrap instanceof Zend_Application_Bootstrap_ResourceBootstrapper - && $bootstrap->hasPluginResource('CacheManager') - ) { - $cacheManager = $bootstrap->bootstrap('CacheManager') - ->getResource('CacheManager'); - if (null !== $cacheManager && $cacheManager->hasCache($cache)) { - $metadataCache = $cacheManager->getCache($cache); - } - } - } else if ($cache instanceof Zend_Cache_Core) { - $metadataCache = $cache; - } - - if ($metadataCache instanceof Zend_Cache_Core) { - Zend_Db_Table::setDefaultMetadataCache($metadataCache); - } - - return $this; - } -} diff --git a/lib/Zend/Application/Resource/Dojo.php b/lib/Zend/Application/Resource/Dojo.php deleted file mode 100644 index b5437550c50..00000000000 --- a/lib/Zend/Application/Resource/Dojo.php +++ /dev/null @@ -1,76 +0,0 @@ -getDojo(); - } - - /** - * Retrieve Dojo View Helper - * - * @return Zend_Dojo_View_Dojo_Container - */ - public function getDojo() - { - if (null === $this->_dojo) { - $this->getBootstrap()->bootstrap('view'); - $view = $this->getBootstrap()->view; - - Zend_Dojo::enableView($view); - $view->dojo()->setOptions($this->getOptions()); - - $this->_dojo = $view->dojo(); - } - - return $this->_dojo; - } -} diff --git a/lib/Zend/Application/Resource/Exception.php b/lib/Zend/Application/Resource/Exception.php deleted file mode 100644 index 0a57c78fd49..00000000000 --- a/lib/Zend/Application/Resource/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ -getFrontController(); - - foreach ($this->getOptions() as $key => $value) { - switch (strtolower($key)) { - case 'controllerdirectory': - if (is_string($value)) { - $front->setControllerDirectory($value); - } elseif (is_array($value)) { - foreach ($value as $module => $directory) { - $front->addControllerDirectory($directory, $module); - } - } - break; - - case 'modulecontrollerdirectoryname': - $front->setModuleControllerDirectoryName($value); - break; - - case 'moduledirectory': - if (is_string($value)) { - $front->addModuleDirectory($value); - } elseif (is_array($value)) { - foreach ($value as $moduleDir) { - $front->addModuleDirectory($moduleDir); - } - } - break; - - case 'defaultcontrollername': - $front->setDefaultControllerName($value); - break; - - case 'defaultaction': - $front->setDefaultAction($value); - break; - - case 'defaultmodule': - $front->setDefaultModule($value); - break; - - case 'baseurl': - if (!empty($value)) { - $front->setBaseUrl($value); - } - break; - - case 'params': - $front->setParams($value); - break; - - case 'plugins': - foreach ((array) $value as $pluginClass) { - $stackIndex = null; - if (is_array($pluginClass)) { - $pluginClass = array_change_key_case($pluginClass, CASE_LOWER); - if (isset($pluginClass['class'])) { - if (isset($pluginClass['stackindex'])) { - $stackIndex = $pluginClass['stackindex']; - } - - $pluginClass = $pluginClass['class']; - } - } - - $plugin = new $pluginClass(); - $front->registerPlugin($plugin, $stackIndex); - } - break; - - case 'returnresponse': - $front->returnResponse((bool) $value); - break; - - case 'throwexceptions': - $front->throwExceptions((bool) $value); - break; - - case 'actionhelperpaths': - if (is_array($value)) { - foreach ($value as $helperPrefix => $helperPath) { - Zend_Controller_Action_HelperBroker::addPath($helperPath, $helperPrefix); - } - } - break; - - case 'dispatcher': - if (!isset($value['class'])) { - #require_once 'Zend/Application/Exception.php'; - throw new Zend_Application_Exception('You must specify both '); - } - if (!isset($value['params'])) { - $value['params'] = array(); - } - - $dispatchClass = $value['class']; - if (!class_exists($dispatchClass)) { - #require_once 'Zend/Application/Exception.php'; - throw new Zend_Application_Exception('Dispatcher class not found!'); - } - $front->setDispatcher(new $dispatchClass((array)$value['params'])); - break; - default: - $front->setParam($key, $value); - break; - } - } - - if (null !== ($bootstrap = $this->getBootstrap())) { - $this->getBootstrap()->frontController = $front; - } - - return $front; - } - - /** - * Retrieve front controller instance - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - if (null === $this->_front) { - $this->_front = Zend_Controller_Front::getInstance(); - } - return $this->_front; - } -} diff --git a/lib/Zend/Application/Resource/Layout.php b/lib/Zend/Application/Resource/Layout.php deleted file mode 100644 index a19b2913f28..00000000000 --- a/lib/Zend/Application/Resource/Layout.php +++ /dev/null @@ -1,70 +0,0 @@ -getBootstrap()->bootstrap('FrontController'); - return $this->getLayout(); - } - - /** - * Retrieve layout object - * - * @return Zend_Layout - */ - public function getLayout() - { - if (null === $this->_layout) { - $this->_layout = Zend_Layout::startMvc($this->getOptions()); - } - return $this->_layout; - } -} diff --git a/lib/Zend/Application/Resource/Locale.php b/lib/Zend/Application/Resource/Locale.php deleted file mode 100644 index 0e06c2ef4f3..00000000000 --- a/lib/Zend/Application/Resource/Locale.php +++ /dev/null @@ -1,117 +0,0 @@ -getLocale(); - } - - /** - * Retrieve locale object - * - * @return Zend_Locale - */ - public function getLocale() - { - if (null === $this->_locale) { - $options = $this->getOptions(); - - if (!isset($options['default'])) { - $this->_locale = new Zend_Locale(); - } elseif (!isset($options['force']) - || (bool)$options['force'] == false - ) { - // Don't force any locale, just go for auto detection - Zend_Locale::setDefault($options['default']); - $this->_locale = new Zend_Locale(); - } else { - $this->_locale = new Zend_Locale($options['default']); - } - - $key = (isset($options['registry_key']) && !is_numeric($options['registry_key'])) - ? $options['registry_key'] - : self::DEFAULT_REGISTRY_KEY; - Zend_Registry::set($key, $this->_locale); - } - - return $this->_locale; - } - - /** - * Set the cache - * - * @param string|Zend_Cache_Core $cache - * @return Zend_Application_Resource_Locale - */ - public function setCache($cache) - { - if (is_string($cache)) { - $bootstrap = $this->getBootstrap(); - if ($bootstrap instanceof Zend_Application_Bootstrap_ResourceBootstrapper - && $bootstrap->hasPluginResource('CacheManager') - ) { - $cacheManager = $bootstrap->bootstrap('CacheManager') - ->getResource('CacheManager'); - if (null !== $cacheManager && $cacheManager->hasCache($cache)) { - $cache = $cacheManager->getCache($cache); - } - } - } - - if ($cache instanceof Zend_Cache_Core) { - Zend_Locale::setCache($cache); - } - - return $this; - } -} diff --git a/lib/Zend/Application/Resource/Log.php b/lib/Zend/Application/Resource/Log.php deleted file mode 100644 index bc932ac0bb1..00000000000 --- a/lib/Zend/Application/Resource/Log.php +++ /dev/null @@ -1,83 +0,0 @@ -getLog(); - } - - /** - * Attach logger - * - * @param Zend_Log $log - * @return Zend_Application_Resource_Log - */ - public function setLog(Zend_Log $log) - { - $this->_log = $log; - return $this; - } - - /** - * Retrieve logger object - * - * @return Zend_Log - */ - public function getLog() - { - if (null === $this->_log) { - $options = $this->getOptions(); - $log = Zend_Log::factory($options); - $this->setLog($log); - } - return $this->_log; - } -} diff --git a/lib/Zend/Application/Resource/Mail.php b/lib/Zend/Application/Resource/Mail.php deleted file mode 100644 index 09d02ae5c1c..00000000000 --- a/lib/Zend/Application/Resource/Mail.php +++ /dev/null @@ -1,151 +0,0 @@ -getMail(); - } - - /** - * - * @return Zend_Mail_Transport_Abstract|null - */ - public function getMail() - { - if (null === $this->_transport) { - $options = $this->getOptions(); - foreach ($options as $key => $option) { - $options[strtolower($key)] = $option; - } - $this->setOptions($options); - - if (isset($options['transport']) - && !is_numeric($options['transport']) - ) { - $this->_transport = $this->_setupTransport($options['transport']); - if (!isset($options['transport']['register']) - || $options['transport']['register'] == '1' - || (isset($options['transport']['register']) - && !is_numeric($options['transport']['register']) - && (bool)$options['transport']['register'] == true) - ) { - Zend_Mail::setDefaultTransport($this->_transport); - } - } - - $this->_setDefaults('from'); - $this->_setDefaults('replyTo'); - } - - return $this->_transport; - } - - protected function _setDefaults($type) - { - $key = strtolower('default' . $type); - $options = $this->getOptions(); - - if (isset($options[$key]['email']) - && !is_numeric($options[$key]['email']) - ) { - $method = array('Zend_Mail', 'setDefault' . ucfirst($type)); - if (isset($options[$key]['name']) - && !is_numeric( - $options[$key]['name'] - ) - ) { - call_user_func( - $method, $options[$key]['email'], $options[$key]['name'] - ); - } else { - call_user_func($method, $options[$key]['email']); - } - } - } - - protected function _setupTransport($options) - { - if (!isset($options['type'])) { - $options['type'] = 'sendmail'; - } - - $transportName = $options['type']; - if (!Zend_Loader_Autoloader::autoload($transportName)) { - $transportName = ucfirst(strtolower($transportName)); - - if (!Zend_Loader_Autoloader::autoload($transportName)) { - $transportName = 'Zend_Mail_Transport_' . $transportName; - if (!Zend_Loader_Autoloader::autoload($transportName)) { - throw new Zend_Application_Resource_Exception( - "Specified Mail Transport '{$transportName}'" - . 'could not be found' - ); - } - } - } - - unset($options['type']); - unset($options['register']); //@see ZF-11022 - - switch($transportName) { - case 'Zend_Mail_Transport_Smtp': - if (!isset($options['host'])) { - throw new Zend_Application_Resource_Exception( - 'A host is necessary for smtp transport,' - . ' but none was given' - ); - } - - $transport = new $transportName($options['host'], $options); - break; - case 'Zend_Mail_Transport_Sendmail': - default: - $transport = new $transportName($options); - break; - } - - return $transport; - } -} diff --git a/lib/Zend/Application/Resource/Modules.php b/lib/Zend/Application/Resource/Modules.php deleted file mode 100644 index a5c26481957..00000000000 --- a/lib/Zend/Application/Resource/Modules.php +++ /dev/null @@ -1,158 +0,0 @@ -_bootstraps = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); - parent::__construct($options); - } - - /** - * Initialize modules - * - * @return array - * @throws Zend_Application_Resource_Exception When bootstrap class was not found - */ - public function init() - { - $bootstraps = array(); - $bootstrap = $this->getBootstrap(); - $bootstrap->bootstrap('FrontController'); - $front = $bootstrap->getResource('FrontController'); - - $modules = $front->getControllerDirectory(); - $default = $front->getDefaultModule(); - $curBootstrapClass = get_class($bootstrap); - foreach ($modules as $module => $moduleDirectory) { - $bootstrapClass = $this->_formatModuleName($module) . '_Bootstrap'; - if (!class_exists($bootstrapClass, false)) { - $bootstrapPath = dirname($moduleDirectory) . '/Bootstrap.php'; - if (file_exists($bootstrapPath)) { - $eMsgTpl = 'Bootstrap file found for module "%s" but bootstrap class "%s" not found'; - include_once $bootstrapPath; - if (($default != $module) - && !class_exists($bootstrapClass, false) - ) { - throw new Zend_Application_Resource_Exception( - sprintf( - $eMsgTpl, $module, $bootstrapClass - ) - ); - } elseif ($default == $module) { - if (!class_exists($bootstrapClass, false)) { - $bootstrapClass = 'Bootstrap'; - if (!class_exists($bootstrapClass, false)) { - throw new Zend_Application_Resource_Exception( - sprintf( - $eMsgTpl, $module, $bootstrapClass - ) - ); - } - } - } - } else { - continue; - } - } - - if ($bootstrapClass == $curBootstrapClass) { - // If the found bootstrap class matches the one calling this - // resource, don't re-execute. - continue; - } - - $bootstraps[$module] = $bootstrapClass; - } - - return $this->_bootstraps = $this->bootstrapBootstraps($bootstraps); - } - - /* - * Bootstraps the bootstraps found. Allows for easy extension. - * @param array $bootstraps Array containing the bootstraps to instantiate - */ - protected function bootstrapBootstraps($bootstraps) - { - $bootstrap = $this->getBootstrap(); - $out = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); - - foreach ($bootstraps as $module => $bootstrapClass) { - $moduleBootstrap = new $bootstrapClass($bootstrap); - $moduleBootstrap->bootstrap(); - $out[$module] = $moduleBootstrap; - } - - return $out; - } - - /** - * Get bootstraps that have been run - * - * @return ArrayObject - */ - public function getExecutedBootstraps() - { - return $this->_bootstraps; - } - - /** - * Format a module name to the module class prefix - * - * @param string $name - * @return string - */ - protected function _formatModuleName($name) - { - $name = strtolower($name); - $name = str_replace(array('-', '.'), ' ', $name); - $name = ucwords($name); - $name = str_replace(' ', '', $name); - return $name; - } -} diff --git a/lib/Zend/Application/Resource/Multidb.php b/lib/Zend/Application/Resource/Multidb.php deleted file mode 100644 index 71871102dc2..00000000000 --- a/lib/Zend/Application/Resource/Multidb.php +++ /dev/null @@ -1,210 +0,0 @@ - - * resources.multidb.defaultMetadataCache = "database" - * - * resources.multidb.db1.adapter = "pdo_mysql" - * resources.multidb.db1.host = "localhost" - * resources.multidb.db1.username = "webuser" - * resources.multidb.db1.password = "XXXX" - * resources.multidb.db1.dbname = "db1" - * resources.multidb.db1.default = true - * - * resources.multidb.db2.adapter = "pdo_pgsql" - * resources.multidb.db2.host = "example.com" - * resources.multidb.db2.username = "dba" - * resources.multidb.db2.password = "notthatpublic" - * resources.multidb.db2.dbname = "db2" - * - * - * @category Zend - * @package Zend_Application - * @subpackage Resource - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Application_Resource_Multidb extends Zend_Application_Resource_ResourceAbstract -{ - /** - * Associative array containing all configured db's - * - * @var array - */ - protected $_dbs = array(); - - /** - * An instance of the default db, if set - * - * @var null|Zend_Db_Adapter_Abstract - */ - protected $_defaultDb; - - /** - * Initialize the Database Connections (instances of Zend_Db_Table_Abstract) - * - * @return Zend_Application_Resource_Multidb - */ - public function init() - { - $options = $this->getOptions(); - - if (isset($options['defaultMetadataCache'])) { - $this->_setDefaultMetadataCache($options['defaultMetadataCache']); - unset($options['defaultMetadataCache']); - } - - foreach ($options as $id => $params) { - $adapter = $params['adapter']; - $default = (int) ( - isset($params['isDefaultTableAdapter']) && $params['isDefaultTableAdapter'] - || isset($params['default']) && $params['default'] - ); - unset( - $params['adapter'], - $params['default'], - $params['isDefaultTableAdapter'] - ); - - $this->_dbs[$id] = Zend_Db::factory($adapter, $params); - - if ($default) { - $this->_setDefault($this->_dbs[$id]); - } - } - - return $this; - } - - /** - * Determine if the given db(identifier) is the default db. - * - * @param string|Zend_Db_Adapter_Abstract $db The db to determine whether it's set as default - * @return boolean True if the given parameter is configured as default. False otherwise - */ - public function isDefault($db) - { - if (!$db instanceof Zend_Db_Adapter_Abstract) { - $db = $this->getDb($db); - } - - return $db === $this->_defaultDb; - } - - /** - * Retrieve the specified database connection - * - * @param null|string|Zend_Db_Adapter_Abstract $db The adapter to retrieve. - * Null to retrieve the default connection - * @return Zend_Db_Adapter_Abstract - * @throws Zend_Application_Resource_Exception if the given parameter could not be found - */ - public function getDb($db = null) - { - if ($db === null) { - return $this->getDefaultDb(); - } - - if (isset($this->_dbs[$db])) { - return $this->_dbs[$db]; - } - - throw new Zend_Application_Resource_Exception( - 'A DB adapter was tried to retrieve, but was not configured' - ); - } - - /** - * Get the default db connection - * - * @param boolean $justPickOne If true, a random (the first one in the stack) - * connection is returned if no default was set. - * If false, null is returned if no default was set. - * @return null|Zend_Db_Adapter_Abstract - */ - public function getDefaultDb($justPickOne = true) - { - if ($this->_defaultDb !== null) { - return $this->_defaultDb; - } - - if ($justPickOne) { - return reset($this->_dbs); // Return first db in db pool - } - - return null; - } - - /** - * Set the default db adapter - * - * @var Zend_Db_Adapter_Abstract $adapter Adapter to set as default - */ - protected function _setDefault(Zend_Db_Adapter_Abstract $adapter) - { - Zend_Db_Table::setDefaultAdapter($adapter); - $this->_defaultDb = $adapter; - } - - /** - * Set the default metadata cache - * - * @param string|Zend_Cache_Core $cache - * @return Zend_Application_Resource_Multidb - */ - protected function _setDefaultMetadataCache($cache) - { - $metadataCache = null; - - if (is_string($cache)) { - $bootstrap = $this->getBootstrap(); - if ($bootstrap instanceof Zend_Application_Bootstrap_ResourceBootstrapper && - $bootstrap->hasPluginResource('CacheManager') - ) { - $cacheManager = $bootstrap->bootstrap('CacheManager') - ->getResource('CacheManager'); - if (null !== $cacheManager && $cacheManager->hasCache($cache)) { - $metadataCache = $cacheManager->getCache($cache); - } - } - } else if ($cache instanceof Zend_Cache_Core) { - $metadataCache = $cache; - } - - if ($metadataCache instanceof Zend_Cache_Core) { - Zend_Db_Table::setDefaultMetadataCache($metadataCache); - } - - return $this; - } -} diff --git a/lib/Zend/Application/Resource/Navigation.php b/lib/Zend/Application/Resource/Navigation.php deleted file mode 100644 index d6042ef6469..00000000000 --- a/lib/Zend/Application/Resource/Navigation.php +++ /dev/null @@ -1,131 +0,0 @@ -_container) { - $options = $this->getOptions(); - - if (isset($options['defaultPageType'])) { - Zend_Navigation_Page::setDefaultPageType( - $options['defaultPageType'] - ); - } - - $pages = isset($options['pages']) ? $options['pages'] : array(); - $this->_container = new Zend_Navigation($pages); - } - - $this->store(); - return $this->_container; - } - - /** - * Stores navigation container in registry or Navigation view helper - * - * @return void - */ - public function store() - { - $options = $this->getOptions(); - if (isset($options['storage']['registry']) && - $options['storage']['registry'] == true) { - $this->_storeRegistry(); - } else { - $this->_storeHelper(); - } - } - - /** - * Stores navigation container in the registry - * - * @return void - */ - protected function _storeRegistry() - { - $options = $this->getOptions(); - // see ZF-7461 - if (isset($options['storage']['registry']['key']) - && !is_numeric($options['storage']['registry']['key']) - ) { - $key = $options['storage']['registry']['key']; - } else { - $key = self::DEFAULT_REGISTRY_KEY; - } - - Zend_Registry::set($key, $this->getContainer()); - } - - /** - * Stores navigation container in the Navigation helper - * - * @return void - */ - protected function _storeHelper() - { - $this->getBootstrap()->bootstrap('view'); - $view = $this->getBootstrap()->view; - $view->getHelper('navigation')->navigation($this->getContainer()); - } - - /** - * Returns navigation container - * - * @return Zend_Navigation - */ - public function getContainer() - { - return $this->_container; - } -} diff --git a/lib/Zend/Application/Resource/Resource.php b/lib/Zend/Application/Resource/Resource.php deleted file mode 100644 index 7c736756603..00000000000 --- a/lib/Zend/Application/Resource/Resource.php +++ /dev/null @@ -1,79 +0,0 @@ -setOptions($options); - } else if ($options instanceof Zend_Config) { - $this->setOptions($options->toArray()); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for resource - * @return Zend_Application_Resource_ResourceAbstract - */ - public function setOptions(array $options) - { - if (array_key_exists('bootstrap', $options)) { - $this->setBootstrap($options['bootstrap']); - unset($options['bootstrap']); - } - - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . strtolower($key); - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - $this->_options = $this->mergeOptions($this->_options, $options); - - return $this; - } - - /** - * Retrieve resource options - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Merge options recursively - * - * @param array $array1 - * @param mixed $array2 - * @return array - */ - public function mergeOptions(array $array1, $array2 = null) - { - if (is_array($array2)) { - foreach ($array2 as $key => $val) { - if (is_array($array2[$key])) { - $array1[$key] = (array_key_exists($key, $array1) && is_array($array1[$key])) - ? $this->mergeOptions($array1[$key], $array2[$key]) - : $array2[$key]; - } else { - $array1[$key] = $val; - } - } - } - return $array1; - } - - /** - * Set the bootstrap to which the resource is attached - * - * @param Zend_Application_Bootstrap_Bootstrapper $bootstrap - * @return Zend_Application_Resource_Resource - */ - public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap) - { - $this->_bootstrap = $bootstrap; - return $this; - } - - /** - * Retrieve the bootstrap to which the resource is attached - * - * @return null|Zend_Application_Bootstrap_Bootstrapper - */ - public function getBootstrap() - { - return $this->_bootstrap; - } -} diff --git a/lib/Zend/Application/Resource/Router.php b/lib/Zend/Application/Resource/Router.php deleted file mode 100644 index 9b2066d1fd6..00000000000 --- a/lib/Zend/Application/Resource/Router.php +++ /dev/null @@ -1,87 +0,0 @@ -getRouter(); - } - - /** - * Retrieve router object - * - * @return Zend_Controller_Router_Rewrite - */ - public function getRouter() - { - if (null === $this->_router) { - $bootstrap = $this->getBootstrap(); - $bootstrap->bootstrap('FrontController'); - $this->_router = $bootstrap->getContainer()->frontcontroller->getRouter(); - - $options = $this->getOptions(); - if (!isset($options['routes'])) { - $options['routes'] = array(); - } - - if (isset($options['chainNameSeparator'])) { - $this->_router->setChainNameSeparator($options['chainNameSeparator']); - } - - if (isset($options['useRequestParametersAsGlobal'])) { - $this->_router->useRequestParametersAsGlobal($options['useRequestParametersAsGlobal']); - } - - $this->_router->addConfig(new Zend_Config($options['routes'])); - } - - return $this->_router; - } -} diff --git a/lib/Zend/Application/Resource/Session.php b/lib/Zend/Application/Resource/Session.php deleted file mode 100644 index ac9b54e6b9b..00000000000 --- a/lib/Zend/Application/Resource/Session.php +++ /dev/null @@ -1,119 +0,0 @@ -_saveHandler = $saveHandler; - return $this; - } - - /** - * Get session save handler - * - * @return Zend_Session_SaveHandler_Interface - * @throws Zend_Application_Resource_Exception - */ - public function getSaveHandler() - { - if (!$this->_saveHandler instanceof Zend_Session_SaveHandler_Interface) { - if (is_array($this->_saveHandler)) { - if (!array_key_exists('class', $this->_saveHandler)) { - throw new Zend_Application_Resource_Exception('Session save handler class not provided in options'); - } - $options = array(); - if (array_key_exists('options', $this->_saveHandler)) { - $options = $this->_saveHandler['options']; - } - $this->_saveHandler = $this->_saveHandler['class']; - $this->_saveHandler = new $this->_saveHandler($options); - } elseif (is_string($this->_saveHandler)) { - $this->_saveHandler = new $this->_saveHandler(); - } - - if (!$this->_saveHandler instanceof Zend_Session_SaveHandler_Interface) { - throw new Zend_Application_Resource_Exception('Invalid session save handler'); - } - } - return $this->_saveHandler; - } - - /** - * @return bool - */ - protected function _hasSaveHandler() - { - return ($this->_saveHandler !== null); - } - - /** - * Defined by Zend_Application_Resource_Resource - * - * @return void - */ - public function init() - { - $options = array_change_key_case($this->getOptions(), CASE_LOWER); - if (isset($options['savehandler'])) { - unset($options['savehandler']); - } - - if (count($options) > 0) { - Zend_Session::setOptions($options); - } - - if ($this->_hasSaveHandler()) { - Zend_Session::setSaveHandler($this->getSaveHandler()); - } - } -} diff --git a/lib/Zend/Application/Resource/Translate.php b/lib/Zend/Application/Resource/Translate.php deleted file mode 100644 index 02fdd65df42..00000000000 --- a/lib/Zend/Application/Resource/Translate.php +++ /dev/null @@ -1,142 +0,0 @@ -getTranslate(); - } - - /** - * Retrieve translate object - * - * @return Zend_Translate - * @throws Zend_Application_Resource_Exception if registry key was used - * already but is no instance of Zend_Translate - */ - public function getTranslate() - { - if (null === $this->_translate) { - $options = $this->getOptions(); - - if (!isset($options['content']) && !isset($options['data'])) { - #require_once 'Zend/Application/Resource/Exception.php'; - throw new Zend_Application_Resource_Exception('No translation source data provided.'); - } else if (array_key_exists('content', $options) && array_key_exists('data', $options)) { - #require_once 'Zend/Application/Resource/Exception.php'; - throw new Zend_Application_Resource_Exception( - 'Conflict on translation source data: choose only one key between content and data.' - ); - } - - if (empty($options['adapter'])) { - $options['adapter'] = Zend_Translate::AN_ARRAY; - } - - if (!empty($options['data'])) { - $options['content'] = $options['data']; - unset($options['data']); - } - - if (isset($options['log'])) { - if (is_array($options['log'])) { - $options['log'] = Zend_Log::factory($options['log']); - } - } - - if (isset($options['options'])) { - foreach ($options['options'] as $key => $value) { - $options[$key] = $value; - } - } - - if (!empty($options['cache']) && is_string($options['cache'])) { - $bootstrap = $this->getBootstrap(); - if ($bootstrap instanceof Zend_Application_Bootstrap_ResourceBootstrapper && - $bootstrap->hasPluginResource('CacheManager') - ) { - $cacheManager = $bootstrap->bootstrap('CacheManager') - ->getResource('CacheManager'); - if (null !== $cacheManager && - $cacheManager->hasCache($options['cache']) - ) { - $options['cache'] = $cacheManager->getCache($options['cache']); - } - } - } - - $key = (isset($options['registry_key']) && !is_numeric($options['registry_key'])) - ? $options['registry_key'] - : self::DEFAULT_REGISTRY_KEY; - unset($options['registry_key']); - - if (Zend_Registry::isRegistered($key)) { - $translate = Zend_Registry::get($key); - if (!$translate instanceof Zend_Translate) { - #require_once 'Zend/Application/Resource/Exception.php'; - throw new Zend_Application_Resource_Exception( - $key - . ' already registered in registry but is ' - . 'no instance of Zend_Translate' - ); - } - - $translate->addTranslation($options); - $this->_translate = $translate; - } else { - $this->_translate = new Zend_Translate($options); - Zend_Registry::set($key, $this->_translate); - } - } - - return $this->_translate; - } -} diff --git a/lib/Zend/Application/Resource/Useragent.php b/lib/Zend/Application/Resource/Useragent.php deleted file mode 100644 index 83945cd4f21..00000000000 --- a/lib/Zend/Application/Resource/Useragent.php +++ /dev/null @@ -1,72 +0,0 @@ -getUserAgent(); - - // Optionally seed the UserAgent view helper - $bootstrap = $this->getBootstrap(); - if ($bootstrap->hasResource('view') || $bootstrap->hasPluginResource('view')) { - $bootstrap->bootstrap('view'); - $view = $bootstrap->getResource('view'); - if (null !== $view) { - $view->userAgent($userAgent); - } - } - - return $userAgent; - } - - /** - * Get UserAgent instance - * - * @return Zend_Http_UserAgent - */ - public function getUserAgent() - { - if (null === $this->_userAgent) { - $options = $this->getOptions(); - $this->_userAgent = new Zend_Http_UserAgent($options); - } - - return $this->_userAgent; - } -} diff --git a/lib/Zend/Application/Resource/View.php b/lib/Zend/Application/Resource/View.php deleted file mode 100644 index 442bfc5c0c3..00000000000 --- a/lib/Zend/Application/Resource/View.php +++ /dev/null @@ -1,86 +0,0 @@ -getView(); - - $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); - $viewRenderer->setView($view); - return $view; - } - - /** - * Retrieve view object - * - * @return Zend_View - */ - public function getView() - { - if (null === $this->_view) { - $options = $this->getOptions(); - $this->_view = new Zend_View($options); - - if (isset($options['doctype'])) { - $this->_view->doctype()->setDoctype(strtoupper($options['doctype'])); - if (isset($options['charset']) && $this->_view->doctype()->isHtml5()) { - $this->_view->headMeta()->setCharset($options['charset']); - } - } - if (isset($options['contentType'])) { - $this->_view->headMeta()->appendHttpEquiv('Content-Type', $options['contentType']); - } - if (isset($options['assign']) && is_array($options['assign'])) { - $this->_view->assign($options['assign']); - } - } - return $this->_view; - } -} diff --git a/lib/Zend/Auth.php b/lib/Zend/Auth.php deleted file mode 100644 index 434d944fc54..00000000000 --- a/lib/Zend/Auth.php +++ /dev/null @@ -1,169 +0,0 @@ -_storage) { - /** - * @see Zend_Auth_Storage_Session - */ - #require_once 'Zend/Auth/Storage/Session.php'; - $this->setStorage(new Zend_Auth_Storage_Session()); - } - - return $this->_storage; - } - - /** - * Sets the persistent storage handler - * - * @param Zend_Auth_Storage_Interface $storage - * @return Zend_Auth Provides a fluent interface - */ - public function setStorage(Zend_Auth_Storage_Interface $storage) - { - $this->_storage = $storage; - return $this; - } - - /** - * Authenticates against the supplied adapter - * - * @param Zend_Auth_Adapter_Interface $adapter - * @return Zend_Auth_Result - */ - public function authenticate(Zend_Auth_Adapter_Interface $adapter) - { - $result = $adapter->authenticate(); - - /** - * ZF-7546 - prevent multiple succesive calls from storing inconsistent results - * Ensure storage has clean state - */ - if ($this->hasIdentity()) { - $this->clearIdentity(); - } - - if ($result->isValid()) { - $this->getStorage()->write($result->getIdentity()); - } - - return $result; - } - - /** - * Returns true if and only if an identity is available from storage - * - * @return boolean - */ - public function hasIdentity() - { - return !$this->getStorage()->isEmpty(); - } - - /** - * Returns the identity from storage or null if no identity is available - * - * @return mixed|null - */ - public function getIdentity() - { - $storage = $this->getStorage(); - - if ($storage->isEmpty()) { - return null; - } - - return $storage->read(); - } - - /** - * Clears the identity from persistent storage - * - * @return void - */ - public function clearIdentity() - { - $this->getStorage()->clear(); - } -} diff --git a/lib/Zend/Auth/Adapter/DbTable.php b/lib/Zend/Auth/Adapter/DbTable.php deleted file mode 100644 index 5022fd5cf8a..00000000000 --- a/lib/Zend/Auth/Adapter/DbTable.php +++ /dev/null @@ -1,560 +0,0 @@ -_setDbAdapter($zendDb); - - if (null !== $tableName) { - $this->setTableName($tableName); - } - - if (null !== $identityColumn) { - $this->setIdentityColumn($identityColumn); - } - - if (null !== $credentialColumn) { - $this->setCredentialColumn($credentialColumn); - } - - if (null !== $credentialTreatment) { - $this->setCredentialTreatment($credentialTreatment); - } - } - - /** - * _setDbAdapter() - set the database adapter to be used for quering - * - * @param Zend_Db_Adapter_Abstract - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Adapter_DbTable - */ - protected function _setDbAdapter(Zend_Db_Adapter_Abstract $zendDb = null) - { - $this->_zendDb = $zendDb; - - /** - * If no adapter is specified, fetch default database adapter. - */ - if(null === $this->_zendDb) { - #require_once 'Zend/Db/Table/Abstract.php'; - $this->_zendDb = Zend_Db_Table_Abstract::getDefaultAdapter(); - if (null === $this->_zendDb) { - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('No database adapter present'); - } - } - - return $this; - } - - /** - * setTableName() - set the table name to be used in the select query - * - * @param string $tableName - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setTableName($tableName) - { - $this->_tableName = $tableName; - return $this; - } - - /** - * setIdentityColumn() - set the column name to be used as the identity column - * - * @param string $identityColumn - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setIdentityColumn($identityColumn) - { - $this->_identityColumn = $identityColumn; - return $this; - } - - /** - * setCredentialColumn() - set the column name to be used as the credential column - * - * @param string $credentialColumn - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setCredentialColumn($credentialColumn) - { - $this->_credentialColumn = $credentialColumn; - return $this; - } - - /** - * setCredentialTreatment() - allows the developer to pass a parameterized string that is - * used to transform or treat the input credential data. - * - * In many cases, passwords and other sensitive data are encrypted, hashed, encoded, - * obscured, or otherwise treated through some function or algorithm. By specifying a - * parameterized treatment string with this method, a developer may apply arbitrary SQL - * upon input credential data. - * - * Examples: - * - * 'PASSWORD(?)' - * 'MD5(?)' - * - * @param string $treatment - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setCredentialTreatment($treatment) - { - $this->_credentialTreatment = $treatment; - return $this; - } - - /** - * setIdentity() - set the value to be used as the identity - * - * @param string $value - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setIdentity($value) - { - $this->_identity = $value; - return $this; - } - - /** - * setCredential() - set the credential value to be used, optionally can specify a treatment - * to be used, should be supplied in parameterized form, such as 'MD5(?)' or 'PASSWORD(?)' - * - * @param string $credential - * @return Zend_Auth_Adapter_DbTable Provides a fluent interface - */ - public function setCredential($credential) - { - $this->_credential = $credential; - return $this; - } - - /** - * setAmbiguityIdentity() - sets a flag for usage of identical identities - * with unique credentials. It accepts integers (0, 1) or boolean (true, - * false) parameters. Default is false. - * - * @param int|bool $flag - * @return Zend_Auth_Adapter_DbTable - */ - public function setAmbiguityIdentity($flag) - { - if (is_integer($flag)) { - $this->_ambiguityIdentity = (1 === $flag ? true : false); - } elseif (is_bool($flag)) { - $this->_ambiguityIdentity = $flag; - } - return $this; - } - /** - * getAmbiguityIdentity() - returns TRUE for usage of multiple identical - * identies with different credentials, FALSE if not used. - * - * @return bool - */ - public function getAmbiguityIdentity() - { - return $this->_ambiguityIdentity; - } - - /** - * getDbSelect() - Return the preauthentication Db Select object for userland select query modification - * - * @return Zend_Db_Select - */ - public function getDbSelect() - { - if ($this->_dbSelect == null) { - $this->_dbSelect = $this->_zendDb->select(); - } - - return $this->_dbSelect; - } - - /** - * getResultRowObject() - Returns the result row as a stdClass object - * - * @param string|array $returnColumns - * @param string|array $omitColumns - * @return stdClass|boolean - */ - public function getResultRowObject($returnColumns = null, $omitColumns = null) - { - if (!$this->_resultRow) { - return false; - } - - $returnObject = new stdClass(); - - if (null !== $returnColumns) { - - $availableColumns = array_keys($this->_resultRow); - foreach ( (array) $returnColumns as $returnColumn) { - if (in_array($returnColumn, $availableColumns)) { - $returnObject->{$returnColumn} = $this->_resultRow[$returnColumn]; - } - } - return $returnObject; - - } elseif (null !== $omitColumns) { - - $omitColumns = (array) $omitColumns; - foreach ($this->_resultRow as $resultColumn => $resultValue) { - if (!in_array($resultColumn, $omitColumns)) { - $returnObject->{$resultColumn} = $resultValue; - } - } - return $returnObject; - - } else { - - foreach ($this->_resultRow as $resultColumn => $resultValue) { - $returnObject->{$resultColumn} = $resultValue; - } - return $returnObject; - - } - } - - /** - * authenticate() - defined by Zend_Auth_Adapter_Interface. This method is called to - * attempt an authentication. Previous to this call, this adapter would have already - * been configured with all necessary information to successfully connect to a database - * table and attempt to find a record matching the provided identity. - * - * @throws Zend_Auth_Adapter_Exception if answering the authentication query is impossible - * @return Zend_Auth_Result - */ - public function authenticate() - { - $this->_authenticateSetup(); - $dbSelect = $this->_authenticateCreateSelect(); - $resultIdentities = $this->_authenticateQuerySelect($dbSelect); - - if ( ($authResult = $this->_authenticateValidateResultSet($resultIdentities)) instanceof Zend_Auth_Result) { - return $authResult; - } - - if (true === $this->getAmbiguityIdentity()) { - $validIdentities = array (); - $zendAuthCredentialMatchColumn = $this->_zendDb->foldCase('zend_auth_credential_match'); - foreach ($resultIdentities as $identity) { - if (1 === (int) $identity[$zendAuthCredentialMatchColumn]) { - $validIdentities[] = $identity; - } - } - $resultIdentities = $validIdentities; - } - - $authResult = $this->_authenticateValidateResult(array_shift($resultIdentities)); - return $authResult; - } - - /** - * _authenticateSetup() - This method abstracts the steps involved with - * making sure that this adapter was indeed setup properly with all - * required pieces of information. - * - * @throws Zend_Auth_Adapter_Exception - in the event that setup was not done properly - * @return true - */ - protected function _authenticateSetup() - { - $exception = null; - - if ($this->_tableName == '') { - $exception = 'A table must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.'; - } elseif ($this->_identityColumn == '') { - $exception = 'An identity column must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.'; - } elseif ($this->_credentialColumn == '') { - $exception = 'A credential column must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.'; - } elseif ($this->_identity == '') { - $exception = 'A value for the identity was not provided prior to authentication with Zend_Auth_Adapter_DbTable.'; - } elseif ($this->_credential === null) { - $exception = 'A credential value was not provided prior to authentication with Zend_Auth_Adapter_DbTable.'; - } - - if (null !== $exception) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception($exception); - } - - $this->_authenticateResultInfo = array( - 'code' => Zend_Auth_Result::FAILURE, - 'identity' => $this->_identity, - 'messages' => array() - ); - - return true; - } - - /** - * _authenticateCreateSelect() - This method creates a Zend_Db_Select object that - * is completely configured to be queried against the database. - * - * @return Zend_Db_Select - */ - protected function _authenticateCreateSelect() - { - // build credential expression - if (empty($this->_credentialTreatment) || (strpos($this->_credentialTreatment, '?') === false)) { - $this->_credentialTreatment = '?'; - } - - $credentialExpression = new Zend_Db_Expr( - '(CASE WHEN ' . - $this->_zendDb->quoteInto( - $this->_zendDb->quoteIdentifier($this->_credentialColumn, true) - . ' = ' . $this->_credentialTreatment, $this->_credential - ) - . ' THEN 1 ELSE 0 END) AS ' - . $this->_zendDb->quoteIdentifier( - $this->_zendDb->foldCase('zend_auth_credential_match') - ) - ); - - // get select - $dbSelect = clone $this->getDbSelect(); - $dbSelect->from($this->_tableName, array('*', $credentialExpression)) - ->where($this->_zendDb->quoteIdentifier($this->_identityColumn, true) . ' = ?', $this->_identity); - - return $dbSelect; - } - - /** - * _authenticateQuerySelect() - This method accepts a Zend_Db_Select object and - * performs a query against the database with that object. - * - * @param Zend_Db_Select $dbSelect - * @throws Zend_Auth_Adapter_Exception - when an invalid select - * object is encountered - * @return array - */ - protected function _authenticateQuerySelect(Zend_Db_Select $dbSelect) - { - try { - if ($this->_zendDb->getFetchMode() != Zend_DB::FETCH_ASSOC) { - $origDbFetchMode = $this->_zendDb->getFetchMode(); - $this->_zendDb->setFetchMode(Zend_DB::FETCH_ASSOC); - } - $resultIdentities = $this->_zendDb->fetchAll($dbSelect); - if (isset($origDbFetchMode)) { - $this->_zendDb->setFetchMode($origDbFetchMode); - unset($origDbFetchMode); - } - } catch (Exception $e) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('The supplied parameters to Zend_Auth_Adapter_DbTable failed to ' - . 'produce a valid sql statement, please check table and column names ' - . 'for validity.', 0, $e); - } - return $resultIdentities; - } - - /** - * _authenticateValidateResultSet() - This method attempts to make - * certain that only one record was returned in the resultset - * - * @param array $resultIdentities - * @return true|Zend_Auth_Result - */ - protected function _authenticateValidateResultSet(array $resultIdentities) - { - - if (count($resultIdentities) < 1) { - $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND; - $this->_authenticateResultInfo['messages'][] = 'A record with the supplied identity could not be found.'; - return $this->_authenticateCreateAuthResult(); - } elseif (count($resultIdentities) > 1 && false === $this->getAmbiguityIdentity()) { - $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS; - $this->_authenticateResultInfo['messages'][] = 'More than one record matches the supplied identity.'; - return $this->_authenticateCreateAuthResult(); - } - - return true; - } - - /** - * _authenticateValidateResult() - This method attempts to validate that - * the record in the resultset is indeed a record that matched the - * identity provided to this adapter. - * - * @param array $resultIdentity - * @return Zend_Auth_Result - */ - protected function _authenticateValidateResult($resultIdentity) - { - $zendAuthCredentialMatchColumn = $this->_zendDb->foldCase('zend_auth_credential_match'); - - if ($resultIdentity[$zendAuthCredentialMatchColumn] != '1') { - $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; - $this->_authenticateResultInfo['messages'][] = 'Supplied credential is invalid.'; - return $this->_authenticateCreateAuthResult(); - } - - unset($resultIdentity[$zendAuthCredentialMatchColumn]); - $this->_resultRow = $resultIdentity; - - $this->_authenticateResultInfo['code'] = Zend_Auth_Result::SUCCESS; - $this->_authenticateResultInfo['messages'][] = 'Authentication successful.'; - return $this->_authenticateCreateAuthResult(); - } - - /** - * _authenticateCreateAuthResult() - Creates a Zend_Auth_Result object from - * the information that has been collected during the authenticate() attempt. - * - * @return Zend_Auth_Result - */ - protected function _authenticateCreateAuthResult() - { - return new Zend_Auth_Result( - $this->_authenticateResultInfo['code'], - $this->_authenticateResultInfo['identity'], - $this->_authenticateResultInfo['messages'] - ); - } - -} diff --git a/lib/Zend/Auth/Adapter/Digest.php b/lib/Zend/Auth/Adapter/Digest.php deleted file mode 100644 index 17d035b068d..00000000000 --- a/lib/Zend/Auth/Adapter/Digest.php +++ /dev/null @@ -1,251 +0,0 @@ -$methodName($$option); - } - } - } - - /** - * Returns the filename option value or null if it has not yet been set - * - * @return string|null - */ - public function getFilename() - { - return $this->_filename; - } - - /** - * Sets the filename option value - * - * @param mixed $filename - * @return Zend_Auth_Adapter_Digest Provides a fluent interface - */ - public function setFilename($filename) - { - $this->_filename = (string) $filename; - return $this; - } - - /** - * Returns the realm option value or null if it has not yet been set - * - * @return string|null - */ - public function getRealm() - { - return $this->_realm; - } - - /** - * Sets the realm option value - * - * @param mixed $realm - * @return Zend_Auth_Adapter_Digest Provides a fluent interface - */ - public function setRealm($realm) - { - $this->_realm = (string) $realm; - return $this; - } - - /** - * Returns the username option value or null if it has not yet been set - * - * @return string|null - */ - public function getUsername() - { - return $this->_username; - } - - /** - * Sets the username option value - * - * @param mixed $username - * @return Zend_Auth_Adapter_Digest Provides a fluent interface - */ - public function setUsername($username) - { - $this->_username = (string) $username; - return $this; - } - - /** - * Returns the password option value or null if it has not yet been set - * - * @return string|null - */ - public function getPassword() - { - return $this->_password; - } - - /** - * Sets the password option value - * - * @param mixed $password - * @return Zend_Auth_Adapter_Digest Provides a fluent interface - */ - public function setPassword($password) - { - $this->_password = (string) $password; - return $this; - } - - /** - * Defined by Zend_Auth_Adapter_Interface - * - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result - */ - public function authenticate() - { - $optionsRequired = array('filename', 'realm', 'username', 'password'); - foreach ($optionsRequired as $optionRequired) { - if (null === $this->{"_$optionRequired"}) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception("Option '$optionRequired' must be set before authentication"); - } - } - - if (false === ($fileHandle = @fopen($this->_filename, 'r'))) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception("Cannot open '$this->_filename' for reading"); - } - - $id = "$this->_username:$this->_realm"; - $idLength = strlen($id); - - $result = array( - 'code' => Zend_Auth_Result::FAILURE, - 'identity' => array( - 'realm' => $this->_realm, - 'username' => $this->_username, - ), - 'messages' => array() - ); - - while ($line = trim(fgets($fileHandle))) { - if (substr($line, 0, $idLength) === $id) { - if ($this->_secureStringCompare(substr($line, -32), md5("$this->_username:$this->_realm:$this->_password"))) { - $result['code'] = Zend_Auth_Result::SUCCESS; - } else { - $result['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; - $result['messages'][] = 'Password incorrect'; - } - return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']); - } - } - - $result['code'] = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND; - $result['messages'][] = "Username '$this->_username' and realm '$this->_realm' combination not found"; - return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']); - } - - /** - * Securely compare two strings for equality while avoided C level memcmp() - * optimisations capable of leaking timing information useful to an attacker - * attempting to iteratively guess the unknown string (e.g. password) being - * compared against. - * - * @param string $a - * @param string $b - * @return bool - */ - protected function _secureStringCompare($a, $b) - { - if (strlen($a) !== strlen($b)) { - return false; - } - $result = 0; - for ($i = 0; $i < strlen($a); $i++) { - $result |= ord($a[$i]) ^ ord($b[$i]); - } - return $result == 0; - } -} diff --git a/lib/Zend/Auth/Adapter/Exception.php b/lib/Zend/Auth/Adapter/Exception.php deleted file mode 100644 index 8f22edc3af8..00000000000 --- a/lib/Zend/Auth/Adapter/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ - 'basic'|'digest'|'basic digest' - * 'realm' => - * 'digest_domains' => Space-delimited list of URIs - * 'nonce_timeout' => - * 'use_opaque' => Whether to send the opaque value in the header - * 'alogrithm' => See $_supportedAlgos. Default: MD5 - * 'proxy_auth' => Whether to do authentication as a Proxy - * @throws Zend_Auth_Adapter_Exception - */ - public function __construct(array $config) - { - if (!extension_loaded('hash')) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception(__CLASS__ . ' requires the \'hash\' extension'); - } - - $this->_request = null; - $this->_response = null; - $this->_ieNoOpaque = false; - - - if (empty($config['accept_schemes'])) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Config key \'accept_schemes\' is required'); - } - - $schemes = explode(' ', $config['accept_schemes']); - $this->_acceptSchemes = array_intersect($schemes, $this->_supportedSchemes); - if (empty($this->_acceptSchemes)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('No supported schemes given in \'accept_schemes\'. Valid values: ' - . implode(', ', $this->_supportedSchemes)); - } - - // Double-quotes are used to delimit the realm string in the HTTP header, - // and colons are field delimiters in the password file. - if (empty($config['realm']) || - !ctype_print($config['realm']) || - strpos($config['realm'], ':') !== false || - strpos($config['realm'], '"') !== false) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Config key \'realm\' is required, and must contain only printable ' - . 'characters, excluding quotation marks and colons'); - } else { - $this->_realm = $config['realm']; - } - - if (in_array('digest', $this->_acceptSchemes)) { - if (empty($config['digest_domains']) || - !ctype_print($config['digest_domains']) || - strpos($config['digest_domains'], '"') !== false) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Config key \'digest_domains\' is required, and must contain ' - . 'only printable characters, excluding quotation marks'); - } else { - $this->_domains = $config['digest_domains']; - } - - if (empty($config['nonce_timeout']) || - !is_numeric($config['nonce_timeout'])) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Config key \'nonce_timeout\' is required, and must be an ' - . 'integer'); - } else { - $this->_nonceTimeout = (int) $config['nonce_timeout']; - } - - // We use the opaque value unless explicitly told not to - if (isset($config['use_opaque']) && false == (bool) $config['use_opaque']) { - $this->_useOpaque = false; - } else { - $this->_useOpaque = true; - } - - if (isset($config['algorithm']) && in_array($config['algorithm'], $this->_supportedAlgos)) { - $this->_algo = $config['algorithm']; - } else { - $this->_algo = 'MD5'; - } - } - - // Don't be a proxy unless explicitly told to do so - if (isset($config['proxy_auth']) && true == (bool) $config['proxy_auth']) { - $this->_imaProxy = true; // I'm a Proxy - } else { - $this->_imaProxy = false; - } - } - - /** - * Setter for the _basicResolver property - * - * @param Zend_Auth_Adapter_Http_Resolver_Interface $resolver - * @return Zend_Auth_Adapter_Http Provides a fluent interface - */ - public function setBasicResolver(Zend_Auth_Adapter_Http_Resolver_Interface $resolver) - { - $this->_basicResolver = $resolver; - - return $this; - } - - /** - * Getter for the _basicResolver property - * - * @return Zend_Auth_Adapter_Http_Resolver_Interface - */ - public function getBasicResolver() - { - return $this->_basicResolver; - } - - /** - * Setter for the _digestResolver property - * - * @param Zend_Auth_Adapter_Http_Resolver_Interface $resolver - * @return Zend_Auth_Adapter_Http Provides a fluent interface - */ - public function setDigestResolver(Zend_Auth_Adapter_Http_Resolver_Interface $resolver) - { - $this->_digestResolver = $resolver; - - return $this; - } - - /** - * Getter for the _digestResolver property - * - * @return Zend_Auth_Adapter_Http_Resolver_Interface - */ - public function getDigestResolver() - { - return $this->_digestResolver; - } - - /** - * Setter for the Request object - * - * @param Zend_Controller_Request_Http $request - * @return Zend_Auth_Adapter_Http Provides a fluent interface - */ - public function setRequest(Zend_Controller_Request_Http $request) - { - $this->_request = $request; - - return $this; - } - - /** - * Getter for the Request object - * - * @return Zend_Controller_Request_Http - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Setter for the Response object - * - * @param Zend_Controller_Response_Http $response - * @return Zend_Auth_Adapter_Http Provides a fluent interface - */ - public function setResponse(Zend_Controller_Response_Http $response) - { - $this->_response = $response; - - return $this; - } - - /** - * Getter for the Response object - * - * @return Zend_Controller_Response_Http - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Authenticate - * - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result - */ - public function authenticate() - { - if (empty($this->_request) || - empty($this->_response)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Request and Response objects must be set before calling ' - . 'authenticate()'); - } - - if ($this->_imaProxy) { - $getHeader = 'Proxy-Authorization'; - } else { - $getHeader = 'Authorization'; - } - - $authHeader = $this->_request->getHeader($getHeader); - if (!$authHeader) { - return $this->_challengeClient(); - } - - list($clientScheme) = explode(' ', $authHeader); - $clientScheme = strtolower($clientScheme); - - // The server can issue multiple challenges, but the client should - // answer with only the selected auth scheme. - if (!in_array($clientScheme, $this->_supportedSchemes)) { - $this->_response->setHttpResponseCode(400); - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE_UNCATEGORIZED, - array(), - array('Client requested an incorrect or unsupported authentication scheme') - ); - } - - // client sent a scheme that is not the one required - if (!in_array($clientScheme, $this->_acceptSchemes)) { - // challenge again the client - return $this->_challengeClient(); - } - - switch ($clientScheme) { - case 'basic': - $result = $this->_basicAuth($authHeader); - break; - case 'digest': - $result = $this->_digestAuth($authHeader); - break; - default: - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Unsupported authentication scheme'); - } - - return $result; - } - - /** - * Challenge Client - * - * Sets a 401 or 407 Unauthorized response code, and creates the - * appropriate Authenticate header(s) to prompt for credentials. - * - * @return Zend_Auth_Result Always returns a non-identity Auth result - */ - protected function _challengeClient() - { - if ($this->_imaProxy) { - $statusCode = 407; - $headerName = 'Proxy-Authenticate'; - } else { - $statusCode = 401; - $headerName = 'WWW-Authenticate'; - } - - $this->_response->setHttpResponseCode($statusCode); - - // Send a challenge in each acceptable authentication scheme - if (in_array('basic', $this->_acceptSchemes)) { - $this->_response->setHeader($headerName, $this->_basicHeader()); - } - if (in_array('digest', $this->_acceptSchemes)) { - $this->_response->setHeader($headerName, $this->_digestHeader()); - } - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, - array(), - array('Invalid or absent credentials; challenging client') - ); - } - - /** - * Basic Header - * - * Generates a Proxy- or WWW-Authenticate header value in the Basic - * authentication scheme. - * - * @return string Authenticate header value - */ - protected function _basicHeader() - { - return 'Basic realm="' . $this->_realm . '"'; - } - - /** - * Digest Header - * - * Generates a Proxy- or WWW-Authenticate header value in the Digest - * authentication scheme. - * - * @return string Authenticate header value - */ - protected function _digestHeader() - { - $wwwauth = 'Digest realm="' . $this->_realm . '", ' - . 'domain="' . $this->_domains . '", ' - . 'nonce="' . $this->_calcNonce() . '", ' - . ($this->_useOpaque ? 'opaque="' . $this->_calcOpaque() . '", ' : '') - . 'algorithm="' . $this->_algo . '", ' - . 'qop="' . implode(',', $this->_supportedQops) . '"'; - - return $wwwauth; - } - - /** - * Basic Authentication - * - * @param string $header Client's Authorization header - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result - */ - protected function _basicAuth($header) - { - if (empty($header)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('The value of the client Authorization header is required'); - } - if (empty($this->_basicResolver)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('A basicResolver object must be set before doing Basic ' - . 'authentication'); - } - - // Decode the Authorization header - $auth = substr($header, strlen('Basic ')); - $auth = base64_decode($auth); - if (!$auth) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Unable to base64_decode Authorization header value'); - } - - // See ZF-1253. Validate the credentials the same way the digest - // implementation does. If invalid credentials are detected, - // re-challenge the client. - if (!ctype_print($auth)) { - return $this->_challengeClient(); - } - // Fix for ZF-1515: Now re-challenges on empty username or password - $creds = array_filter(explode(':', $auth)); - if (count($creds) != 2) { - return $this->_challengeClient(); - } - - $password = $this->_basicResolver->resolve($creds[0], $this->_realm); - if ($password && $this->_secureStringCompare($password, $creds[1])) { - $identity = array('username'=>$creds[0], 'realm'=>$this->_realm); - return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity); - } else { - return $this->_challengeClient(); - } - } - - /** - * Digest Authentication - * - * @param string $header Client's Authorization header - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result Valid auth result only on successful auth - */ - protected function _digestAuth($header) - { - if (empty($header)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('The value of the client Authorization header is required'); - } - if (empty($this->_digestResolver)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('A digestResolver object must be set before doing Digest authentication'); - } - - $data = $this->_parseDigestAuth($header); - if ($data === false) { - $this->_response->setHttpResponseCode(400); - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE_UNCATEGORIZED, - array(), - array('Invalid Authorization header format') - ); - } - - // See ZF-1052. This code was a bit too unforgiving of invalid - // usernames. Now, if the username is bad, we re-challenge the client. - if ('::invalid::' == $data['username']) { - return $this->_challengeClient(); - } - - // Verify that the client sent back the same nonce - if ($this->_calcNonce() != $data['nonce']) { - return $this->_challengeClient(); - } - // The opaque value is also required to match, but of course IE doesn't - // play ball. - if (!$this->_ieNoOpaque && $this->_calcOpaque() != $data['opaque']) { - return $this->_challengeClient(); - } - - // Look up the user's password hash. If not found, deny access. - // This makes no assumptions about how the password hash was - // constructed beyond that it must have been built in such a way as - // to be recreatable with the current settings of this object. - $ha1 = $this->_digestResolver->resolve($data['username'], $data['realm']); - if ($ha1 === false) { - return $this->_challengeClient(); - } - - // If MD5-sess is used, a1 value is made of the user's password - // hash with the server and client nonce appended, separated by - // colons. - if ($this->_algo == 'MD5-sess') { - $ha1 = hash('md5', $ha1 . ':' . $data['nonce'] . ':' . $data['cnonce']); - } - - // Calculate h(a2). The value of this hash depends on the qop - // option selected by the client and the supported hash functions - switch ($data['qop']) { - case 'auth': - $a2 = $this->_request->getMethod() . ':' . $data['uri']; - break; - case 'auth-int': - // Should be REQUEST_METHOD . ':' . uri . ':' . hash(entity-body), - // but this isn't supported yet, so fall through to default case - default: - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Client requested an unsupported qop option'); - } - // Using hash() should make parameterizing the hash algorithm - // easier - $ha2 = hash('md5', $a2); - - - // Calculate the server's version of the request-digest. This must - // match $data['response']. See RFC 2617, section 3.2.2.1 - $message = $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . $ha2; - $digest = hash('md5', $ha1 . ':' . $message); - - // If our digest matches the client's let them in, otherwise return - // a 401 code and exit to prevent access to the protected resource. - if ($this->_secureStringCompare($digest, $data['response'])) { - $identity = array('username'=>$data['username'], 'realm'=>$data['realm']); - return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity); - } else { - return $this->_challengeClient(); - } - } - - /** - * Calculate Nonce - * - * @return string The nonce value - */ - protected function _calcNonce() - { - // Once subtle consequence of this timeout calculation is that it - // actually divides all of time into _nonceTimeout-sized sections, such - // that the value of timeout is the point in time of the next - // approaching "boundary" of a section. This allows the server to - // consistently generate the same timeout (and hence the same nonce - // value) across requests, but only as long as one of those - // "boundaries" is not crossed between requests. If that happens, the - // nonce will change on its own, and effectively log the user out. This - // would be surprising if the user just logged in. - $timeout = ceil(time() / $this->_nonceTimeout) * $this->_nonceTimeout; - - $nonce = hash('md5', $timeout . ':' . $this->_request->getServer('HTTP_USER_AGENT') . ':' . __CLASS__); - return $nonce; - } - - /** - * Calculate Opaque - * - * The opaque string can be anything; the client must return it exactly as - * it was sent. It may be useful to store data in this string in some - * applications. Ideally, a new value for this would be generated each time - * a WWW-Authenticate header is sent (in order to reduce predictability), - * but we would have to be able to create the same exact value across at - * least two separate requests from the same client. - * - * @return string The opaque value - */ - protected function _calcOpaque() - { - return hash('md5', 'Opaque Data:' . __CLASS__); - } - - /** - * Parse Digest Authorization header - * - * @param string $header Client's Authorization: HTTP header - * @return array|false Data elements from header, or false if any part of - * the header is invalid - */ - protected function _parseDigestAuth($header) - { - $temp = null; - $data = array(); - - // See ZF-1052. Detect invalid usernames instead of just returning a - // 400 code. - $ret = preg_match('/username="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1]) - || !ctype_print($temp[1]) - || strpos($temp[1], ':') !== false) { - $data['username'] = '::invalid::'; - } else { - $data['username'] = $temp[1]; - } - $temp = null; - - $ret = preg_match('/realm="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (!ctype_print($temp[1]) || strpos($temp[1], ':') !== false) { - return false; - } else { - $data['realm'] = $temp[1]; - } - $temp = null; - - $ret = preg_match('/nonce="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (!ctype_xdigit($temp[1])) { - return false; - } else { - $data['nonce'] = $temp[1]; - } - $temp = null; - - $ret = preg_match('/uri="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - // Section 3.2.2.5 in RFC 2617 says the authenticating server must - // verify that the URI field in the Authorization header is for the - // same resource requested in the Request Line. - $rUri = @parse_url($this->_request->getRequestUri()); - $cUri = @parse_url($temp[1]); - if (false === $rUri || false === $cUri) { - return false; - } else { - // Make sure the path portion of both URIs is the same - if ($rUri['path'] != $cUri['path']) { - return false; - } - // Section 3.2.2.5 seems to suggest that the value of the URI - // Authorization field should be made into an absolute URI if the - // Request URI is absolute, but it's vague, and that's a bunch of - // code I don't want to write right now. - $data['uri'] = $temp[1]; - } - $temp = null; - - $ret = preg_match('/response="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (32 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { - return false; - } else { - $data['response'] = $temp[1]; - } - $temp = null; - - // The spec says this should default to MD5 if omitted. OK, so how does - // that square with the algo we send out in the WWW-Authenticate header, - // if it can easily be overridden by the client? - $ret = preg_match('/algorithm="?(' . $this->_algo . ')"?/', $header, $temp); - if ($ret && !empty($temp[1]) - && in_array($temp[1], $this->_supportedAlgos)) { - $data['algorithm'] = $temp[1]; - } else { - $data['algorithm'] = 'MD5'; // = $this->_algo; ? - } - $temp = null; - - // Not optional in this implementation - $ret = preg_match('/cnonce="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (!ctype_print($temp[1])) { - return false; - } else { - $data['cnonce'] = $temp[1]; - } - $temp = null; - - // If the server sent an opaque value, the client must send it back - if ($this->_useOpaque) { - $ret = preg_match('/opaque="([^"]+)"/', $header, $temp); - if (!$ret || empty($temp[1])) { - - // Big surprise: IE isn't RFC 2617-compliant. - if (false !== strpos($this->_request->getHeader('User-Agent'), 'MSIE')) { - $temp[1] = ''; - $this->_ieNoOpaque = true; - } else { - return false; - } - } - // This implementation only sends MD5 hex strings in the opaque value - if (!$this->_ieNoOpaque && - (32 != strlen($temp[1]) || !ctype_xdigit($temp[1]))) { - return false; - } else { - $data['opaque'] = $temp[1]; - } - $temp = null; - } - - // Not optional in this implementation, but must be one of the supported - // qop types - $ret = preg_match('/qop="?(' . implode('|', $this->_supportedQops) . ')"?/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (!in_array($temp[1], $this->_supportedQops)) { - return false; - } else { - $data['qop'] = $temp[1]; - } - $temp = null; - - // Not optional in this implementation. The spec says this value - // shouldn't be a quoted string, but apparently some implementations - // quote it anyway. See ZF-1544. - $ret = preg_match('/nc="?([0-9A-Fa-f]{8})"?/', $header, $temp); - if (!$ret || empty($temp[1])) { - return false; - } - if (8 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { - return false; - } else { - $data['nc'] = $temp[1]; - } - $temp = null; - - return $data; - } - - /** - * Securely compare two strings for equality while avoided C level memcmp() - * optimisations capable of leaking timing information useful to an attacker - * attempting to iteratively guess the unknown string (e.g. password) being - * compared against. - * - * @param string $a - * @param string $b - * @return bool - */ - protected function _secureStringCompare($a, $b) - { - if (strlen($a) !== strlen($b)) { - return false; - } - $result = 0; - for ($i = 0; $i < strlen($a); $i++) { - $result |= ord($a[$i]) ^ ord($b[$i]); - } - return $result == 0; - } -} diff --git a/lib/Zend/Auth/Adapter/Http/Resolver/Exception.php b/lib/Zend/Auth/Adapter/Http/Resolver/Exception.php deleted file mode 100644 index dd47800f5df..00000000000 --- a/lib/Zend/Auth/Adapter/Http/Resolver/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ -setFile($path); - } - } - - /** - * Set the path to the credentials file - * - * @param string $path - * @throws Zend_Auth_Adapter_Http_Resolver_Exception - * @return Zend_Auth_Adapter_Http_Resolver_File Provides a fluent interface - */ - public function setFile($path) - { - if (empty($path) || !is_readable($path)) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Path not readable: ' . $path); - } - $this->_file = $path; - - return $this; - } - - /** - * Returns the path to the credentials file - * - * @return string - */ - public function getFile() - { - return $this->_file; - } - - /** - * Resolve credentials - * - * Only the first matching username/realm combination in the file is - * returned. If the file contains credentials for Digest authentication, - * the returned string is the password hash, or h(a1) from RFC 2617. The - * returned string is the plain-text password for Basic authentication. - * - * The expected format of the file is: - * username:realm:sharedSecret - * - * That is, each line consists of the user's username, the applicable - * authentication realm, and the password or hash, each delimited by - * colons. - * - * @param string $username Username - * @param string $realm Authentication Realm - * @throws Zend_Auth_Adapter_Http_Resolver_Exception - * @return string|false User's shared secret, if the user is found in the - * realm, false otherwise. - */ - public function resolve($username, $realm) - { - if (empty($username)) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Username is required'); - } else if (!ctype_print($username) || strpos($username, ':') !== false) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Username must consist only of printable characters, ' - . 'excluding the colon'); - } - if (empty($realm)) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Realm is required'); - } else if (!ctype_print($realm) || strpos($realm, ':') !== false) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Realm must consist only of printable characters, ' - . 'excluding the colon.'); - } - - // Open file, read through looking for matching credentials - $fp = @fopen($this->_file, 'r'); - if (!$fp) { - /** - * @see Zend_Auth_Adapter_Http_Resolver_Exception - */ - #require_once 'Zend/Auth/Adapter/Http/Resolver/Exception.php'; - throw new Zend_Auth_Adapter_Http_Resolver_Exception('Unable to open password file: ' . $this->_file); - } - - // No real validation is done on the contents of the password file. The - // assumption is that we trust the administrators to keep it secure. - while (($line = fgetcsv($fp, 512, ':')) !== false) { - if ($line[0] == $username && $line[1] == $realm) { - $password = $line[2]; - fclose($fp); - return $password; - } - } - - fclose($fp); - return false; - } -} diff --git a/lib/Zend/Auth/Adapter/Http/Resolver/Interface.php b/lib/Zend/Auth/Adapter/Http/Resolver/Interface.php deleted file mode 100644 index 4326ee8202f..00000000000 --- a/lib/Zend/Auth/Adapter/Http/Resolver/Interface.php +++ /dev/null @@ -1,47 +0,0 @@ -setOptions($options); - if ($username !== null) { - $this->setUsername($username); - } - if ($password !== null) { - $this->setPassword($password); - } - } - - /** - * Returns the array of arrays of Zend_Ldap options of this adapter. - * - * @return array|null - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Sets the array of arrays of Zend_Ldap options to be used by - * this adapter. - * - * @param array $options The array of arrays of Zend_Ldap options - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setOptions($options) - { - $this->_options = is_array($options) ? $options : array(); - return $this; - } - - /** - * Returns the username of the account being authenticated, or - * NULL if none is set. - * - * @return string|null - */ - public function getUsername() - { - return $this->_username; - } - - /** - * Sets the username for binding - * - * @param string $username The username for binding - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setUsername($username) - { - $this->_username = (string) $username; - return $this; - } - - /** - * Returns the password of the account being authenticated, or - * NULL if none is set. - * - * @return string|null - */ - public function getPassword() - { - return $this->_password; - } - - /** - * Sets the passwort for the account - * - * @param string $password The password of the account being authenticated - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setPassword($password) - { - $this->_password = (string) $password; - return $this; - } - - /** - * setIdentity() - set the identity (username) to be used - * - * Proxies to {@see setUsername()} - * - * Closes ZF-6813 - * - * @param string $identity - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setIdentity($identity) - { - return $this->setUsername($identity); - } - - /** - * setCredential() - set the credential (password) value to be used - * - * Proxies to {@see setPassword()} - * - * Closes ZF-6813 - * - * @param string $credential - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setCredential($credential) - { - return $this->setPassword($credential); - } - - /** - * Returns the LDAP Object - * - * @return Zend_Ldap The Zend_Ldap object used to authenticate the credentials - */ - public function getLdap() - { - if ($this->_ldap === null) { - /** - * @see Zend_Ldap - */ - #require_once 'Zend/Ldap.php'; - $this->_ldap = new Zend_Ldap(); - } - - return $this->_ldap; - } - - /** - * Set an Ldap connection - * - * @param Zend_Ldap $ldap An existing Ldap object - * @return Zend_Auth_Adapter_Ldap Provides a fluent interface - */ - public function setLdap(Zend_Ldap $ldap) - { - $this->_ldap = $ldap; - - $this->setOptions(array($ldap->getOptions())); - - return $this; - } - - /** - * Returns a domain name for the current LDAP options. This is used - * for skipping redundant operations (e.g. authentications). - * - * @return string - */ - protected function _getAuthorityName() - { - $options = $this->getLdap()->getOptions(); - $name = $options['accountDomainName']; - if (!$name) - $name = $options['accountDomainNameShort']; - return $name ? $name : ''; - } - - /** - * Authenticate the user - * - * @throws Zend_Auth_Adapter_Exception - * @return Zend_Auth_Result - */ - public function authenticate() - { - /** - * @see Zend_Ldap_Exception - */ - #require_once 'Zend/Ldap/Exception.php'; - - $messages = array(); - $messages[0] = ''; // reserved - $messages[1] = ''; // reserved - - $username = $this->_username; - $password = $this->_password; - - if (!$username) { - $code = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND; - $messages[0] = 'A username is required'; - return new Zend_Auth_Result($code, '', $messages); - } - if (!$password) { - /* A password is required because some servers will - * treat an empty password as an anonymous bind. - */ - $code = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; - $messages[0] = 'A password is required'; - return new Zend_Auth_Result($code, '', $messages); - } - - $ldap = $this->getLdap(); - - $code = Zend_Auth_Result::FAILURE; - $messages[0] = "Authority not found: $username"; - $failedAuthorities = array(); - - /* Iterate through each server and try to authenticate the supplied - * credentials against it. - */ - foreach ($this->_options as $name => $options) { - - if (!is_array($options)) { - /** - * @see Zend_Auth_Adapter_Exception - */ - #require_once 'Zend/Auth/Adapter/Exception.php'; - throw new Zend_Auth_Adapter_Exception('Adapter options array not an array'); - } - $adapterOptions = $this->_prepareOptions($ldap, $options); - $dname = ''; - - try { - if ($messages[1]) - $messages[] = $messages[1]; - $messages[1] = ''; - $messages[] = $this->_optionsToString($options); - - $dname = $this->_getAuthorityName(); - if (isset($failedAuthorities[$dname])) { - /* If multiple sets of server options for the same domain - * are supplied, we want to skip redundant authentications - * where the identity or credentials where found to be - * invalid with another server for the same domain. The - * $failedAuthorities array tracks this condition (and also - * serves to supply the original error message). - * This fixes issue ZF-4093. - */ - $messages[1] = $failedAuthorities[$dname]; - $messages[] = "Skipping previously failed authority: $dname"; - continue; - } - - $canonicalName = $ldap->getCanonicalAccountName($username); - $ldap->bind($canonicalName, $password); - /* - * Fixes problem when authenticated user is not allowed to retrieve - * group-membership information or own account. - * This requires that the user specified with "username" and optionally - * "password" in the Zend_Ldap options is able to retrieve the required - * information. - */ - $requireRebind = false; - if (isset($options['username'])) { - $ldap->bind(); - $requireRebind = true; - } - $dn = $ldap->getCanonicalAccountName($canonicalName, Zend_Ldap::ACCTNAME_FORM_DN); - - $groupResult = $this->_checkGroupMembership($ldap, $canonicalName, $dn, $adapterOptions); - if ($groupResult === true) { - $this->_authenticatedDn = $dn; - $messages[0] = ''; - $messages[1] = ''; - $messages[] = "$canonicalName authentication successful"; - if ($requireRebind === true) { - // rebinding with authenticated user - $ldap->bind($dn, $password); - } - return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $canonicalName, $messages); - } else { - $messages[0] = 'Account is not a member of the specified group'; - $messages[1] = $groupResult; - $failedAuthorities[$dname] = $groupResult; - } - } catch (Zend_Ldap_Exception $zle) { - - /* LDAP based authentication is notoriously difficult to diagnose. Therefore - * we bend over backwards to capture and record every possible bit of - * information when something goes wrong. - */ - - $err = $zle->getCode(); - - if ($err == Zend_Ldap_Exception::LDAP_X_DOMAIN_MISMATCH) { - /* This error indicates that the domain supplied in the - * username did not match the domains in the server options - * and therefore we should just skip to the next set of - * server options. - */ - continue; - } else if ($err == Zend_Ldap_Exception::LDAP_NO_SUCH_OBJECT) { - $code = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND; - $messages[0] = "Account not found: $username"; - $failedAuthorities[$dname] = $zle->getMessage(); - } else if ($err == Zend_Ldap_Exception::LDAP_INVALID_CREDENTIALS) { - $code = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; - $messages[0] = 'Invalid credentials'; - $failedAuthorities[$dname] = $zle->getMessage(); - } else { - $line = $zle->getLine(); - $messages[] = $zle->getFile() . "($line): " . $zle->getMessage(); - $messages[] = preg_replace( - '/\b'.preg_quote(substr($password, 0, 15), '/').'\b/', - '*****', - $zle->getTraceAsString() - ); - $messages[0] = 'An unexpected failure occurred'; - } - $messages[1] = $zle->getMessage(); - } - } - - $msg = isset($messages[1]) ? $messages[1] : $messages[0]; - $messages[] = "$username authentication failed: $msg"; - - return new Zend_Auth_Result($code, $username, $messages); - } - - /** - * Sets the LDAP specific options on the Zend_Ldap instance - * - * @param Zend_Ldap $ldap - * @param array $options - * @return array of auth-adapter specific options - */ - protected function _prepareOptions(Zend_Ldap $ldap, array $options) - { - $adapterOptions = array( - 'group' => null, - 'groupDn' => $ldap->getBaseDn(), - 'groupScope' => Zend_Ldap::SEARCH_SCOPE_SUB, - 'groupAttr' => 'cn', - 'groupFilter' => 'objectClass=groupOfUniqueNames', - 'memberAttr' => 'uniqueMember', - 'memberIsDn' => true - ); - foreach ($adapterOptions as $key => $value) { - if (array_key_exists($key, $options)) { - $value = $options[$key]; - unset($options[$key]); - switch ($key) { - case 'groupScope': - $value = (int)$value; - if (in_array($value, array(Zend_Ldap::SEARCH_SCOPE_BASE, - Zend_Ldap::SEARCH_SCOPE_ONE, Zend_Ldap::SEARCH_SCOPE_SUB), true)) { - $adapterOptions[$key] = $value; - } - break; - case 'memberIsDn': - $adapterOptions[$key] = ($value === true || - $value === '1' || strcasecmp($value, 'true') == 0); - break; - default: - $adapterOptions[$key] = trim($value); - break; - } - } - } - $ldap->setOptions($options); - return $adapterOptions; - } - - /** - * Checks the group membership of the bound user - * - * @param Zend_Ldap $ldap - * @param string $canonicalName - * @param string $dn - * @param array $adapterOptions - * @return string|true - */ - protected function _checkGroupMembership(Zend_Ldap $ldap, $canonicalName, $dn, array $adapterOptions) - { - if ($adapterOptions['group'] === null) { - return true; - } - - if ($adapterOptions['memberIsDn'] === false) { - $user = $canonicalName; - } else { - $user = $dn; - } - - /** - * @see Zend_Ldap_Filter - */ - #require_once 'Zend/Ldap/Filter.php'; - $groupName = Zend_Ldap_Filter::equals($adapterOptions['groupAttr'], $adapterOptions['group']); - $membership = Zend_Ldap_Filter::equals($adapterOptions['memberAttr'], $user); - $group = Zend_Ldap_Filter::andFilter($groupName, $membership); - $groupFilter = $adapterOptions['groupFilter']; - if (!empty($groupFilter)) { - $group = $group->addAnd($groupFilter); - } - - $result = $ldap->count($group, $adapterOptions['groupDn'], $adapterOptions['groupScope']); - - if ($result === 1) { - return true; - } else { - return 'Failed to verify group membership with ' . $group->toString(); - } - } - - /** - * getAccountObject() - Returns the result entry as a stdClass object - * - * This resembles the feature {@see Zend_Auth_Adapter_DbTable::getResultRowObject()}. - * Closes ZF-6813 - * - * @param array $returnAttribs - * @param array $omitAttribs - * @return stdClass|boolean - */ - public function getAccountObject(array $returnAttribs = array(), array $omitAttribs = array()) - { - if (!$this->_authenticatedDn) { - return false; - } - - $returnObject = new stdClass(); - - $returnAttribs = array_map('strtolower', $returnAttribs); - $omitAttribs = array_map('strtolower', $omitAttribs); - $returnAttribs = array_diff($returnAttribs, $omitAttribs); - - $entry = $this->getLdap()->getEntry($this->_authenticatedDn, $returnAttribs, true); - foreach ($entry as $attr => $value) { - if (in_array($attr, $omitAttribs)) { - // skip attributes marked to be omitted - continue; - } - if (is_array($value)) { - $returnObject->$attr = (count($value) > 1) ? $value : $value[0]; - } else { - $returnObject->$attr = $value; - } - } - return $returnObject; - } - - /** - * Converts options to string - * - * @param array $options - * @return string - */ - private function _optionsToString(array $options) - { - $str = ''; - foreach ($options as $key => $val) { - if ($key === 'password') - $val = '*****'; - if ($str) - $str .= ','; - $str .= $key . '=' . $val; - } - return $str; - } -} diff --git a/lib/Zend/Auth/Adapter/OpenId.php b/lib/Zend/Auth/Adapter/OpenId.php deleted file mode 100644 index 0a68bc20ecf..00000000000 --- a/lib/Zend/Auth/Adapter/OpenId.php +++ /dev/null @@ -1,283 +0,0 @@ -_id = $id; - $this->_storage = $storage; - $this->_returnTo = $returnTo; - $this->_root = $root; - $this->_extensions = $extensions; - $this->_response = $response; - } - - /** - * Sets the value to be used as the identity - * - * @param string $id the identity value - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setIdentity($id) - { - $this->_id = $id; - return $this; - } - - /** - * Sets the storage implementation which will be use by OpenId - * - * @param Zend_OpenId_Consumer_Storage $storage - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setStorage(Zend_OpenId_Consumer_Storage $storage) - { - $this->_storage = $storage; - return $this; - } - - /** - * Sets the HTTP URL to redirect response from server to - * - * @param string $returnTo - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setReturnTo($returnTo) - { - $this->_returnTo = $returnTo; - return $this; - } - - /** - * Sets HTTP URL to identify consumer on server - * - * @param string $root - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setRoot($root) - { - $this->_root = $root; - return $this; - } - - /** - * Sets OpenID extension(s) - * - * @param mixed $extensions - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setExtensions($extensions) - { - $this->_extensions = $extensions; - return $this; - } - - /** - * Sets an optional response object to perform HTTP or HTML form redirection - * - * @param string $response - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setResponse($response) - { - $this->_response = $response; - return $this; - } - - /** - * Enables or disables interaction with user during authentication on - * OpenID provider. - * - * @param bool $check_immediate - * @return Zend_Auth_Adapter_OpenId Provides a fluent interface - */ - public function setCheckImmediate($check_immediate) - { - $this->_check_immediate = $check_immediate; - return $this; - } - - /** - * Sets HTTP client object to make HTTP requests - * - * @param Zend_Http_Client $client HTTP client object to be used - */ - public function setHttpClient($client) { - $this->_httpClient = $client; - } - - /** - * Authenticates the given OpenId identity. - * Defined by Zend_Auth_Adapter_Interface. - * - * @throws Zend_Auth_Adapter_Exception If answering the authentication query is impossible - * @return Zend_Auth_Result - */ - public function authenticate() { - $id = $this->_id; - if (!empty($id)) { - $consumer = new Zend_OpenId_Consumer($this->_storage); - $consumer->setHttpClient($this->_httpClient); - /* login() is never returns on success */ - if (!$this->_check_immediate) { - if (!$consumer->login($id, - $this->_returnTo, - $this->_root, - $this->_extensions, - $this->_response)) { - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE, - $id, - array("Authentication failed", $consumer->getError())); - } - } else { - if (!$consumer->check($id, - $this->_returnTo, - $this->_root, - $this->_extensions, - $this->_response)) { - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE, - $id, - array("Authentication failed", $consumer->getError())); - } - } - } else { - $params = (isset($_SERVER['REQUEST_METHOD']) && - $_SERVER['REQUEST_METHOD']=='POST') ? $_POST: $_GET; - $consumer = new Zend_OpenId_Consumer($this->_storage); - $consumer->setHttpClient($this->_httpClient); - if ($consumer->verify( - $params, - $id, - $this->_extensions)) { - return new Zend_Auth_Result( - Zend_Auth_Result::SUCCESS, - $id, - array("Authentication successful")); - } else { - return new Zend_Auth_Result( - Zend_Auth_Result::FAILURE, - $id, - array("Authentication failed", $consumer->getError())); - } - } - } - -} diff --git a/lib/Zend/Auth/Exception.php b/lib/Zend/Auth/Exception.php deleted file mode 100644 index 753f037552c..00000000000 --- a/lib/Zend/Auth/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ - self::SUCCESS ) { - $code = 1; - } - - $this->_code = $code; - $this->_identity = $identity; - $this->_messages = $messages; - } - - /** - * Returns whether the result represents a successful authentication attempt - * - * @return boolean - */ - public function isValid() - { - return ($this->_code > 0) ? true : false; - } - - /** - * getCode() - Get the result code for this authentication attempt - * - * @return int - */ - public function getCode() - { - return $this->_code; - } - - /** - * Returns the identity used in the authentication attempt - * - * @return mixed - */ - public function getIdentity() - { - return $this->_identity; - } - - /** - * Returns an array of string reasons why the authentication attempt was unsuccessful - * - * If authentication was successful, this method returns an empty array. - * - * @return array - */ - public function getMessages() - { - return $this->_messages; - } -} diff --git a/lib/Zend/Auth/Storage/Exception.php b/lib/Zend/Auth/Storage/Exception.php deleted file mode 100644 index 7ab89718a02..00000000000 --- a/lib/Zend/Auth/Storage/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_data); - } - - /** - * Returns the contents of storage - * Behavior is undefined when storage is empty. - * - * @throws Zend_Auth_Storage_Exception If reading contents from storage is impossible - * @return mixed - */ - public function read() - { - return $this->_data; - } - - /** - * Writes $contents to storage - * - * @param mixed $contents - * @throws Zend_Auth_Storage_Exception If writing $contents to storage is impossible - * @return void - */ - public function write($contents) - { - $this->_data = $contents; - } - - /** - * Clears contents from storage - * - * @throws Zend_Auth_Storage_Exception If clearing contents from storage is impossible - * @return void - */ - public function clear() - { - $this->_data = null; - } -} diff --git a/lib/Zend/Auth/Storage/Session.php b/lib/Zend/Auth/Storage/Session.php deleted file mode 100644 index 8d179fb9505..00000000000 --- a/lib/Zend/Auth/Storage/Session.php +++ /dev/null @@ -1,149 +0,0 @@ -_namespace = $namespace; - $this->_member = $member; - $this->_session = new Zend_Session_Namespace($this->_namespace); - } - - /** - * Returns the session namespace - * - * @return string - */ - public function getNamespace() - { - return $this->_namespace; - } - - /** - * Returns the name of the session object member - * - * @return string - */ - public function getMember() - { - return $this->_member; - } - - /** - * Defined by Zend_Auth_Storage_Interface - * - * @return boolean - */ - public function isEmpty() - { - return !isset($this->_session->{$this->_member}); - } - - /** - * Defined by Zend_Auth_Storage_Interface - * - * @return mixed - */ - public function read() - { - return $this->_session->{$this->_member}; - } - - /** - * Defined by Zend_Auth_Storage_Interface - * - * @param mixed $contents - * @return void - */ - public function write($contents) - { - $this->_session->{$this->_member} = $contents; - } - - /** - * Defined by Zend_Auth_Storage_Interface - * - * @return void - */ - public function clear() - { - unset($this->_session->{$this->_member}); - } -} diff --git a/lib/Zend/Barcode.php b/lib/Zend/Barcode.php deleted file mode 100644 index 7338cbf0f95..00000000000 --- a/lib/Zend/Barcode.php +++ /dev/null @@ -1,352 +0,0 @@ -rendererParams)) { - $rendererConfig = $barcode->rendererParams->toArray(); - } - if (isset($barcode->renderer)) { - $renderer = (string) $barcode->renderer; - } - if (isset($barcode->barcodeParams)) { - $barcodeConfig = $barcode->barcodeParams->toArray(); - } - if (isset($barcode->barcode)) { - $barcode = (string) $barcode->barcode; - } else { - $barcode = null; - } - } - - try { - $barcode = self::makeBarcode($barcode, $barcodeConfig); - $renderer = self::makeRenderer($renderer, $rendererConfig); - } catch (Zend_Exception $e) { - $renderable = ($e instanceof Zend_Barcode_Exception) ? $e->isRenderable() : false; - if ($automaticRenderError && $renderable) { - $barcode = self::makeBarcode('error', array( - 'text' => $e->getMessage() - )); - $renderer = self::makeRenderer($renderer, array()); - } else { - throw $e; - } - } - - $renderer->setAutomaticRenderError($automaticRenderError); - return $renderer->setBarcode($barcode); - } - - /** - * Barcode Constructor - * - * @param mixed $barcode String name of barcode class, or Zend_Config object. - * @param mixed $barcodeConfig OPTIONAL; an array or Zend_Config object with barcode parameters. - * @return Zend_Barcode_Object - */ - public static function makeBarcode($barcode, $barcodeConfig = array()) - { - if ($barcode instanceof Zend_Barcode_Object_ObjectAbstract) { - return $barcode; - } - - /* - * Convert Zend_Config argument to plain string - * barcode name and separate config object. - */ - if ($barcode instanceof Zend_Config) { - if (isset($barcode->barcodeParams) && $barcode->barcodeParams instanceof Zend_Config) { - $barcodeConfig = $barcode->barcodeParams->toArray(); - } - if (isset($barcode->barcode)) { - $barcode = (string) $barcode->barcode; - } else { - $barcode = null; - } - } - if ($barcodeConfig instanceof Zend_Config) { - $barcodeConfig = $barcodeConfig->toArray(); - } - - /* - * Verify that barcode parameters are in an array. - */ - if (!is_array($barcodeConfig)) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - throw new Zend_Barcode_Exception( - 'Barcode parameters must be in an array or a Zend_Config object' - ); - } - - /* - * Verify that an barcode name has been specified. - */ - if (!is_string($barcode) || empty($barcode)) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - throw new Zend_Barcode_Exception( - 'Barcode name must be specified in a string' - ); - } - /* - * Form full barcode class name - */ - $barcodeNamespace = 'Zend_Barcode_Object'; - if (isset($barcodeConfig['barcodeNamespace'])) { - $barcodeNamespace = $barcodeConfig['barcodeNamespace']; - } - - $barcodeName = strtolower($barcodeNamespace . '_' . $barcode); - $barcodeName = str_replace(' ', '_', ucwords( - str_replace( '_', ' ', $barcodeName) - )); - - /* - * Load the barcode class. This throws an exception - * if the specified class cannot be loaded. - */ - if (!class_exists($barcodeName)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($barcodeName); - } - - /* - * Create an instance of the barcode class. - * Pass the config to the barcode class constructor. - */ - $bcAdapter = new $barcodeName($barcodeConfig); - - /* - * Verify that the object created is a descendent of the abstract barcode type. - */ - if (!$bcAdapter instanceof Zend_Barcode_Object_ObjectAbstract) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - throw new Zend_Barcode_Exception( - "Barcode class '$barcodeName' does not extend Zend_Barcode_Object_ObjectAbstract" - ); - } - return $bcAdapter; - } - - /** - * Renderer Constructor - * - * @param mixed $renderer String name of renderer class, or Zend_Config object. - * @param mixed $rendererConfig OPTIONAL; an array or Zend_Config object with renderer parameters. - * @return Zend_Barcode_Renderer - */ - public static function makeRenderer($renderer = 'image', $rendererConfig = array()) - { - if ($renderer instanceof Zend_Barcode_Renderer_RendererAbstract) { - return $renderer; - } - - /* - * Convert Zend_Config argument to plain string - * barcode name and separate config object. - */ - if ($renderer instanceof Zend_Config) { - if (isset($renderer->rendererParams)) { - $rendererConfig = $renderer->rendererParams->toArray(); - } - if (isset($renderer->renderer)) { - $renderer = (string) $renderer->renderer; - } - } - if ($rendererConfig instanceof Zend_Config) { - $rendererConfig = $rendererConfig->toArray(); - } - - /* - * Verify that barcode parameters are in an array. - */ - if (!is_array($rendererConfig)) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - $e = new Zend_Barcode_Exception( - 'Barcode parameters must be in an array or a Zend_Config object' - ); - $e->setIsRenderable(false); - throw $e; - } - - /* - * Verify that an barcode name has been specified. - */ - if (!is_string($renderer) || empty($renderer)) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - $e = new Zend_Barcode_Exception( - 'Renderer name must be specified in a string' - ); - $e->setIsRenderable(false); - throw $e; - } - - /* - * Form full barcode class name - */ - $rendererNamespace = 'Zend_Barcode_Renderer'; - if (isset($rendererConfig['rendererNamespace'])) { - $rendererNamespace = $rendererConfig['rendererNamespace']; - } - - $rendererName = strtolower($rendererNamespace . '_' . $renderer); - $rendererName = str_replace(' ', '_', ucwords( - str_replace( '_', ' ', $rendererName) - )); - - /* - * Load the barcode class. This throws an exception - * if the specified class cannot be loaded. - */ - if (!class_exists($rendererName)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rendererName); - } - - /* - * Create an instance of the barcode class. - * Pass the config to the barcode class constructor. - */ - $rdrAdapter = new $rendererName($rendererConfig); - - /* - * Verify that the object created is a descendent of the abstract barcode type. - */ - if (!$rdrAdapter instanceof Zend_Barcode_Renderer_RendererAbstract) { - /** - * @see Zend_Barcode_Exception - */ - #require_once 'Zend/Barcode/Exception.php'; - $e = new Zend_Barcode_Exception( - "Renderer class '$rendererName' does not extend Zend_Barcode_Renderer_RendererAbstract" - ); - $e->setIsRenderable(false); - throw $e; - } - return $rdrAdapter; - } - - /** - * Proxy to renderer render() method - * - * @param string | Zend_Barcode_Object | array | Zend_Config $barcode - * @param string | Zend_Barcode_Renderer $renderer - * @param array | Zend_Config $barcodeConfig - * @param array | Zend_Config $rendererConfig - */ - public static function render( - $barcode, - $renderer, - $barcodeConfig = array(), - $rendererConfig = array() - ) { - self::factory($barcode, $renderer, $barcodeConfig, $rendererConfig)->render(); - } - - /** - * Proxy to renderer draw() method - * - * @param string | Zend_Barcode_Object | array | Zend_Config $barcode - * @param string | Zend_Barcode_Renderer $renderer - * @param array | Zend_Config $barcodeConfig - * @param array | Zend_Config $rendererConfig - * @return mixed - */ - public static function draw( - $barcode, - $renderer, - $barcodeConfig = array(), - $rendererConfig = array() - ) { - return self::factory($barcode, $renderer, $barcodeConfig, $rendererConfig)->draw(); - } - - /** - * Proxy for setBarcodeFont of Zend_Barcode_Object - * @param string $font - * @eturn void - */ - public static function setBarcodeFont($font) - { - #require_once 'Zend/Barcode/Object/ObjectAbstract.php'; - Zend_Barcode_Object_ObjectAbstract::setBarcodeFont($font); - } -} diff --git a/lib/Zend/Barcode/Exception.php b/lib/Zend/Barcode/Exception.php deleted file mode 100644 index 703b0c4f6eb..00000000000 --- a/lib/Zend/Barcode/Exception.php +++ /dev/null @@ -1,63 +0,0 @@ -_isRenderable = (bool) $flag; - return $this; - } - - /** - * Retrieve renderable flag - * - * @return bool - */ - public function isRenderable() - { - return $this->_isRenderable; - } -} diff --git a/lib/Zend/Barcode/Object/Code128.php b/lib/Zend/Barcode/Object/Code128.php deleted file mode 100644 index 0d5eabc12a8..00000000000 --- a/lib/Zend/Barcode/Object/Code128.php +++ /dev/null @@ -1,395 +0,0 @@ - "11011001100", 1 => "11001101100", 2 => "11001100110", - 3 => "10010011000", 4 => "10010001100", 5 => "10001001100", - 6 => "10011001000", 7 => "10011000100", 8 => "10001100100", - 9 => "11001001000", 10 => "11001000100", 11 => "11000100100", - 12 => "10110011100", 13 => "10011011100", 14 => "10011001110", - 15 => "10111001100", 16 => "10011101100", 17 => "10011100110", - 18 => "11001110010", 19 => "11001011100", 20 => "11001001110", - 21 => "11011100100", 22 => "11001110100", 23 => "11101101110", - 24 => "11101001100", 25 => "11100101100", 26 => "11100100110", - 27 => "11101100100", 28 => "11100110100", 29 => "11100110010", - 30 => "11011011000", 31 => "11011000110", 32 => "11000110110", - 33 => "10100011000", 34 => "10001011000", 35 => "10001000110", - 36 => "10110001000", 37 => "10001101000", 38 => "10001100010", - 39 => "11010001000", 40 => "11000101000", 41 => "11000100010", - 42 => "10110111000", 43 => "10110001110", 44 => "10001101110", - 45 => "10111011000", 46 => "10111000110", 47 => "10001110110", - 48 => "11101110110", 49 => "11010001110", 50 => "11000101110", - 51 => "11011101000", 52 => "11011100010", 53 => "11011101110", - 54 => "11101011000", 55 => "11101000110", 56 => "11100010110", - 57 => "11101101000", 58 => "11101100010", 59 => "11100011010", - 60 => "11101111010", 61 => "11001000010", 62 => "11110001010", - 63 => "10100110000", 64 => "10100001100", 65 => "10010110000", - 66 => "10010000110", 67 => "10000101100", 68 => "10000100110", - 69 => "10110010000", 70 => "10110000100", 71 => "10011010000", - 72 => "10011000010", 73 => "10000110100", 74 => "10000110010", - 75 => "11000010010", 76 => "11001010000", 77 => "11110111010", - 78 => "11000010100", 79 => "10001111010", 80 => "10100111100", - 81 => "10010111100", 82 => "10010011110", 83 => "10111100100", - 84 => "10011110100", 85 => "10011110010", 86 => "11110100100", - 87 => "11110010100", 88 => "11110010010", 89 => "11011011110", - 90 => "11011110110", 91 => "11110110110", 92 => "10101111000", - 93 => "10100011110", 94 => "10001011110", 95 => "10111101000", - 96 => "10111100010", 97 => "11110101000", 98 => "11110100010", - 99 => "10111011110", 100 => "10111101110", 101 => "11101011110", - 102 => "11110101110", - 103 => "11010000100", 104 => "11010010000", 105 => "11010011100", - 106 => "1100011101011"); - - /** - * Character sets ABC - * @var array - */ - protected $_charSets = array( - 'A' => array( - ' ', '!', '"', '#', '$', '%', '&', "'", - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 'FNC3', 'FNC2', 'SHIFT', 'Code C', 'Code B', 'FNC4', 'FNC1', - 'START A', 'START B', 'START C', 'STOP'), - 'B' => array( - ' ', '!', '"', '#', '$', '%', '&', "'", - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - 'x', 'y', 'z', '{', '|', '}', '~', 0x7F, - 'FNC3', 'FNC2', 'SHIFT', 'Code C', 'FNC4', 'Code A', 'FNC1', - 'START A', 'START B', 'START C', 'STOP',), - 'C' => array( - '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', - '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', - '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', - '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', - '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', - '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', - '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', - '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', - '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', - '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', - 'Code B', 'Code A', 'FNC1', 'START A', 'START B', 'START C', 'STOP')); - /*'A' => array( - ' '=>0, '!'=>1, '"'=>2, '#'=>3, '$'=>4, '%'=>5, '&'=>6, "'"=>7, - '('=>8, ')'=>9, '*'=>10, '+'=>11, ','=>12, '-'=>13, '.'=>14, '/'=>15, - '0'=>16, '1'=>17, '2'=>18, '3'=>19, '4'=>20, '5'=>21, '6'=>22, '7'=>23, - '8'=>24, '9'=>25, ':'=>26, ';'=>27, '<'=>28, '='=>29, '>'=>30, '?'=>31, - '@'=>32, 'A'=>33, 'B'=>34, 'C'=>35, 'D'=>36, 'E'=>37, 'F'=>38, 'G'=>39, - 'H'=>40, 'I'=>41, 'J'=>42, 'K'=>43, 'L'=>44, 'M'=>45, 'N'=>46, 'O'=>47, - 'P'=>48, 'Q'=>49, 'R'=>50, 'S'=>51, 'T'=>52, 'U'=>53, 'V'=>54, 'W'=>55, - 'X'=>56, 'Y'=>57, 'Z'=>58, '['=>59, '\\'=>60, ']'=>61, '^'=>62, '_'=>63, - 0x00=>64, 0x01=>65, 0x02=>66, 0x03=>67, 0x04=>68, 0x05=>69, 0x06=>70, 0x07=>71, - 0x08=>72, 0x09=>73, 0x0A=>74, 0x0B=>75, 0x0C=>76, 0x0D=>77, 0x0E=>78, 0x0F=>79, - 0x10=>80, 0x11=>81, 0x12=>82, 0x13=>83, 0x14=>84, 0x15=>85, 0x16=>86, 0x17=>87, - 0x18=>88, 0x19=>89, 0x1A=>90, 0x1B=>91, 0x1C=>92, 0x1D=>93, 0x1E=>94, 0x1F=>95, - 'FNC3'=>96, 'FNC2'=>97, 'SHIFT'=>98, 'Code C'=>99, 'Code B'=>100, 'FNC4'=>101, 'FNC1'=>102, 'START A'=>103, - 'START B'=>104, 'START C'=>105, 'STOP'=>106), - 'B' => array( - ' '=>0, '!'=>1, '"'=>2, '#'=>3, '$'=>4, '%'=>5, '&'=>6, "'"=>7, - '('=>8, ')'=>9, '*'=>10, '+'=>11, ','=>12, '-'=>13, '.'=>14, '/'=>15, - '0'=>16, '1'=>17, '2'=>18, '3'=>19, '4'=>20, '5'=>21, '6'=>22, '7'=>23, - '8'=>24, '9'=>25, ':'=>26, ';'=>27, '<'=>28, '='=>29, '>'=>30, '?'=>31, - '@'=>32, 'A'=>33, 'B'=>34, 'C'=>35, 'D'=>36, 'E'=>37, 'F'=>38, 'G'=>39, - 'H'=>40, 'I'=>41, 'J'=>42, 'K'=>43, 'L'=>44, 'M'=>45, 'N'=>46, 'O'=>47, - 'P'=>48, 'Q'=>49, 'R'=>50, 'S'=>51, 'T'=>52, 'U'=>53, 'V'=>54, 'W'=>55, - 'X'=>56, 'Y'=>57, 'Z'=>58, '['=>59, '\\'=>60, ']'=>61, '^'=>62, '_'=>63, - '`' =>64, 'a'=>65, 'b'=>66, 'c'=>67, 'd'=>68, 'e'=>69, 'f'=>70, 'g'=>71, - 'h'=>72, 'i'=>73, 'j'=>74, 'k'=>75, 'l'=>76, 'm'=>77, 'n'=>78, 'o'=>79, - 'p'=>80, 'q'=>81, 'r'=>82, 's'=>83, 't'=>84, 'u'=>85, 'v'=>86, 'w'=>87, - 'x'=>88, 'y'=>89, 'z'=>90, '{'=>91, '|'=>92, '}'=>93, '~'=>94, 0x7F=>95, - 'FNC3'=>96, 'FNC2'=>97, 'SHIFT'=>98, 'Code C'=>99, 'FNC4'=>100, 'Code A'=>101, 'FNC1'=>102, 'START A'=>103, - 'START B'=>104, 'START C'=>105, 'STOP'=>106,), - 'C' => array( - '00'=>0, '01'=>1, '02'=>2, '03'=>3, '04'=>4, '05'=>5, '06'=>6, '07'=>7, '08'=>8, '09'=>9, - '10'=>10, '11'=>11, '12'=>12, '13'=>13, '14'=>14, '15'=>15, '16'=>16, '17'=>17, '18'=>18, '19'=>19, - '20'=>20, '21'=>21, '22'=>22, '23'=>23, '24'=>24, '25'=>25, '26'=>26, '27'=>27, '28'=>28, '29'=>29, - '30'=>30, '31'=>31, '32'=>32, '33'=>33, '34'=>34, '35'=>35, '36'=>36, '37'=>37, '38'=>38, '39'=>39, - '40'=>40, '41'=>41, '42'=>42, '43'=>43, '44'=>44, '45'=>45, '46'=>46, '47'=>47, '48'=>48, '49'=>49, - '50'=>50, '51'=>51, '52'=>52, '53'=>53, '54'=>54, '55'=>55, '56'=>56, '57'=>57, '58'=>58, '59'=>59, - '60'=>60, '61'=>61, '62'=>62, '63'=>63, '64'=>64, '65'=>65, '66'=>66, '67'=>67, '68'=>68, '69'=>69, - '70'=>70, '71'=>71, '72'=>72, '73'=>73, '74'=>74, '75'=>75, '76'=>76, '77'=>77, '78'=>78, '79'=>79, - '80'=>80, '81'=>81, '82'=>82, '83'=>83, '84'=>84, '85'=>85, '86'=>86, '87'=>87, '88'=>88, '89'=>89, - '90'=>90, '91'=>91, '92'=>92, '93'=>93, '94'=>94, '95'=>95, '96'=>96, '97'=>97, '98'=>98, '99'=>99, - 'Code B'=>100, 'Code A'=>101, 'FNC1'=>102, 'START A'=>103, 'START B'=>104, 'START C'=>105, 'STOP'=>106));*/ - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - // Each characters contain 11 bars... - $characterLength = 11 * $this->_barThinWidth * $this->_factor; - $convertedChars = count($this->_convertToBarcodeChars($this->getText())); - if ($this->_withChecksum) { - $convertedChars++; - } - $encodedData = $convertedChars * $characterLength; - // ...except the STOP character (13) - $encodedData += $characterLength + 2 * $this->_barThinWidth * $this->_factor; - $width = $quietZone + $encodedData + $quietZone; - return $width; - } - - /** - * Partial check of code128 barcode - * @return void - */ - protected function _checkParams() - { - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - - $convertedChars = $this->_convertToBarcodeChars($this->getText()); - - if ($this->_withChecksum) { - $convertedChars[] = $this->getChecksum($this->getText()); - } - - // STOP CHARACTER - $convertedChars[] = 106; - - foreach ($convertedChars as $barcodeChar) { - $barcodePattern = $this->_codingMap[$barcodeChar]; - foreach (str_split($barcodePattern) as $c) { - $barcodeTable[] = array($c, $this->_barThinWidth, 0, 1); - } - } - return $barcodeTable; - } - - /** - * Checks if the next $length chars of $string starting at $pos are numeric. - * Returns false if the end of the string is reached. - * @param string $string String to search - * @param int $pos Starting position - * @param int $length Length to search - * @return bool - */ - protected static function _isDigit($string, $pos, $length = 2) - { - if ($pos + $length > strlen($string)) { - return false; - } - - for ($i = $pos; $i < $pos + $length; $i++) { - if (!is_numeric($string[$i])) { - return false; - } - } - return true; - } - - /** - * Convert string to barcode string - * - * @param $string - * @return array - */ - protected function _convertToBarcodeChars($string) - { - $string = (string) $string; - if (!strlen($string)) { - return array(); - } - - if (isset($this->_convertedText[md5($string)])) { - return $this->_convertedText[md5($string)]; - } - - $currentCharset = null; - $sum = 0; - $fak = 0; - $result = array(); - - for ($pos = 0; $pos < strlen($string); $pos++) { - $char = $string[$pos]; - $code = null; - - if (self::_isDigit($string, $pos, 4) && $currentCharset != 'C' - || self::_isDigit($string, $pos, 2) && $currentCharset == 'C') { - /** - * Switch to C if the next 4 chars are numeric or stay C if the next 2 - * chars are numeric - */ - if ($currentCharset != 'C') { - if ($pos == 0) { - $code = array_search("START C", $this->_charSets['C']); - } else { - $code = array_search("Code C", $this->_charSets[$currentCharset]); - } - $result[] = $code; - $currentCharset = 'C'; - } - } else if (in_array($char, $this->_charSets['B']) && $currentCharset != 'B' - && !(in_array($char, $this->_charSets['A']) && $currentCharset == 'A')) { - /** - * Switch to B as B contains the char and B is not the current charset. - */ - if ($pos == 0) { - $code = array_search("START B", $this->_charSets['B']); - } else { - $code = array_search("Code B", $this->_charSets[$currentCharset]); - } - $result[] = $code; - $currentCharset = 'B'; - } else if (array_key_exists($char, $this->_charSets['A']) && $currentCharset != 'A' - && !(array_key_exists($char, $this->_charSets['B']) && $currentCharset == 'B')) { - /** - * Switch to C as C contains the char and C is not the current charset. - */ - if ($pos == 0) { - $code = array_search("START A", $this->_charSets['A']); - } else { - $code =array_search("Code A", $this->_charSets[$currentCharset]); - } - $result[] = $code; - $currentCharset = 'A'; - } - - if ($currentCharset == 'C') { - $code = array_search(substr($string, $pos, 2), $this->_charSets['C']); - $pos++; //Two chars from input - } else { - $code = array_search($string[$pos], $this->_charSets[$currentCharset]); - } - $result[] = $code; - } - - $this->_convertedText[md5($string)] = $result; - return $result; - } - - /** - * Set text to encode - * @param string $value - * @return Zend_Barcode_Object - */ - public function setText($value) - { - $this->_text = $value; - return $this; - } - - /** - * Retrieve text to encode - * @return string - */ - public function getText() - { - return $this->_text; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $tableOfChars = $this->_convertToBarcodeChars($text); - - $sum = $tableOfChars[0]; - unset($tableOfChars[0]); - - $k = 1; - foreach ($tableOfChars as $char) { - $sum += ($k++) * $char; - } - - $checksum = $sum % 103; - - return $checksum; - } - - /** - * Standard validation for most of barcode objects - * - * @param string $value - * @param array $options - * @return bool - */ - protected function _validateText($value, $options = array()) - { - // @TODO: add code128 validator - return true; - } -} diff --git a/lib/Zend/Barcode/Object/Code25.php b/lib/Zend/Barcode/Object/Code25.php deleted file mode 100644 index 388c979a2e9..00000000000 --- a/lib/Zend/Barcode/Object/Code25.php +++ /dev/null @@ -1,143 +0,0 @@ - '00110', - '1' => '10001', - '2' => '01001', - '3' => '11000', - '4' => '00101', - '5' => '10100', - '6' => '01100', - '7' => '00011', - '8' => '10010', - '9' => '01010', - ); - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (2 * $this->_barThickWidth + 4 * $this->_barThinWidth) * $this->_factor; - $characterLength = (3 * $this->_barThinWidth + 2 * $this->_barThickWidth + 5 * $this->_barThinWidth) - * $this->_factor; - $encodedData = strlen($this->getText()) * $characterLength; - $stopCharacter = (2 * $this->_barThickWidth + 4 * $this->_barThinWidth) * $this->_factor; - return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Partial check of interleaved 2 of 5 barcode - * @return void - */ - protected function _checkParams() - { - $this->_checkRatio(); - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - - // Start character (30301) - $barcodeTable[] = array(1 , $this->_barThickWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThickWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth); - - $text = str_split($this->getText()); - foreach ($text as $char) { - $barcodeChar = str_split($this->_codingMap[$char]); - foreach ($barcodeChar as $c) { - /* visible, width, top, length */ - $width = $c ? $this->_barThickWidth : $this->_barThinWidth; - $barcodeTable[] = array(1 , $width , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth); - } - } - - // Stop character (30103) - $barcodeTable[] = array(1 , $this->_barThickWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThickWidth , 0 , 1); - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $factor = 3; - $checksum = 0; - - for ($i = strlen($text); $i > 0; $i --) { - $checksum += intval($text[$i - 1]) * $factor; - $factor = 4 - $factor; - } - - $checksum = (10 - ($checksum % 10)) % 10; - - return $checksum; - } -} diff --git a/lib/Zend/Barcode/Object/Code25interleaved.php b/lib/Zend/Barcode/Object/Code25interleaved.php deleted file mode 100644 index 19b68536507..00000000000 --- a/lib/Zend/Barcode/Object/Code25interleaved.php +++ /dev/null @@ -1,179 +0,0 @@ -_barcodeLength = 'even'; - } - - /** - * Activate/deactivate drawing of bearer bars - * @param boolean $value - * @return Zend_Barcode_Object_Int25 - */ - public function setWithBearerBars($value) - { - $this->_withBearerBars = (bool) $value; - return $this; - } - - /** - * Retrieve if bearer bars are enabled - * @return boolean - */ - public function getWithBearerBars() - { - return $this->_withBearerBars; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (4 * $this->_barThinWidth) * $this->_factor; - $characterLength = (3 * $this->_barThinWidth + 2 * $this->_barThickWidth) * $this->_factor; - $encodedData = strlen($this->getText()) * $characterLength; - $stopCharacter = ($this->_barThickWidth + 2 * $this->_barThinWidth) * $this->_factor; - return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - if ($this->_withBearerBars) { - $this->_withBorder = false; - } - - // Start character (0000) - $barcodeTable[] = array(1, $this->_barThinWidth, 0, 1); - $barcodeTable[] = array(0, $this->_barThinWidth, 0, 1); - $barcodeTable[] = array(1, $this->_barThinWidth, 0, 1); - $barcodeTable[] = array(0, $this->_barThinWidth, 0, 1); - - // Encoded $text - $text = $this->getText(); - for ($i = 0; $i < strlen($text); $i += 2) { // Draw 2 chars at a time - $char1 = substr($text, $i, 1); - $char2 = substr($text, $i + 1, 1); - - // Interleave - for ($ibar = 0; $ibar < 5; $ibar ++) { - // Draws char1 bar (fore color) - $barWidth = (substr($this->_codingMap[$char1], $ibar, 1)) - ? $this->_barThickWidth - : $this->_barThinWidth; - - $barcodeTable[] = array(1, $barWidth, 0, 1); - - // Left space corresponding to char2 (background color) - $barWidth = (substr($this->_codingMap[$char2], $ibar, 1)) - ? $this->_barThickWidth - : $this->_barThinWidth; - $barcodeTable[] = array(0, $barWidth, 0 , 1); - } - } - - // Stop character (100) - $barcodeTable[] = array(1 , $this->_barThickWidth, 0, 1); - $barcodeTable[] = array(0 , $this->_barThinWidth, 0, 1); - $barcodeTable[] = array(1 , $this->_barThinWidth, 0, 1); - return $barcodeTable; - } - - /** - * Drawing of bearer bars (if enabled) - * - * @return void - */ - protected function _postDrawBarcode() - { - if (!$this->_withBearerBars) { - return; - } - - $width = $this->_barThickWidth * $this->_factor; - $point1 = $this->_rotate(-1, -1); - $point2 = $this->_rotate($this->_calculateWidth() - 1, -1); - $point3 = $this->_rotate($this->_calculateWidth() - 1, $width - 1); - $point4 = $this->_rotate(-1, $width - 1); - $this->_addPolygon(array( - $point1, - $point2, - $point3, - $point4, - )); - $point1 = $this->_rotate( - 0, - 0 + $this->_barHeight * $this->_factor - 1 - ); - $point2 = $this->_rotate( - $this->_calculateWidth() - 1, - 0 + $this->_barHeight * $this->_factor - 1 - ); - $point3 = $this->_rotate( - $this->_calculateWidth() - 1, - 0 + $this->_barHeight * $this->_factor - $width - ); - $point4 = $this->_rotate( - 0, - 0 + $this->_barHeight * $this->_factor - $width - ); - $this->_addPolygon(array( - $point1, - $point2, - $point3, - $point4, - )); - } -} diff --git a/lib/Zend/Barcode/Object/Code39.php b/lib/Zend/Barcode/Object/Code39.php deleted file mode 100644 index 637f9e11c20..00000000000 --- a/lib/Zend/Barcode/Object/Code39.php +++ /dev/null @@ -1,188 +0,0 @@ - '000110100', - '1' => '100100001', - '2' => '001100001', - '3' => '101100000', - '4' => '000110001', - '5' => '100110000', - '6' => '001110000', - '7' => '000100101', - '8' => '100100100', - '9' => '001100100', - 'A' => '100001001', - 'B' => '001001001', - 'C' => '101001000', - 'D' => '000011001', - 'E' => '100011000', - 'F' => '001011000', - 'G' => '000001101', - 'H' => '100001100', - 'I' => '001001100', - 'J' => '000011100', - 'K' => '100000011', - 'L' => '001000011', - 'M' => '101000010', - 'N' => '000010011', - 'O' => '100010010', - 'P' => '001010010', - 'Q' => '000000111', - 'R' => '100000110', - 'S' => '001000110', - 'T' => '000010110', - 'U' => '110000001', - 'V' => '011000001', - 'W' => '111000000', - 'X' => '010010001', - 'Y' => '110010000', - 'Z' => '011010000', - '-' => '010000101', - '.' => '110000100', - ' ' => '011000100', - '$' => '010101000', - '/' => '010100010', - '+' => '010001010', - '%' => '000101010', - '*' => '010010100', - ); - - /** - * Partial check of Code39 barcode - * @return void - */ - protected function _checkParams() - { - $this->_checkRatio(); - } - - /** - * Width of the barcode (in pixels) - * @return int - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $characterLength = (6 * $this->_barThinWidth + 3 * $this->_barThickWidth + 1) * $this->_factor; - $encodedData = strlen($this->getText()) * $characterLength - $this->_factor; - return $quietZone + $encodedData + $quietZone; - } - - /** - * Set text to encode - * @param string $value - * @return Zend_Barcode_Object - */ - public function setText($value) - { - $this->_text = $value; - return $this; - } - - /** - * Retrieve text to display - * @return string - */ - public function getText() - { - return '*' . parent::getText() . '*'; - } - - /** - * Retrieve text to display - * @return string - */ - public function getTextToDisplay() - { - $text = parent::getTextToDisplay(); - if (substr($text, 0, 1) != '*' && substr($text, -1) != '*') { - return '*' . $text . '*'; - } else { - return $text; - } - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $text = str_split($this->getText()); - $barcodeTable = array(); - foreach ($text as $char) { - $barcodeChar = str_split($this->_codingMap[$char]); - $visible = true; - foreach ($barcodeChar as $c) { - /* visible, width, top, length */ - $width = $c ? $this->_barThickWidth : $this->_barThinWidth; - $barcodeTable[] = array((int) $visible, $width, 0, 1); - $visible = ! $visible; - } - $barcodeTable[] = array(0 , $this->_barThinWidth); - } - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $text = str_split($text); - $charset = array_flip(array_keys($this->_codingMap)); - $checksum = 0; - foreach ($text as $character) { - $checksum += $charset[$character]; - } - return array_search(($checksum % 43), $charset); - } -} diff --git a/lib/Zend/Barcode/Object/Ean13.php b/lib/Zend/Barcode/Object/Ean13.php deleted file mode 100644 index 0e79e75dc28..00000000000 --- a/lib/Zend/Barcode/Object/Ean13.php +++ /dev/null @@ -1,225 +0,0 @@ - array( - 0 => "0001101", 1 => "0011001", 2 => "0010011", 3 => "0111101", 4 => "0100011", - 5 => "0110001", 6 => "0101111", 7 => "0111011", 8 => "0110111", 9 => "0001011" - ), - 'B' => array( - 0 => "0100111", 1 => "0110011", 2 => "0011011", 3 => "0100001", 4 => "0011101", - 5 => "0111001", 6 => "0000101", 7 => "0010001", 8 => "0001001", 9 => "0010111" - ), - 'C' => array( - 0 => "1110010", 1 => "1100110", 2 => "1101100", 3 => "1000010", 4 => "1011100", - 5 => "1001110", 6 => "1010000", 7 => "1000100", 8 => "1001000", 9 => "1110100" - )); - - protected $_parities = array( - 0 => array('A','A','A','A','A','A'), - 1 => array('A','A','B','A','B','B'), - 2 => array('A','A','B','B','A','B'), - 3 => array('A','A','B','B','B','A'), - 4 => array('A','B','A','A','B','B'), - 5 => array('A','B','B','A','A','B'), - 6 => array('A','B','B','B','A','A'), - 7 => array('A','B','A','B','A','B'), - 8 => array('A','B','A','B','B','A'), - 9 => array('A','B','B','A','B','A') - ); - - /** - * Default options for Postnet barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barcodeLength = 13; - $this->_mandatoryChecksum = true; - $this->_mandatoryQuietZones = true; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $middleCharacter = (5 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $encodedData = (7 * $this->_barThinWidth) * $this->_factor * 12; - return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Partial check of interleaved EAN/UPC barcode - * @return void - */ - protected function _checkParams() - {} - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - $height = ($this->_drawText) ? 1.1 : 1; - - // Start character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - - $textTable = str_split($this->getText()); - $parity = $this->_parities[$textTable[0]]; - - // First part - for ($i = 1; $i < 7; $i++) { - $bars = str_split($this->_codingMap[$parity[$i - 1]][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Middle character (01010) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - - // Second part - for ($i = 7; $i < 13; $i++) { - $bars = str_split($this->_codingMap['C'][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Stop character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $factor = 3; - $checksum = 0; - - for ($i = strlen($text); $i > 0; $i --) { - $checksum += intval($text[$i - 1]) * $factor; - $factor = 4 - $factor; - } - - $checksum = (10 - ($checksum % 10)) % 10; - - return $checksum; - } - - /** - * Partial function to draw text - * @return void - */ - protected function _drawText() - { - if (get_class($this) == 'Zend_Barcode_Object_Ean13') { - $this->_drawEan13Text(); - } else { - parent::_drawText(); - } - } - - protected function _drawEan13Text() - { - if ($this->_drawText) { - $text = $this->getTextToDisplay(); - $characterWidth = (7 * $this->_barThinWidth) * $this->_factor; - $leftPosition = $this->getQuietZone() - $characterWidth; - for ($i = 0; $i < $this->_barcodeLength; $i ++) { - $this->_addText( - $text[$i], - $this->_fontSize * $this->_factor, - $this->_rotate( - $leftPosition, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'left', - - $this->_orientation - ); - switch ($i) { - case 0: - $factor = 3; - break; - case 6: - $factor = 4; - break; - default: - $factor = 0; - } - $leftPosition = $leftPosition + $characterWidth + ($factor * $this->_barThinWidth * $this->_factor); - } - } - } -} diff --git a/lib/Zend/Barcode/Object/Ean2.php b/lib/Zend/Barcode/Object/Ean2.php deleted file mode 100644 index 94d332b885f..00000000000 --- a/lib/Zend/Barcode/Object/Ean2.php +++ /dev/null @@ -1,65 +0,0 @@ - array('A','A'), - 1 => array('A','B'), - 2 => array('B','A'), - 3 => array('B','B') - ); - - /** - * Default options for Ean2 barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barcodeLength = 2; - } - - protected function _getParity($i) - { - $modulo = $this->getText() % 4; - return $this->_parities[$modulo][$i]; - } -} diff --git a/lib/Zend/Barcode/Object/Ean5.php b/lib/Zend/Barcode/Object/Ean5.php deleted file mode 100644 index 785cc580560..00000000000 --- a/lib/Zend/Barcode/Object/Ean5.php +++ /dev/null @@ -1,147 +0,0 @@ - array('B','B','A','A','A'), - 1 => array('B','A','B','A','A'), - 2 => array('B','A','A','B','A'), - 3 => array('B','A','A','A','B'), - 4 => array('A','B','B','A','A'), - 5 => array('A','A','B','B','A'), - 6 => array('A','A','A','B','B'), - 7 => array('A','B','A','B','A'), - 8 => array('A','B','A','A','B'), - 9 => array('A','A','B','A','B') - ); - - /** - * Default options for Ean5 barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barcodeLength = 5; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (5 * $this->_barThinWidth) * $this->_factor; - $middleCharacter = (2 * $this->_barThinWidth) * $this->_factor; - $encodedData = (7 * $this->_barThinWidth) * $this->_factor; - return $quietZone + $startCharacter + ($this->_barcodeLength - 1) * $middleCharacter + $this->_barcodeLength * $encodedData + $quietZone; - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - - // Start character (01011) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - - $firstCharacter = true; - $textTable = str_split($this->getText()); - - // Characters - for ($i = 0; $i < $this->_barcodeLength; $i++) { - if ($firstCharacter) { - $firstCharacter = false; - } else { - // Intermediate character (01) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - } - $bars = str_split($this->_codingMap[$this->_getParity($i)][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $checksum = 0; - - for ($i = 0 ; $i < $this->_barcodeLength; $i ++) { - $checksum += intval($text[$i]) * ($i % 2 ? 9 : 3); - } - - return ($checksum % 10); - } - - protected function _getParity($i) - { - $checksum = $this->getChecksum($this->getText()); - return $this->_parities[$checksum][$i]; - } - - /** - * Retrieve text to encode - * @return string - */ - public function getText() - { - return $this->_addLeadingZeros($this->_text); - } -} diff --git a/lib/Zend/Barcode/Object/Ean8.php b/lib/Zend/Barcode/Object/Ean8.php deleted file mode 100644 index cd380a54931..00000000000 --- a/lib/Zend/Barcode/Object/Ean8.php +++ /dev/null @@ -1,177 +0,0 @@ -_barcodeLength = 8; - $this->_mandatoryChecksum = true; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $middleCharacter = (5 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $encodedData = (7 * $this->_barThinWidth) * $this->_factor * 8; - return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - $height = ($this->_drawText) ? 1.1 : 1; - - // Start character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - - $textTable = str_split($this->getText()); - - // First part - for ($i = 0; $i < 4; $i++) { - $bars = str_split($this->_codingMap['A'][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Middle character (01010) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - - // Second part - for ($i = 4; $i < 8; $i++) { - $bars = str_split($this->_codingMap['C'][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Stop character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - return $barcodeTable; - } - - /** - * Partial function to draw text - * @return void - */ - protected function _drawText() - { - if ($this->_drawText) { - $text = $this->getTextToDisplay(); - $characterWidth = (7 * $this->_barThinWidth) * $this->_factor; - $leftPosition = $this->getQuietZone() + (3 * $this->_barThinWidth) * $this->_factor; - for ($i = 0; $i < $this->_barcodeLength; $i ++) { - $this->_addText( - $text[$i], - $this->_fontSize * $this->_factor, - $this->_rotate( - $leftPosition, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'left', - - $this->_orientation - ); - switch ($i) { - case 3: - $factor = 4; - break; - default: - $factor = 0; - } - $leftPosition = $leftPosition + $characterWidth + ($factor * $this->_barThinWidth * $this->_factor); - } - } - } - - /** - * Particular validation for Ean8 barcode objects - * (to suppress checksum character substitution) - * - * @param string $value - * @param array $options - * @throws Zend_Barcode_Object_Exception - */ - protected function _validateText($value, $options = array()) - { - $validator = new Zend_Validate_Barcode(array( - 'adapter' => 'ean8', - 'checksum' => false, - )); - - $value = $this->_addLeadingZeros($value, true); - - if (!$validator->isValid($value)) { - $message = implode("\n", $validator->getMessages()); - - /** - * @see Zend_Barcode_Object_Exception - */ - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception($message); - } - } -} diff --git a/lib/Zend/Barcode/Object/Error.php b/lib/Zend/Barcode/Object/Error.php deleted file mode 100644 index 7b2c70e4496..00000000000 --- a/lib/Zend/Barcode/Object/Error.php +++ /dev/null @@ -1,104 +0,0 @@ -_instructions = array(); - $this->_addText('ERROR:', 10, array(5 , 18), $this->_font, 0, 'left'); - $this->_addText($this->_text, 10, array(5 , 32), $this->_font, 0, 'left'); - return $this->_instructions; - } - - /** - * For compatibility reason - * @return void - */ - protected function _prepareBarcode() - { - } - - /** - * For compatibility reason - * @return void - */ - protected function _checkParams() - { - } - - /** - * For compatibility reason - * @return void - */ - protected function _calculateBarcodeWidth() - { - } -} diff --git a/lib/Zend/Barcode/Object/Exception.php b/lib/Zend/Barcode/Object/Exception.php deleted file mode 100644 index 356016feff1..00000000000 --- a/lib/Zend/Barcode/Object/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_barcodeLength = 12; - $this->_mandatoryChecksum = true; - } - - /** - * Retrieve text to display - * @return string - */ - public function getTextToDisplay() - { - return preg_replace('/([0-9]{2})([0-9]{3})([0-9]{3})([0-9]{3})([0-9])/', - '$1.$2 $3.$4 $5', - $this->getText()); - } - - /** - * Check allowed characters - * @param string $value - * @return string - * @throws Zend_Barcode_Object_Exception - */ - public function validateText($value) - { - $this->_validateText($value, array('validator' => $this->getType())); - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $checksum = 0; - - for ($i = strlen($text); $i > 0; $i --) { - $checksum += intval($text[$i - 1]) * (($i % 2) ? 4 : 9); - } - - $checksum = (10 - ($checksum % 10)) % 10; - - return $checksum; - } -} diff --git a/lib/Zend/Barcode/Object/Itf14.php b/lib/Zend/Barcode/Object/Itf14.php deleted file mode 100644 index e42b1dd129c..00000000000 --- a/lib/Zend/Barcode/Object/Itf14.php +++ /dev/null @@ -1,49 +0,0 @@ -_barcodeLength = 14; - $this->_mandatoryChecksum = true; - } -} diff --git a/lib/Zend/Barcode/Object/Leitcode.php b/lib/Zend/Barcode/Object/Leitcode.php deleted file mode 100644 index e0b802a2e93..00000000000 --- a/lib/Zend/Barcode/Object/Leitcode.php +++ /dev/null @@ -1,64 +0,0 @@ -_barcodeLength = 14; - $this->_mandatoryChecksum = true; - } - - /** - * Retrieve text to display - * @return string - */ - public function getTextToDisplay() - { - return preg_replace('/([0-9]{5})([0-9]{3})([0-9]{3})([0-9]{2})([0-9])/', - '$1.$2.$3.$4 $5', - $this->getText()); - } -} diff --git a/lib/Zend/Barcode/Object/ObjectAbstract.php b/lib/Zend/Barcode/Object/ObjectAbstract.php deleted file mode 100644 index 0fd7a8bfc1a..00000000000 --- a/lib/Zend/Barcode/Object/ObjectAbstract.php +++ /dev/null @@ -1,1440 +0,0 @@ -_getDefaultOptions(); - if (self::$_staticFont !== null) { - $this->_font = self::$_staticFont; - } - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - if (is_array($options)) { - $this->setOptions($options); - } - $this->_type = strtolower( - substr(get_class($this), strlen($this->_barcodeNamespace) + 1) - ); - if ($this->_mandatoryChecksum) { - $this->_withChecksum = true; - $this->_withChecksumInText = true; - } - } - - /** - * Set default options for particular object - */ - protected function _getDefaultOptions() - { - } - - /** - * Set barcode state from options array - * - * @param array $options - * @return $this - */ - public function setOptions($options) - { - foreach ($options as $key => $value) { - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - return $this; - } - - /** - * Set barcode state from config object - * - * @param Zend_Config $config - * @return $this - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Set barcode namespace for autoloading - * - * @param string $namespace - * @return $this - */ - public function setBarcodeNamespace($namespace) - { - $this->_barcodeNamespace = $namespace; - return $this; - } - - /** - * Retrieve barcode namespace - * - * @return string - */ - public function getBarcodeNamespace() - { - return $this->_barcodeNamespace; - } - - /** - * Retrieve type of barcode - * - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * Set height of the barcode bar - * - * @param integer $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setBarHeight($value) - { - if (intval($value) <= 0) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Bar height must be greater than 0' - ); - } - $this->_barHeight = intval($value); - return $this; - } - - /** - * Get height of the barcode bar - * - * @return integer - */ - public function getBarHeight() - { - return $this->_barHeight; - } - - /** - * Set thickness of thin bar - * - * @param integer $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setBarThinWidth($value) - { - if (intval($value) <= 0) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Bar width must be greater than 0' - ); - } - $this->_barThinWidth = intval($value); - return $this; - } - - /** - * Get thickness of thin bar - * - * @return integer - */ - public function getBarThinWidth() - { - return $this->_barThinWidth; - } - - /** - * Set thickness of thick bar - * - * @param integer $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setBarThickWidth($value) - { - if (intval($value) <= 0) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Bar width must be greater than 0' - ); - } - $this->_barThickWidth = intval($value); - return $this; - } - - /** - * Get thickness of thick bar - * - * @return integer - */ - public function getBarThickWidth() - { - return $this->_barThickWidth; - } - - /** - * Set factor applying to - * thinBarWidth - thickBarWidth - barHeight - fontSize - * - * @param int|float|string|bool $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setFactor($value) - { - if (floatval($value) <= 0) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Factor must be greater than 0' - ); - } - $this->_factor = floatval($value); - return $this; - } - - /** - * Get factor applying to - * thinBarWidth - thickBarWidth - barHeight - fontSize - * - * @return integer - */ - public function getFactor() - { - return $this->_factor; - } - - /** - * Set color of the barcode and text - * - * @param string $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setForeColor($value) - { - if (preg_match('`\#[0-9A-F]{6}`', $value)) { - $this->_foreColor = hexdec($value); - } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) { - $this->_foreColor = intval($value); - } else { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Text color must be set as #[0-9A-F]{6}' - ); - } - return $this; - } - - /** - * Retrieve color of the barcode and text - * - * @return unknown - */ - public function getForeColor() - { - return $this->_foreColor; - } - - /** - * Set the color of the background - * - * @param integer $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setBackgroundColor($value) - { - if (preg_match('`\#[0-9A-F]{6}`', $value)) { - $this->_backgroundColor = hexdec($value); - } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) { - $this->_backgroundColor = intval($value); - } else { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Background color must be set as #[0-9A-F]{6}' - ); - } - return $this; - } - - /** - * Retrieve background color of the image - * - * @return integer - */ - public function getBackgroundColor() - { - return $this->_backgroundColor; - } - - /** - * Activate/deactivate drawing of the bar - * - * @param boolean $value - * @return $this - */ - public function setWithBorder($value) - { - $this->_withBorder = (bool) $value; - return $this; - } - - /** - * Retrieve if border are draw or not - * - * @return boolean - */ - public function getWithBorder() - { - return $this->_withBorder; - } - - /** - * Activate/deactivate drawing of the quiet zones - * - * @param boolean $value - * @return $this - */ - public function setWithQuietZones($value) - { - $this->_withQuietZones = (bool) $value; - return $this; - } - - /** - * Retrieve if quiet zones are draw or not - * - * @return boolean - */ - public function getWithQuietZones() - { - return $this->_withQuietZones; - } - - /** - * Allow fast inversion of font/bars color and background color - * - * @return $this - */ - public function setReverseColor() - { - $tmp = $this->_foreColor; - $this->_foreColor = $this->_backgroundColor; - $this->_backgroundColor = $tmp; - - return $this; - } - - /** - * Set orientation of barcode and text - * - * @param int|float|string|bool $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setOrientation($value) - { - $value = floatval($value); - $this->_orientation = $value - floor($value / 360) * 360; - return $this; - } - - /** - * Retrieve orientation of barcode and text - * - * @return float - */ - public function getOrientation() - { - return $this->_orientation; - } - - /** - * Set text to encode - * - * @param string $value - * @return $this - */ - public function setText($value) - { - $this->_text = trim($value); - return $this; - } - - /** - * Retrieve text to encode - * - * @return string - */ - public function getText() - { - $text = $this->_text; - if ($this->_withChecksum) { - $text .= $this->getChecksum($this->_text); - } - return $this->_addLeadingZeros($text); - } - - /** - * Automatically add leading zeros if barcode length is fixed - * - * @param string $text - * @param boolean $withoutChecksum - * @return string - */ - protected function _addLeadingZeros($text, $withoutChecksum = false) - { - if ($this->_barcodeLength && $this->_addLeadingZeros) { - $omitChecksum = (int) ($this->_withChecksum && $withoutChecksum); - if (is_int($this->_barcodeLength)) { - $length = $this->_barcodeLength - $omitChecksum; - if (strlen($text) < $length) { - $text = str_repeat('0', $length - strlen($text)) . $text; - } - } else { - if ($this->_barcodeLength == 'even') { - $text = ((strlen($text) - $omitChecksum) % 2 ? '0' . $text : $text); - } - } - } - return $text; - } - - /** - * Retrieve text to encode - * - * @return string - */ - public function getRawText() - { - return $this->_text; - } - - /** - * Retrieve text to display - * - * @return string - */ - public function getTextToDisplay() - { - if ($this->_withChecksumInText) { - return $this->getText(); - } else { - return $this->_addLeadingZeros($this->_text, true); - } - } - - /** - * Activate/deactivate drawing of text to encode - * - * @param boolean $value - * @return $this - */ - public function setDrawText($value) - { - $this->_drawText = (bool) $value; - return $this; - } - - /** - * Retrieve if drawing of text to encode is enabled - * - * @return boolean - */ - public function getDrawText() - { - return $this->_drawText; - } - - /** - * Activate/deactivate the adjustment of the position - * of the characters to the position of the bars - * - * @param boolean $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setStretchText($value) - { - $this->_stretchText = (bool) $value; - return $this; - } - - /** - * Retrieve if the adjustment of the position of the characters - * to the position of the bars is enabled - * - * @return boolean - */ - public function getStretchText() - { - return $this->_stretchText; - } - - /** - * Activate/deactivate the automatic generation - * of the checksum character - * added to the barcode text - * - * @param boolean $value - * @return $this - */ - public function setWithChecksum($value) - { - if (!$this->_mandatoryChecksum) { - $this->_withChecksum = (bool) $value; - } - return $this; - } - - /** - * Retrieve if the checksum character is automatically - * added to the barcode text - * - * @return boolean - */ - public function getWithChecksum() - { - return $this->_withChecksum; - } - - /** - * Activate/deactivate the automatic generation - * of the checksum character - * added to the barcode text - * - * @param boolean $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setWithChecksumInText($value) - { - if (!$this->_mandatoryChecksum) { - $this->_withChecksumInText = (bool) $value; - } - - return $this; - } - - /** - * Retrieve if the checksum character is automatically - * added to the barcode text - * - * @return boolean - */ - public function getWithChecksumInText() - { - return $this->_withChecksumInText; - } - - /** - * Set the font for all instances of barcode - * - * @param string $font - */ - public static function setBarcodeFont($font) - { - if (is_string($font) || (is_int($font) && $font >= 1 && $font <= 5)) { - self::$_staticFont = $font; - } - } - - /** - * Set the font: - * - if integer between 1 and 5, use gd built-in fonts - * - if string, $value is assumed to be the path to a TTF font - * - * @param integer|string $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setFont($value) - { - if (is_int($value) && $value >= 1 && $value <= 5) { - if (!extension_loaded('gd')) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'GD extension is required to use numeric font' - ); - } - - // Case of numeric font with GD - $this->_font = $value; - - // In this case font size is given by: - $this->_fontSize = imagefontheight($value); - } elseif (is_string($value)) { - $this->_font = $value; - } else { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - sprintf( - 'Invalid font "%s" provided to setFont()', - $value - ) - ); - } - return $this; - } - - /** - * Retrieve the font - * - * @return integer|string - */ - public function getFont() - { - return $this->_font; - } - - /** - * Set the size of the font in case of TTF - * - * @param float $value - * @return $this - * @throws Zend_Barcode_Object_Exception - */ - public function setFontSize($value) - { - if (is_numeric($this->_font)) { - // Case of numeric font with GD - return $this; - } - - if (!is_numeric($value)) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Font size must be a numeric value' - ); - } - - $this->_fontSize = $value; - return $this; - } - - /** - * Retrieve the size of the font in case of TTF - * - * @return float - */ - public function getFontSize() - { - return $this->_fontSize; - } - - /** - * Quiet zone before first bar - * and after the last bar - * - * @return integer - */ - public function getQuietZone() - { - if ($this->_withQuietZones || $this->_mandatoryQuietZones) { - return 10 * $this->_barThinWidth * $this->_factor; - } else { - return 0; - } - } - - /** - * Add an instruction in the array of instructions - * - * @param array $instruction - */ - protected function _addInstruction(array $instruction) - { - $this->_instructions[] = $instruction; - } - - /** - * Retrieve the set of drawing instructions - * - * @return array - */ - public function getInstructions() - { - return $this->_instructions; - } - - /** - * Add a polygon drawing instruction in the set of instructions - * - * @param array $points - * @param integer $color - * @param boolean $filled - */ - protected function _addPolygon(array $points, $color = null, $filled = true) - { - if ($color === null) { - $color = $this->_foreColor; - } - $this->_addInstruction( - array( - 'type' => 'polygon', - 'points' => $points, - 'color' => $color, - 'filled' => $filled, - ) - ); - } - - /** - * Add a text drawing instruction in the set of instructions - * - * @param string $text - * @param float $size - * @param array $position - * @param string $font - * @param integer $color - * @param string $alignment - * @param float|int $orientation - */ - protected function _addText( - $text, - $size, - $position, - $font, - $color, - $alignment = 'center', - $orientation = 0 - ) { - if ($color === null) { - $color = $this->_foreColor; - } - $this->_addInstruction( - array( - 'type' => 'text', - 'text' => $text, - 'size' => $size, - 'position' => $position, - 'font' => $font, - 'color' => $color, - 'alignment' => $alignment, - 'orientation' => $orientation, - ) - ); - } - - /** - * Checking of parameters after all settings - * - * @return bool - */ - public function checkParams() - { - $this->_checkText(); - $this->_checkFontAndOrientation(); - $this->_checkParams(); - return true; - } - - /** - * Check if a text is really provided to barcode - * - * @param string|null $value - * @throws Zend_Barcode_Object_Exception - */ - protected function _checkText($value = null) - { - if ($value === null) { - $value = $this->_text; - } - if (!strlen($value)) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'A text must be provide to Barcode before drawing' - ); - } - $this->validateText($value); - } - - /** - * Check the ratio between the thick and the thin bar - * - * @param int $min - * @param int $max - * @throws Zend_Barcode_Object_Exception - */ - protected function _checkRatio($min = 2, $max = 3) - { - $ratio = $this->_barThickWidth / $this->_barThinWidth; - if (!($ratio >= $min && $ratio <= $max)) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - sprintf( - 'Ratio thick/thin bar must be between %0.1f and %0.1f (actual %0.3f)', - $min, - $max, - $ratio - ) - ); - } - } - - /** - * Drawing with an angle is just allow TTF font - * - * @throws Zend_Barcode_Object_Exception - */ - protected function _checkFontAndOrientation() - { - if (is_numeric($this->_font) && $this->_orientation != 0) { - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception( - 'Only drawing with TTF font allow orientation of the barcode.' - ); - } - } - - /** - * Width of the result image (before any rotation) - * - * @return integer - */ - protected function _calculateWidth() - { - return (int) $this->_withBorder - + $this->_calculateBarcodeWidth() - + (int) $this->_withBorder; - } - - /** - * Calculate the width of the barcode - * - * @return integer - */ - abstract protected function _calculateBarcodeWidth(); - - /** - * Height of the result object - * - * @return int - */ - protected function _calculateHeight() - { - return (int) $this->_withBorder * 2 - + $this->_calculateBarcodeHeight() - + (int) $this->_withBorder * 2; - } - - /** - * Height of the barcode - * - * @return int - */ - protected function _calculateBarcodeHeight() - { - $textHeight = 0; - $extraHeight = 0; - if ($this->_drawText) { - $textHeight += $this->_fontSize; - $extraHeight = 2; - } - - return ($this->_barHeight + $textHeight) * $this->_factor - + $extraHeight; - } - - /** - * Get height of the result object - * - * @param bool $recalculate - * @return int - */ - public function getHeight($recalculate = false) - { - if ($this->_height === null || $recalculate) { - $this->_height = - abs( - $this->_calculateHeight() * cos( - $this->_orientation / 180 * pi() - ) - ) - + abs( - $this->_calculateWidth() * sin( - $this->_orientation / 180 * pi() - ) - ); - } - return $this->_height; - } - - /** - * Get width of the result object - * - * @param bool $recalculate - * @return int - */ - public function getWidth($recalculate = false) - { - if ($this->_width === null || $recalculate) { - $this->_width = - abs( - $this->_calculateWidth() * cos( - $this->_orientation / 180 * pi() - ) - ) - + abs( - $this->_calculateHeight() * sin( - $this->_orientation / 180 * pi() - ) - ); - } - return $this->_width; - } - - /** - * Calculate the offset from the left of the object - * if an orientation is activated - * - * @param bool $recalculate - * @return float - */ - public function getOffsetLeft($recalculate = false) - { - if ($this->_offsetLeft === null || $recalculate) { - $this->_offsetLeft = - min(array( - 0 * cos( - $this->_orientation / 180 * pi()) - 0 * sin( - $this->_orientation / 180 * pi()), - 0 * cos( - $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin( - $this->_orientation / 180 * pi()), - $this->_calculateBarcodeWidth() * cos( - $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin( - $this->_orientation / 180 * pi()), - $this->_calculateBarcodeWidth() * cos( - $this->_orientation / 180 * pi()) - 0 * sin( - $this->_orientation / 180 * pi()), - )); - } - return $this->_offsetLeft; - } - - /** - * Calculate the offset from the top of the object - * if an orientation is activated - * - * @param bool $recalculate - * @return float - */ - public function getOffsetTop($recalculate = false) - { - if ($this->_offsetTop === null || $recalculate) { - $this->_offsetTop = - min(array( - 0 * cos( - $this->_orientation / 180 * pi()) + 0 * sin( - $this->_orientation / 180 * pi()), - $this->_calculateBarcodeHeight() * cos( - $this->_orientation / 180 * pi()) + 0 * sin( - $this->_orientation / 180 * pi()), - $this->_calculateBarcodeHeight() * cos( - $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin( - $this->_orientation / 180 * pi()), - 0 * cos( - $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin( - $this->_orientation / 180 * pi()), - )); - } - return $this->_offsetTop; - } - - /** - * Apply rotation on a point in X/Y dimensions - * - * @param float $x1 x-position before rotation - * @param float $y1 y-position before rotation - * @return array Array of two elements corresponding to the new XY point - */ - protected function _rotate($x1, $y1) - { - $x2 = $x1 * cos($this->_orientation / 180 * pi()) - - $y1 * sin($this->_orientation / 180 * pi()) - + $this->getOffsetLeft(); - $y2 = $y1 * cos($this->_orientation / 180 * pi()) - + $x1 * sin($this->_orientation / 180 * pi()) - + $this->getOffsetTop(); - - return array( - intval($x2), - intval($y2) - ); - } - - /** - * Complete drawing of the barcode - * - * @return array Table of instructions - */ - public function draw() - { - $this->checkParams(); - $this->_drawBarcode(); - $this->_drawBorder(); - $this->_drawText(); - return $this->getInstructions(); - } - - /** - * Draw the barcode - */ - protected function _drawBarcode() - { - $barcodeTable = $this->_prepareBarcode(); - - $this->_preDrawBarcode(); - - $xpos = (int) $this->_withBorder; - $ypos = (int) $this->_withBorder; - - $point1 = $this->_rotate(0, 0); - $point2 = $this->_rotate(0, $this->_calculateHeight() - 1); - $point3 = $this->_rotate( - $this->_calculateWidth() - 1, - $this->_calculateHeight() - 1 - ); - $point4 = $this->_rotate($this->_calculateWidth() - 1, 0); - - $this->_addPolygon( - array( - $point1, - $point2, - $point3, - $point4 - ), $this->_backgroundColor - ); - - $xpos += $this->getQuietZone(); - $barLength = $this->_barHeight * $this->_factor; - - foreach ($barcodeTable as $bar) { - $width = $bar[1] * $this->_factor; - if ($bar[0]) { - $point1 = $this->_rotate($xpos, $ypos + $bar[2] * $barLength); - $point2 = $this->_rotate($xpos, $ypos + $bar[3] * $barLength); - $point3 = $this->_rotate( - $xpos + $width - 1, - $ypos + $bar[3] * $barLength - ); - $point4 = $this->_rotate( - $xpos + $width - 1, - $ypos + $bar[2] * $barLength - ); - $this->_addPolygon( - array( - $point1, - $point2, - $point3, - $point4, - ) - ); - } - $xpos += $width; - } - - $this->_postDrawBarcode(); - } - - /** - * Partial function to draw border - */ - protected function _drawBorder() - { - if ($this->_withBorder) { - $point1 = $this->_rotate(0, 0); - $point2 = $this->_rotate($this->_calculateWidth() - 1, 0); - $point3 = $this->_rotate( - $this->_calculateWidth() - 1, - $this->_calculateHeight() - 1 - ); - $point4 = $this->_rotate(0, $this->_calculateHeight() - 1); - $this->_addPolygon( - array( - $point1, - $point2, - $point3, - $point4, - $point1, - ), $this->_foreColor, false - ); - } - } - - /** - * Partial function to draw text - */ - protected function _drawText() - { - if ($this->_drawText) { - $text = $this->getTextToDisplay(); - if ($this->_stretchText) { - $textLength = strlen($text); - $space = ($this->_calculateWidth() - 2 * $this->getQuietZone()) / $textLength; - for ($i = 0; $i < $textLength; $i ++) { - $leftPosition = $this->getQuietZone() + $space * ($i + 0.5); - $this->_addText( - $text[$i], - $this->_fontSize * $this->_factor, - $this->_rotate( - $leftPosition, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'center', - - $this->_orientation - ); - } - } else { - $this->_addText( - $text, - $this->_fontSize * $this->_factor, - $this->_rotate( - $this->_calculateWidth() / 2, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'center', - - $this->_orientation - ); - } - } - } - - /** - * Check for invalid characters - * - * @param string $value Text to be ckecked - */ - public function validateText($value) - { - $this->_validateText($value); - } - - /** - * Standard validation for most of barcode objects - * - * @param string $value - * @param array $options - * @throws Zend_Barcode_Object_Exception - */ - protected function _validateText($value, $options = array()) - { - $validatorName = (isset($options['validator'])) ? $options['validator'] : $this->getType(); - - $validator = new Zend_Validate_Barcode( - array( - 'adapter' => $validatorName, - 'checksum' => false, - ) - ); - - $checksumCharacter = ''; - $withChecksum = false; - if ($this->_mandatoryChecksum) { - $checksumCharacter = $this->_substituteChecksumCharacter; - $withChecksum = true; - } - - $value = $this->_addLeadingZeros($value, $withChecksum) - . $checksumCharacter; - - if (!$validator->isValid($value)) { - $message = implode("\n", $validator->getMessages()); - - /** - * @see Zend_Barcode_Object_Exception - */ - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception($message); - } - } - - /** - * Each child must prepare the barcode and return - * a table like array( - * 0 => array( - * 0 => int (visible(black) or not(white)) - * 1 => int (width of the bar) - * 2 => float (0->1 position from the top of the beginning of the bar in %) - * 3 => float (0->1 position from the top of the end of the bar in %) - * ), - * 1 => ... - * ) - * - * @return array - */ - abstract protected function _prepareBarcode(); - - /** - * Checking of parameters after all settings - */ - abstract protected function _checkParams(); - - /** - * Allow each child to draw something else - */ - protected function _preDrawBarcode() - { - } - - /** - * Allow each child to draw something else - * (ex: bearer bars in interleaved 2 of 5 code) - */ - protected function _postDrawBarcode() - { - } -} diff --git a/lib/Zend/Barcode/Object/Planet.php b/lib/Zend/Barcode/Object/Planet.php deleted file mode 100644 index 780932887ab..00000000000 --- a/lib/Zend/Barcode/Object/Planet.php +++ /dev/null @@ -1,62 +0,0 @@ - "00111", - 1 => "11100", - 2 => "11010", - 3 => "11001", - 4 => "10110", - 5 => "10101", - 6 => "10011", - 7 => "01110", - 8 => "01101", - 9 => "01011" - ); -} diff --git a/lib/Zend/Barcode/Object/Postnet.php b/lib/Zend/Barcode/Object/Postnet.php deleted file mode 100644 index cf4c218d545..00000000000 --- a/lib/Zend/Barcode/Object/Postnet.php +++ /dev/null @@ -1,136 +0,0 @@ - "11000", - 1 => "00011", - 2 => "00101", - 3 => "00110", - 4 => "01001", - 5 => "01010", - 6 => "01100", - 7 => "10001", - 8 => "10010", - 9 => "10100" - ); - - /** - * Default options for Postnet barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barThinWidth = 2; - $this->_barHeight = 20; - $this->_drawText = false; - $this->_stretchText = true; - $this->_mandatoryChecksum = true; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (2 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (1 * $this->_barThinWidth) * $this->_factor; - $encodedData = (10 * $this->_barThinWidth) * $this->_factor * strlen($this->getText()); - return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Partial check of interleaved Postnet barcode - * @return void - */ - protected function _checkParams() - {} - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - - // Start character (1) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - - // Text to encode - $textTable = str_split($this->getText()); - foreach ($textTable as $char) { - $bars = str_split($this->_codingMap[$char]); - foreach ($bars as $b) { - $barcodeTable[] = array(1 , $this->_barThinWidth , 0.5 - $b * 0.5 , 1); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - } - } - - // Stop character (1) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $sum = array_sum(str_split($text)); - $checksum = (10 - ($sum % 10)) % 10; - return $checksum; - } -} diff --git a/lib/Zend/Barcode/Object/Royalmail.php b/lib/Zend/Barcode/Object/Royalmail.php deleted file mode 100644 index 40590f05936..00000000000 --- a/lib/Zend/Barcode/Object/Royalmail.php +++ /dev/null @@ -1,163 +0,0 @@ - '3300', '1' => '3210', '2' => '3201', '3' => '2310', '4' => '2301', '5' => '2211', - '6' => '3120', '7' => '3030', '8' => '3021', '9' => '2130', 'A' => '2121', 'B' => '2031', - 'C' => '3102', 'D' => '3012', 'E' => '3003', 'F' => '2112', 'G' => '2103', 'H' => '2013', - 'I' => '1320', 'J' => '1230', 'K' => '1221', 'L' => '0330', 'M' => '0321', 'N' => '0231', - 'O' => '1302', 'P' => '1212', 'Q' => '1203', 'R' => '0312', 'S' => '0303', 'T' => '0213', - 'U' => '1122', 'V' => '1032', 'W' => '1023', 'X' => '0132', 'Y' => '0123', 'Z' => '0033' - ); - - protected $_rows = array( - '0' => 1, '1' => 1, '2' => 1, '3' => 1, '4' => 1, '5' => 1, - '6' => 2, '7' => 2, '8' => 2, '9' => 2, 'A' => 2, 'B' => 2, - 'C' => 3, 'D' => 3, 'E' => 3, 'F' => 3, 'G' => 3, 'H' => 3, - 'I' => 4, 'J' => 4, 'K' => 4, 'L' => 4, 'M' => 4, 'N' => 4, - 'O' => 5, 'P' => 5, 'Q' => 5, 'R' => 5, 'S' => 5, 'T' => 5, - 'U' => 0, 'V' => 0, 'W' => 0, 'X' => 0, 'Y' => 0, 'Z' => 0, - ); - - protected $_columns = array( - '0' => 1, '1' => 2, '2' => 3, '3' => 4, '4' => 5, '5' => 0, - '6' => 1, '7' => 2, '8' => 3, '9' => 4, 'A' => 5, 'B' => 0, - 'C' => 1, 'D' => 2, 'E' => 3, 'F' => 4, 'G' => 5, 'H' => 0, - 'I' => 1, 'J' => 2, 'K' => 3, 'L' => 4, 'M' => 5, 'N' => 0, - 'O' => 1, 'P' => 2, 'Q' => 3, 'R' => 4, 'S' => 5, 'T' => 0, - 'U' => 1, 'V' => 2, 'W' => 3, 'X' => 4, 'Y' => 5, 'Z' => 0, - ); - - /** - * Default options for Postnet barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barThinWidth = 2; - $this->_barHeight = 20; - $this->_drawText = false; - $this->_stretchText = true; - $this->_mandatoryChecksum = true; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (2 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (1 * $this->_barThinWidth) * $this->_factor; - $encodedData = (8 * $this->_barThinWidth) * $this->_factor * strlen($this->getText()); - return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Partial check of interleaved Postnet barcode - * @return void - */ - protected function _checkParams() - {} - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - - // Start character (1) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 5/8); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - - // Text to encode - $textTable = str_split($this->getText()); - foreach ($textTable as $char) { - $bars = str_split($this->_codingMap[$char]); - foreach ($bars as $b) { - $barcodeTable[] = array(1 , $this->_barThinWidth , ($b > 1 ? 3/8 : 0) , ($b % 2 ? 5/8 : 1)); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , 1); - } - } - - // Stop character (1) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , 1); - return $barcodeTable; - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $this->_checkText($text); - $values = str_split($text); - $rowvalue = 0; - $colvalue = 0; - foreach($values as $row) { - $rowvalue += $this->_rows[$row]; - $colvalue += $this->_columns[$row]; - } - - $rowvalue %= 6; - $colvalue %= 6; - - $rowchkvalue = array_keys($this->_rows, $rowvalue); - $colchkvalue = array_keys($this->_columns, $colvalue); - return current(array_intersect($rowchkvalue, $colchkvalue)); - } -} diff --git a/lib/Zend/Barcode/Object/Upca.php b/lib/Zend/Barcode/Object/Upca.php deleted file mode 100644 index 51ad5323abd..00000000000 --- a/lib/Zend/Barcode/Object/Upca.php +++ /dev/null @@ -1,172 +0,0 @@ -_barcodeLength = 12; - $this->_mandatoryChecksum = true; - $this->_mandatoryQuietZones = true; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $middleCharacter = (5 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $encodedData = (7 * $this->_barThinWidth) * $this->_factor * 12; - return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - $height = ($this->_drawText) ? 1.1 : 1; - - // Start character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - - $textTable = str_split($this->getText()); - - // First character - $bars = str_split($this->_codingMap['A'][$textTable[0]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , $height); - } - - // First part - for ($i = 1; $i < 6; $i++) { - $bars = str_split($this->_codingMap['A'][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Middle character (01010) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - - // Second part - for ($i = 6; $i < 11; $i++) { - $bars = str_split($this->_codingMap['C'][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Last character - $bars = str_split($this->_codingMap['C'][$textTable[11]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , $height); - } - - // Stop character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - return $barcodeTable; - } - - /** - * Partial function to draw text - * @return void - */ - protected function _drawText() - { - if ($this->_drawText) { - $text = $this->getTextToDisplay(); - $characterWidth = (7 * $this->_barThinWidth) * $this->_factor; - $leftPosition = $this->getQuietZone() - $characterWidth; - for ($i = 0; $i < $this->_barcodeLength; $i ++) { - $fontSize = $this->_fontSize; - if ($i == 0 || $i == 11) { - $fontSize *= 0.8; - } - $this->_addText( - $text[$i], - $fontSize * $this->_factor, - $this->_rotate( - $leftPosition, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'left', - - $this->_orientation - ); - switch ($i) { - case 0: - $factor = 10; - break; - case 5: - $factor = 4; - break; - case 10: - $factor = 11; - break; - default: - $factor = 0; - } - $leftPosition = $leftPosition + $characterWidth + ($factor * $this->_barThinWidth * $this->_factor); - } - } - } -} diff --git a/lib/Zend/Barcode/Object/Upce.php b/lib/Zend/Barcode/Object/Upce.php deleted file mode 100644 index 7783e49f115..00000000000 --- a/lib/Zend/Barcode/Object/Upce.php +++ /dev/null @@ -1,230 +0,0 @@ - array( - 0 => array('B','B','B','A','A','A'), - 1 => array('B','B','A','B','A','A'), - 2 => array('B','B','A','A','B','A'), - 3 => array('B','B','A','A','A','B'), - 4 => array('B','A','B','B','A','A'), - 5 => array('B','A','A','B','B','A'), - 6 => array('B','A','A','A','B','B'), - 7 => array('B','A','B','A','B','A'), - 8 => array('B','A','B','A','A','B'), - 9 => array('B','A','A','B','A','B')), - 1 => array( - 0 => array('A','A','A','B','B','B'), - 1 => array('A','A','B','A','B','B'), - 2 => array('A','A','B','B','A','B'), - 3 => array('A','A','B','B','B','A'), - 4 => array('A','B','A','A','B','B'), - 5 => array('A','B','B','A','A','B'), - 6 => array('A','B','B','B','A','A'), - 7 => array('A','B','A','B','A','B'), - 8 => array('A','B','A','B','B','A'), - 9 => array('A','B','B','A','B','A')) - ); - - /** - * Default options for Postnet barcode - * @return void - */ - protected function _getDefaultOptions() - { - $this->_barcodeLength = 8; - $this->_mandatoryChecksum = true; - $this->_mandatoryQuietZones = true; - } - - /** - * Retrieve text to encode - * @return string - */ - public function getText() - { - $text = parent::getText(); - if ($text[0] != 1) { - $text[0] = 0; - } - return $text; - } - - /** - * Width of the barcode (in pixels) - * @return integer - */ - protected function _calculateBarcodeWidth() - { - $quietZone = $this->getQuietZone(); - $startCharacter = (3 * $this->_barThinWidth) * $this->_factor; - $stopCharacter = (6 * $this->_barThinWidth) * $this->_factor; - $encodedData = (7 * $this->_barThinWidth) * $this->_factor * 6; - return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone; - } - - /** - * Prepare array to draw barcode - * @return array - */ - protected function _prepareBarcode() - { - $barcodeTable = array(); - $height = ($this->_drawText) ? 1.1 : 1; - - // Start character (101) - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - - $textTable = str_split($this->getText()); - $system = 0; - if ($textTable[0] == 1) { - $system = 1; - } - $checksum = $textTable[7]; - $parity = $this->_parities[$system][$checksum]; - - for ($i = 1; $i < 7; $i++) { - $bars = str_split($this->_codingMap[$parity[$i - 1]][$textTable[$i]]); - foreach ($bars as $b) { - $barcodeTable[] = array($b , $this->_barThinWidth , 0 , 1); - } - } - - // Stop character (10101) - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(0 , $this->_barThinWidth , 0 , $height); - $barcodeTable[] = array(1 , $this->_barThinWidth , 0 , $height); - return $barcodeTable; - } - - /** - * Partial function to draw text - * @return void - */ - protected function _drawText() - { - if ($this->_drawText) { - $text = $this->getTextToDisplay(); - $characterWidth = (7 * $this->_barThinWidth) * $this->_factor; - $leftPosition = $this->getQuietZone() - $characterWidth; - for ($i = 0; $i < $this->_barcodeLength; $i ++) { - $fontSize = $this->_fontSize; - if ($i == 0 || $i == 7) { - $fontSize *= 0.8; - } - $this->_addText( - $text[$i], - $fontSize * $this->_factor, - $this->_rotate( - $leftPosition, - (int) $this->_withBorder * 2 - + $this->_factor * ($this->_barHeight + $fontSize) + 1 - ), - $this->_font, - $this->_foreColor, - 'left', - - $this->_orientation - ); - switch ($i) { - case 0: - $factor = 3; - break; - case 6: - $factor = 5; - break; - default: - $factor = 0; - } - $leftPosition = $leftPosition + $characterWidth + ($factor * $this->_barThinWidth * $this->_factor); - } - } - } - - /** - * Particular validation for Upce barcode objects - * (to suppress checksum character substitution) - * - * @param string $value - * @param array $options - * @throws Zend_Barcode_Object_Exception - */ - protected function _validateText($value, $options = array()) - { - $validator = new Zend_Validate_Barcode(array( - 'adapter' => 'upce', - 'checksum' => false, - )); - - $value = $this->_addLeadingZeros($value, true); - - if (!$validator->isValid($value)) { - $message = implode("\n", $validator->getMessages()); - - /** - * @see Zend_Barcode_Object_Exception - */ - #require_once 'Zend/Barcode/Object/Exception.php'; - throw new Zend_Barcode_Object_Exception($message); - } - } - - /** - * Get barcode checksum - * - * @param string $text - * @return int - */ - public function getChecksum($text) - { - $text = $this->_addLeadingZeros($text, true); - if ($text[0] != 1) { - $text[0] = 0; - } - return parent::getChecksum($text); - } -} diff --git a/lib/Zend/Barcode/Renderer/Exception.php b/lib/Zend/Barcode/Renderer/Exception.php deleted file mode 100644 index 8a110c5d505..00000000000 --- a/lib/Zend/Barcode/Renderer/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_userHeight = intval($value); - return $this; - } - - /** - * Get barcode height - * - * @return int - */ - public function getHeight() - { - return $this->_userHeight; - } - - /** - * Set barcode width - * - * @param mixed $value - * @return self - * @throws Zend_Barcode_Renderer_Exception - */ - public function setWidth($value) - { - if (!is_numeric($value) || intval($value) < 0) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Image width must be greater than or equals 0' - ); - } - $this->_userWidth = intval($value); - return $this; - } - - /** - * Get barcode width - * - * @return int - */ - public function getWidth() - { - return $this->_userWidth; - } - - /** - * Set an image resource to draw the barcode inside - * - * @param $image - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setResource($image) - { - if (gettype($image) != 'resource' || get_resource_type($image) != 'gd') { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Invalid image resource provided to setResource()' - ); - } - $this->_resource = $image; - return $this; - } - - /** - * Set the image type to produce (png, jpeg, gif) - * - * @param string $value - * @return Zend_Barcode_RendererAbstract - * @throws Zend_Barcode_Renderer_Exception - */ - public function setImageType($value) - { - if ($value == 'jpg') { - $value = 'jpeg'; - } - - if (!in_array($value, $this->_allowedImageType)) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception(sprintf( - 'Invalid type "%s" provided to setImageType()', - $value - )); - } - - $this->_imageType = $value; - return $this; - } - - /** - * Retrieve the image type to produce - * - * @return string - */ - public function getImageType() - { - return $this->_imageType; - } - - /** - * Initialize the image resource - * - * @return void - * @throws Zend_Barcode_Exception - */ - protected function _initRenderer() - { - if (!extension_loaded('gd')) { - #require_once 'Zend/Barcode/Exception.php'; - $e = new Zend_Barcode_Exception( - 'Gd extension must be loaded to render barcode as image' - ); - $e->setIsRenderable(false); - throw $e; - } - - $barcodeWidth = $this->_barcode->getWidth(true); - $barcodeHeight = $this->_barcode->getHeight(true); - - if ($this->_resource !== null) { - $foreColor = $this->_barcode->getForeColor(); - $backgroundColor = $this->_barcode->getBackgroundColor(); - $this->_imageBackgroundColor = imagecolorallocate( - $this->_resource, - ($backgroundColor & 0xFF0000) >> 16, - ($backgroundColor & 0x00FF00) >> 8, - $backgroundColor & 0x0000FF - ); - $this->_imageForeColor = imagecolorallocate( - $this->_resource, - ($foreColor & 0xFF0000) >> 16, - ($foreColor & 0x00FF00) >> 8, - $foreColor & 0x0000FF - ); - } else { - $width = $barcodeWidth; - $height = $barcodeHeight; - if ($this->_userWidth && $this->_barcode->getType() != 'error') { - $width = $this->_userWidth; - } - if ($this->_userHeight && $this->_barcode->getType() != 'error') { - $height = $this->_userHeight; - } - - $foreColor = $this->_barcode->getForeColor(); - $backgroundColor = $this->_barcode->getBackgroundColor(); - $this->_resource = imagecreatetruecolor($width, $height); - - $this->_imageBackgroundColor = imagecolorallocate( - $this->_resource, - ($backgroundColor & 0xFF0000) >> 16, - ($backgroundColor & 0x00FF00) >> 8, - $backgroundColor & 0x0000FF - ); - $this->_imageForeColor = imagecolorallocate( - $this->_resource, - ($foreColor & 0xFF0000) >> 16, - ($foreColor & 0x00FF00) >> 8, - $foreColor & 0x0000FF - ); - $white = imagecolorallocate($this->_resource, 255, 255, 255); - imagefilledrectangle($this->_resource, 0, 0, $width - 1, $height - 1, $white); - } - $this->_adjustPosition(imagesy($this->_resource), imagesx($this->_resource)); - imagefilledrectangle( - $this->_resource, - $this->_leftOffset, - $this->_topOffset, - $this->_leftOffset + $barcodeWidth - 1, - $this->_topOffset + $barcodeHeight - 1, - $this->_imageBackgroundColor - ); - } - - /** - * Check barcode parameters - * - * @return void - */ - protected function _checkParams() - { - $this->_checkDimensions(); - } - - /** - * Check barcode dimensions - * - * @return void - * @throws Zend_Barcode_Renderer_Exception - */ - protected function _checkDimensions() - { - if ($this->_resource !== null) { - if (imagesy($this->_resource) < $this->_barcode->getHeight(true)) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Barcode is define outside the image (height)' - ); - } - } else { - if ($this->_userHeight) { - $height = $this->_barcode->getHeight(true); - if ($this->_userHeight < $height) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception(sprintf( - "Barcode is define outside the image (calculated: '%d', provided: '%d')", - $height, - $this->_userHeight - )); - } - } - } - if ($this->_resource !== null) { - if (imagesx($this->_resource) < $this->_barcode->getWidth(true)) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Barcode is define outside the image (width)' - ); - } - } else { - if ($this->_userWidth) { - $width = $this->_barcode->getWidth(true); - if ($this->_userWidth < $width) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception(sprintf( - "Barcode is define outside the image (calculated: '%d', provided: '%d')", - $width, - $this->_userWidth - )); - } - } - } - } - - /** - * Draw and render the barcode with correct headers - * - * @return mixed - */ - public function render() - { - $this->draw(); - header("Content-Type: image/" . $this->_imageType); - $functionName = 'image' . $this->_imageType; - call_user_func($functionName, $this->_resource); - @imagedestroy($this->_resource); - } - - /** - * Draw a polygon in the image resource - * - * @param array $points - * @param integer $color - * @param boolean $filled - */ - protected function _drawPolygon($points, $color, $filled = true) - { - $newPoints = array( - $points[0][0] + $this->_leftOffset, - $points[0][1] + $this->_topOffset, - $points[1][0] + $this->_leftOffset, - $points[1][1] + $this->_topOffset, - $points[2][0] + $this->_leftOffset, - $points[2][1] + $this->_topOffset, - $points[3][0] + $this->_leftOffset, - $points[3][1] + $this->_topOffset, - ); - - $allocatedColor = imagecolorallocate( - $this->_resource, - ($color & 0xFF0000) >> 16, - ($color & 0x00FF00) >> 8, - $color & 0x0000FF - ); - - if ($filled) { - imagefilledpolygon($this->_resource, $newPoints, 4, $allocatedColor); - } else { - imagepolygon($this->_resource, $newPoints, 4, $allocatedColor); - } - } - - /** - * Draw a polygon in the image resource - * - * @param string $text - * @param float $size - * @param array $position - * @param string $font - * @param integer $color - * @param string $alignment - * @param float|int $orientation - * @throws Zend_Barcode_Renderer_Exception - */ - protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0) - { - $allocatedColor = imagecolorallocate( - $this->_resource, - ($color & 0xFF0000) >> 16, - ($color & 0x00FF00) >> 8, - $color & 0x0000FF - ); - - if ($font == null) { - $font = 3; - } - $position[0] += $this->_leftOffset; - $position[1] += $this->_topOffset; - - if (is_numeric($font)) { - if ($orientation) { - /** - * imagestring() doesn't allow orientation, if orientation - * needed: a TTF font is required. - * Throwing an exception here, allow to use automaticRenderError - * to informe user of the problem instead of simply not drawing - * the text - */ - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'No orientation possible with GD internal font' - ); - } - $fontWidth = imagefontwidth($font); - $positionY = $position[1] - imagefontheight($font) + 1; - switch ($alignment) { - case 'left': - $positionX = $position[0]; - break; - case 'center': - $positionX = $position[0] - ceil(($fontWidth * strlen($text)) / 2); - break; - case 'right': - $positionX = $position[0] - ($fontWidth * strlen($text)); - break; - } - imagestring($this->_resource, $font, $positionX, $positionY, $text, $color); - } else { - - if (!function_exists('imagettfbbox')) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'A font was provided, but this instance of PHP does not have TTF (FreeType) support' - ); - } - - $box = imagettfbbox($size, 0, $font, $text); - switch ($alignment) { - case 'left': - $width = 0; - break; - case 'center': - $width = ($box[2] - $box[0]) / 2; - break; - case 'right': - $width = ($box[2] - $box[0]); - break; - } - imagettftext( - $this->_resource, - $size, - $orientation, - $position[0] - ($width * cos(pi() * $orientation / 180)), - $position[1] + ($width * sin(pi() * $orientation / 180)), - $allocatedColor, - $font, - $text - ); - } - } -} diff --git a/lib/Zend/Barcode/Renderer/Pdf.php b/lib/Zend/Barcode/Renderer/Pdf.php deleted file mode 100644 index 0aa87b606f3..00000000000 --- a/lib/Zend/Barcode/Renderer/Pdf.php +++ /dev/null @@ -1,245 +0,0 @@ -_resource = $pdf; - $this->_page = intval($page); - - if (!count($this->_resource->pages)) { - $this->_page = 0; - $this->_resource->pages[] = new Zend_Pdf_Page( - Zend_Pdf_Page::SIZE_A4 - ); - } - return $this; - } - - /** - * Check renderer parameters - * - * @return void - */ - protected function _checkParams() - { - } - - /** - * Draw the barcode in the PDF, send headers and the PDF - * @return mixed - */ - public function render() - { - $this->draw(); - header("Content-Type: application/pdf"); - echo $this->_resource->render(); - } - - /** - * Initialize the PDF resource - * @return void - */ - protected function _initRenderer() - { - if ($this->_resource === null) { - $this->_resource = new Zend_Pdf(); - $this->_resource->pages[] = new Zend_Pdf_Page( - Zend_Pdf_Page::SIZE_A4 - ); - } - - $pdfPage = $this->_resource->pages[$this->_page]; - $this->_adjustPosition($pdfPage->getHeight(), $pdfPage->getWidth()); - } - - /** - * Draw a polygon in the rendering resource - * @param array $points - * @param integer $color - * @param boolean $filled - */ - protected function _drawPolygon($points, $color, $filled = true) - { - $page = $this->_resource->pages[$this->_page]; - foreach ($points as $point) { - $x[] = $point[0] * $this->_moduleSize + $this->_leftOffset; - $y[] = $page->getHeight() - $point[1] * $this->_moduleSize - $this->_topOffset; - } - if (count($y) == 4) { - if ($x[0] != $x[3] && $y[0] == $y[3]) { - $y[0] -= ($this->_moduleSize / 2); - $y[3] -= ($this->_moduleSize / 2); - } - if ($x[1] != $x[2] && $y[1] == $y[2]) { - $y[1] += ($this->_moduleSize / 2); - $y[2] += ($this->_moduleSize / 2); - } - } - - $color = new Zend_Pdf_Color_Rgb( - (($color & 0xFF0000) >> 16) / 255.0, - (($color & 0x00FF00) >> 8) / 255.0, - ($color & 0x0000FF) / 255.0 - ); - - $page->setLineColor($color); - $page->setFillColor($color); - $page->setLineWidth($this->_moduleSize); - - $fillType = ($filled) - ? Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - : Zend_Pdf_Page::SHAPE_DRAW_STROKE; - - $page->drawPolygon($x, $y, $fillType); - } - - /** - * Draw a text in the rendering resource - * - * @param string $text - * @param float $size - * @param array $position - * @param string $font - * @param integer $color - * @param string $alignment - * @param float|int $orientation - */ - protected function _drawText( - $text, - $size, - $position, - $font, - $color, - $alignment = 'center', - $orientation = 0 - ) { - $page = $this->_resource->pages[$this->_page]; - $color = new Zend_Pdf_Color_Rgb( - (($color & 0xFF0000) >> 16) / 255.0, - (($color & 0x00FF00) >> 8) / 255.0, - ($color & 0x0000FF) / 255.0 - ); - - $page->setLineColor($color); - $page->setFillColor($color); - $page->setFont(Zend_Pdf_Font::fontWithPath($font), $size * $this->_moduleSize * 1.2); - - $width = $this->widthForStringUsingFontSize( - $text, - Zend_Pdf_Font::fontWithPath($font), - $size * $this->_moduleSize - ); - - $angle = pi() * $orientation / 180; - $left = $position[0] * $this->_moduleSize + $this->_leftOffset; - $top = $page->getHeight() - $position[1] * $this->_moduleSize - $this->_topOffset; - - switch ($alignment) { - case 'center': - $left -= ($width / 2) * cos($angle); - $top -= ($width / 2) * sin($angle); - break; - case 'right': - $left -= $width; - break; - } - $page->rotate($left, $top, $angle); - $page->drawText($text, $left, $top); - $page->rotate($left, $top, - $angle); - } - - /** - * Calculate the width of a string: - * in case of using alignment parameter in drawText - * @param string $text - * @param Zend_Pdf_Font $font - * @param float $fontSize - * @return float - */ - public function widthForStringUsingFontSize($text, $font, $fontSize) - { - $drawingString = iconv('UTF-8', 'UTF-16BE//IGNORE', $text); - $characters = array(); - for ($i = 0; $i < strlen($drawingString); $i ++) { - $characters[] = (ord($drawingString[$i ++]) << 8) | ord($drawingString[$i]); - } - $glyphs = $font->glyphNumbersForCharacters($characters); - $widths = $font->widthsForGlyphs($glyphs); - $stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontSize; - return $stringWidth; - } -} diff --git a/lib/Zend/Barcode/Renderer/RendererAbstract.php b/lib/Zend/Barcode/Renderer/RendererAbstract.php deleted file mode 100644 index bfccaca723e..00000000000 --- a/lib/Zend/Barcode/Renderer/RendererAbstract.php +++ /dev/null @@ -1,551 +0,0 @@ -toArray(); - } - if (is_array($options)) { - $this->setOptions($options); - } - $this->_type = strtolower(substr( - get_class($this), - strlen($this->_rendererNamespace) + 1 - )); - } - - /** - * Set renderer state from options array - * @param array $options - * @return Zend_Renderer_Object - */ - public function setOptions($options) - { - foreach ($options as $key => $value) { - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - return $this; - } - - /** - * Set renderer state from config object - * @param Zend_Config $config - * @return Zend_Renderer_Object - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Set renderer namespace for autoloading - * - * @param string $namespace - * @return Zend_Renderer_Object - */ - public function setRendererNamespace($namespace) - { - $this->_rendererNamespace = $namespace; - return $this; - } - - /** - * Retrieve renderer namespace - * - * @return string - */ - public function getRendererNamespace() - { - return $this->_rendererNamespace; - } - - /** - * Retrieve renderer type - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * Manually adjust top position - * @param integer $value - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setTopOffset($value) - { - if (!is_numeric($value) || intval($value) < 0) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Vertical position must be greater than or equals 0' - ); - } - $this->_topOffset = intval($value); - return $this; - } - - /** - * Retrieve vertical adjustment - * @return integer - */ - public function getTopOffset() - { - return $this->_topOffset; - } - - /** - * Manually adjust left position - * @param integer $value - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setLeftOffset($value) - { - if (!is_numeric($value) || intval($value) < 0) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Horizontal position must be greater than or equals 0' - ); - } - $this->_leftOffset = intval($value); - return $this; - } - - /** - * Retrieve vertical adjustment - * @return integer - */ - public function getLeftOffset() - { - return $this->_leftOffset; - } - - /** - * Activate/Deactivate the automatic rendering of exception - * - * @param boolean $value - * @return $this - */ - public function setAutomaticRenderError($value) - { - $this->_automaticRenderError = (bool) $value; - return $this; - } - - /** - * Horizontal position of the barcode in the rendering resource - * - * @param string $value - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setHorizontalPosition($value) - { - if (!in_array($value, array('left' , 'center' , 'right'))) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - "Invalid barcode position provided must be 'left', 'center' or 'right'" - ); - } - $this->_horizontalPosition = $value; - return $this; - } - - /** - * Horizontal position of the barcode in the rendering resource - * @return string - */ - public function getHorizontalPosition() - { - return $this->_horizontalPosition; - } - - /** - * Vertical position of the barcode in the rendering resource - * - * @param string $value - * @return self - * @throws Zend_Barcode_Renderer_Exception - */ - public function setVerticalPosition($value) - { - if (!in_array($value, array('top' , 'middle' , 'bottom'))) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - "Invalid barcode position provided must be 'top', 'middle' or 'bottom'" - ); - } - $this->_verticalPosition = $value; - return $this; - } - - /** - * Vertical position of the barcode in the rendering resource - * @return string - */ - public function getVerticalPosition() - { - return $this->_verticalPosition; - } - - /** - * Set the size of a module - * @param float $value - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setModuleSize($value) - { - if (!is_numeric($value) || floatval($value) <= 0) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Float size must be greater than 0' - ); - } - $this->_moduleSize = floatval($value); - return $this; - } - - - /** - * Set the size of a module - * @return float - */ - public function getModuleSize() - { - return $this->_moduleSize; - } - - /** - * Retrieve the automatic rendering of exception - * @return boolean - */ - public function getAutomaticRenderError() - { - return $this->_automaticRenderError; - } - - /** - * Set the barcode object - * - * @param Zend_Barcode_Object $barcode - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setBarcode($barcode) - { - if (!$barcode instanceof Zend_Barcode_Object_ObjectAbstract) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Invalid barcode object provided to setBarcode()' - ); - } - $this->_barcode = $barcode; - return $this; - } - - /** - * Retrieve the barcode object - * @return Zend_Barcode_Object - */ - public function getBarcode() - { - return $this->_barcode; - } - - /** - * Checking of parameters after all settings - * @return boolean - */ - public function checkParams() - { - $this->_checkBarcodeObject(); - $this->_checkParams(); - return true; - } - - /** - * Check if a barcode object is correctly provided - * @return void - * @throws Zend_Barcode_Renderer_Exception - */ - protected function _checkBarcodeObject() - { - if ($this->_barcode === null) { - /** - * @see Zend_Barcode_Renderer_Exception - */ - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'No barcode object provided' - ); - } - } - - /** - * Calculate the left and top offset of the barcode in the - * rendering support - * - * @param float $supportHeight - * @param float $supportWidth - * @return void - */ - protected function _adjustPosition($supportHeight, $supportWidth) - { - $barcodeHeight = $this->_barcode->getHeight(true) * $this->_moduleSize; - if ($barcodeHeight != $supportHeight && $this->_topOffset == 0) { - switch ($this->_verticalPosition) { - case 'middle': - $this->_topOffset = floor( - ($supportHeight - $barcodeHeight) / 2); - break; - case 'bottom': - $this->_topOffset = $supportHeight - $barcodeHeight; - break; - case 'top': - default: - $this->_topOffset = 0; - break; - } - } - $barcodeWidth = $this->_barcode->getWidth(true) * $this->_moduleSize; - if ($barcodeWidth != $supportWidth && $this->_leftOffset == 0) { - switch ($this->_horizontalPosition) { - case 'center': - $this->_leftOffset = floor( - ($supportWidth - $barcodeWidth) / 2); - break; - case 'right': - $this->_leftOffset = $supportWidth - $barcodeWidth; - break; - case 'left': - default: - $this->_leftOffset = 0; - break; - } - } - } - - /** - * Draw the barcode in the rendering resource - * - * @return mixed - * @throws Zend_Exception - * @throws Zend_Barcode_Exception - */ - public function draw() - { - try { - $this->checkParams(); - $this->_initRenderer(); - $this->_drawInstructionList(); - } catch (Zend_Exception $e) { - $renderable = false; - if ($e instanceof Zend_Barcode_Exception) { - $renderable = $e->isRenderable(); - } - if ($this->_automaticRenderError && $renderable) { - $barcode = Zend_Barcode::makeBarcode( - 'error', - array('text' => $e->getMessage()) - ); - $this->setBarcode($barcode); - $this->_resource = null; - $this->_initRenderer(); - $this->_drawInstructionList(); - } else { - if ($e instanceof Zend_Barcode_Exception) { - $e->setIsRenderable(false); - } - throw $e; - } - } - return $this->_resource; - } - - /** - * Sub process to draw the barcode instructions - * Needed by the automatic error rendering - */ - private function _drawInstructionList() - { - $instructionList = $this->_barcode->draw(); - foreach ($instructionList as $instruction) { - switch ($instruction['type']) { - case 'polygon': - $this->_drawPolygon( - $instruction['points'], - $instruction['color'], - $instruction['filled'] - ); - break; - case 'text': //$text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0) - $this->_drawText( - $instruction['text'], - $instruction['size'], - $instruction['position'], - $instruction['font'], - $instruction['color'], - $instruction['alignment'], - $instruction['orientation'] - ); - break; - default: - /** - * @see Zend_Barcode_Renderer_Exception - */ - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Unknown drawing command' - ); - } - } - } - - /** - * Checking of parameters after all settings - * @return void - */ - abstract protected function _checkParams(); - - /** - * Render the resource by sending headers and drawed resource - * @return mixed - */ - abstract public function render(); - - /** - * Initialize the rendering resource - * @return void - */ - abstract protected function _initRenderer(); - - /** - * Draw a polygon in the rendering resource - * @param array $points - * @param integer $color - * @param boolean $filled - */ - abstract protected function _drawPolygon($points, $color, $filled = true); - - /** - * Draw a polygon in the rendering resource - * - * @param string $text - * @param float $size - * @param array $position - * @param string $font - * @param integer $color - * @param string $alignment - * @param float|int $orientation - */ - abstract protected function _drawText( - $text, - $size, - $position, - $font, - $color, - $alignment = 'center', - $orientation = 0 - ); -} diff --git a/lib/Zend/Barcode/Renderer/Svg.php b/lib/Zend/Barcode/Renderer/Svg.php deleted file mode 100644 index 76b274d1ecf..00000000000 --- a/lib/Zend/Barcode/Renderer/Svg.php +++ /dev/null @@ -1,385 +0,0 @@ -_userHeight = intval($value); - return $this; - } - - /** - * Get barcode height - * - * @return int - */ - public function getHeight() - { - return $this->_userHeight; - } - - /** - * Set barcode width - * - * @param mixed $value - * @return self - * @throws Zend_Barcode_Renderer_Exception - */ - public function setWidth($value) - { - if (!is_numeric($value) || intval($value) < 0) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Svg width must be greater than or equals 0' - ); - } - $this->_userWidth = intval($value); - return $this; - } - - /** - * Get barcode width - * - * @return int - */ - public function getWidth() - { - return $this->_userWidth; - } - - /** - * Set an image resource to draw the barcode inside - * - * @param $svg - * @return Zend_Barcode_Renderer - * @throws Zend_Barcode_Renderer_Exception - */ - public function setResource($svg) - { - if (!$svg instanceof DOMDocument) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Invalid DOMDocument resource provided to setResource()' - ); - } - $this->_resource = $svg; - return $this; - } - - /** - * Initialize the image resource - * - * @return void - */ - protected function _initRenderer() - { - $barcodeWidth = $this->_barcode->getWidth(true); - $barcodeHeight = $this->_barcode->getHeight(true); - - $backgroundColor = $this->_barcode->getBackgroundColor(); - $imageBackgroundColor = 'rgb(' . implode(', ', array(($backgroundColor & 0xFF0000) >> 16, - ($backgroundColor & 0x00FF00) >> 8, - ($backgroundColor & 0x0000FF))) . ')'; - - $width = $barcodeWidth; - $height = $barcodeHeight; - if ($this->_userWidth && $this->_barcode->getType() != 'error') { - $width = $this->_userWidth; - } - if ($this->_userHeight && $this->_barcode->getType() != 'error') { - $height = $this->_userHeight; - } - if ($this->_resource === null) { - $this->_resource = new DOMDocument('1.0', 'utf-8'); - $this->_resource->formatOutput = true; - $this->_rootElement = $this->_resource->createElement('svg'); - $this->_rootElement->setAttribute('xmlns', "http://www.w3.org/2000/svg"); - $this->_rootElement->setAttribute('version', '1.1'); - $this->_rootElement->setAttribute('width', $width); - $this->_rootElement->setAttribute('height', $height); - - $this->_appendRootElement('title', - array(), - "Barcode " . strtoupper($this->_barcode->getType()) . " " . $this->_barcode->getText()); - } else { - $this->_readRootElement(); - $width = $this->_rootElement->getAttribute('width'); - $height = $this->_rootElement->getAttribute('height'); - } - $this->_adjustPosition($height, $width); - - $this->_appendRootElement('rect', - array('x' => $this->_leftOffset, - 'y' => $this->_topOffset, - 'width' => ($this->_leftOffset + $barcodeWidth - 1), - 'height' => ($this->_topOffset + $barcodeHeight - 1), - 'fill' => $imageBackgroundColor)); - } - - protected function _readRootElement() - { - if ($this->_resource !== null) { - $this->_rootElement = $this->_resource->documentElement; - } - } - - /** - * Append a new DOMElement to the root element - * - * @param string $tagName - * @param array $attributes - * @param string $textContent - */ - protected function _appendRootElement($tagName, $attributes = array(), $textContent = null) - { - $newElement = $this->_createElement($tagName, $attributes, $textContent); - $this->_rootElement->appendChild($newElement); - } - - /** - * Create DOMElement - * - * @param string $tagName - * @param array $attributes - * @param string $textContent - * @return DOMElement - */ - protected function _createElement($tagName, $attributes = array(), $textContent = null) - { - $element = $this->_resource->createElement($tagName); - foreach ($attributes as $k =>$v) { - $element->setAttribute($k, $v); - } - if ($textContent !== null) { - $element->appendChild(new DOMText((string) $textContent)); - } - return $element; - } - - /** - * Check barcode parameters - * - * @return void - */ - protected function _checkParams() - { - $this->_checkDimensions(); - } - - /** - * Check barcode dimensions - * - * @return void - * @throws Zend_Barcode_Renderer_Exception - */ - protected function _checkDimensions() - { - if ($this->_resource !== null) { - $this->_readRootElement(); - $height = (float) $this->_rootElement->getAttribute('height'); - if ($height < $this->_barcode->getHeight(true)) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Barcode is define outside the image (height)' - ); - } - } else { - if ($this->_userHeight) { - $height = $this->_barcode->getHeight(true); - if ($this->_userHeight < $height) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception(sprintf( - "Barcode is define outside the image (calculated: '%d', provided: '%d')", - $height, - $this->_userHeight - )); - } - } - } - if ($this->_resource !== null) { - $this->_readRootElement(); - $width = $this->_rootElement->getAttribute('width'); - if ($width < $this->_barcode->getWidth(true)) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception( - 'Barcode is define outside the image (width)' - ); - } - } else { - if ($this->_userWidth) { - $width = (float) $this->_barcode->getWidth(true); - if ($this->_userWidth < $width) { - #require_once 'Zend/Barcode/Renderer/Exception.php'; - throw new Zend_Barcode_Renderer_Exception(sprintf( - "Barcode is define outside the image (calculated: '%d', provided: '%d')", - $width, - $this->_userWidth - )); - } - } - } - } - - /** - * Draw the barcode in the rendering resource - * @return mixed - */ - public function draw() - { - parent::draw(); - $this->_resource->appendChild($this->_rootElement); - return $this->_resource; - } - - /** - * Draw and render the barcode with correct headers - * - * @return mixed - */ - public function render() - { - $this->draw(); - header("Content-Type: image/svg+xml"); - echo $this->_resource->saveXML(); - } - - /** - * Draw a polygon in the svg resource - * - * @param array $points - * @param integer $color - * @param boolean $filled - */ - protected function _drawPolygon($points, $color, $filled = true) - { - $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16, - ($color & 0x00FF00) >> 8, - ($color & 0x0000FF))) . ')'; - $orientation = $this->getBarcode()->getOrientation(); - $newPoints = array( - $points[0][0] + $this->_leftOffset, - $points[0][1] + $this->_topOffset, - $points[1][0] + $this->_leftOffset, - $points[1][1] + $this->_topOffset, - $points[2][0] + $this->_leftOffset + cos(-$orientation), - $points[2][1] + $this->_topOffset - sin($orientation), - $points[3][0] + $this->_leftOffset + cos(-$orientation), - $points[3][1] + $this->_topOffset - sin($orientation), - ); - $newPoints = implode(' ', $newPoints); - $attributes['points'] = $newPoints; - $attributes['fill'] = $color; - $this->_appendRootElement('polygon', $attributes); - } - - /** - * Draw a polygon in the svg resource - * - * @param string $text - * @param float $size - * @param array $position - * @param string $font - * @param integer $color - * @param string $alignment - * @param float|int $orientation - */ - protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0) - { - $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16, - ($color & 0x00FF00) >> 8, - ($color & 0x0000FF))) . ')'; - $attributes['x'] = $position[0] + $this->_leftOffset; - $attributes['y'] = $position[1] + $this->_topOffset; - //$attributes['font-family'] = $font; - $attributes['color'] = $color; - $attributes['font-size'] = $size * 1.2; - switch ($alignment) { - case 'left': - $textAnchor = 'start'; - break; - case 'right': - $textAnchor = 'end'; - break; - case 'center': - default: - $textAnchor = 'middle'; - } - $attributes['style'] = 'text-anchor: ' . $textAnchor; - $attributes['transform'] = 'rotate(' - . (- $orientation) - . ', ' - . ($position[0] + $this->_leftOffset) - . ', ' . ($position[1] + $this->_topOffset) - . ')'; - $this->_appendRootElement('text', $attributes, $text); - } -} diff --git a/lib/Zend/Cache.php b/lib/Zend/Cache.php deleted file mode 100644 index 10000f11be9..00000000000 --- a/lib/Zend/Cache.php +++ /dev/null @@ -1,250 +0,0 @@ -setBackend($backendObject); - return $frontendObject; - } - - /** - * Backend Constructor - * - * @param string $backend - * @param array $backendOptions - * @param boolean $customBackendNaming - * @param boolean $autoload - * @return Zend_Cache_Backend - */ - public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false) - { - if (!$customBackendNaming) { - $backend = self::_normalizeName($backend); - } - if (in_array($backend, Zend_Cache::$standardBackends)) { - // we use a standard backend - $backendClass = 'Zend_Cache_Backend_' . $backend; - // security controls are explicit - #require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; - } else { - // we use a custom backend - if (!preg_match('~^[\w\\\\]+$~D', $backend)) { - Zend_Cache::throwException("Invalid backend name [$backend]"); - } - if (!$customBackendNaming) { - // we use this boolean to avoid an API break - $backendClass = 'Zend_Cache_Backend_' . $backend; - } else { - $backendClass = $backend; - } - if (!$autoload) { - $file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; - if (!(self::_isReadable($file))) { - self::throwException("file $file not found in include_path"); - } - #require_once $file; - } - } - return new $backendClass($backendOptions); - } - - /** - * Frontend Constructor - * - * @param string $frontend - * @param array $frontendOptions - * @param boolean $customFrontendNaming - * @param boolean $autoload - * @return Zend_Cache_Core|Zend_Cache_Frontend - */ - public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false) - { - if (!$customFrontendNaming) { - $frontend = self::_normalizeName($frontend); - } - if (in_array($frontend, self::$standardFrontends)) { - // we use a standard frontend - // For perfs reasons, with frontend == 'Core', we can interact with the Core itself - $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend; - // security controls are explicit - #require_once str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; - } else { - // we use a custom frontend - if (!preg_match('~^[\w\\\\]+$~D', $frontend)) { - Zend_Cache::throwException("Invalid frontend name [$frontend]"); - } - if (!$customFrontendNaming) { - // we use this boolean to avoid an API break - $frontendClass = 'Zend_Cache_Frontend_' . $frontend; - } else { - $frontendClass = $frontend; - } - if (!$autoload) { - $file = str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; - if (!(self::_isReadable($file))) { - self::throwException("file $file not found in include_path"); - } - #require_once $file; - } - } - return new $frontendClass($frontendOptions); - } - - /** - * Throw an exception - * - * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic - * @param string $msg Message for the exception - * @throws Zend_Cache_Exception - */ - public static function throwException($msg, Exception $e = null) - { - // For perfs reasons, we use this dynamic inclusion - #require_once 'Zend/Cache/Exception.php'; - throw new Zend_Cache_Exception($msg, 0, $e); - } - - /** - * Normalize frontend and backend names to allow multiple words TitleCased - * - * @param string $name Name to normalize - * @return string - */ - protected static function _normalizeName($name) - { - $name = ucfirst(strtolower($name)); - $name = str_replace(array('-', '_', '.'), ' ', $name); - $name = ucwords($name); - $name = str_replace(' ', '', $name); - if (stripos($name, 'ZendServer') === 0) { - $name = 'ZendServer_' . substr($name, strlen('ZendServer')); - } - - return $name; - } - - /** - * Returns TRUE if the $filename is readable, or FALSE otherwise. - * This function uses the PHP include_path, where PHP's is_readable() - * does not. - * - * Note : this method comes from Zend_Loader (see #ZF-2891 for details) - * - * @param string $filename - * @return boolean - */ - private static function _isReadable($filename) - { - if (!$fh = @fopen($filename, 'r', true)) { - return false; - } - @fclose($fh); - return true; - } - -} diff --git a/lib/Zend/Cache/Backend.php b/lib/Zend/Cache/Backend.php deleted file mode 100644 index c440b34d1f6..00000000000 --- a/lib/Zend/Cache/Backend.php +++ /dev/null @@ -1,288 +0,0 @@ - (int) lifetime : - * - Cache lifetime (in seconds) - * - If null, the cache is valid forever - * - * =====> (int) logging : - * - if set to true, a logging is activated throw Zend_Log - * - * @var array directives - */ - protected $_directives = array( - 'lifetime' => 3600, - 'logging' => false, - 'logger' => null - ); - - /** - * Available options - * - * @var array available options - */ - protected $_options = array(); - - /** - * Constructor - * - * @param array $options Associative array of options - */ - public function __construct(array $options = array()) - { - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - } - - /** - * Set the frontend directives - * - * @param array $directives Assoc of directives - * @throws Zend_Cache_Exception - * @return void - */ - public function setDirectives($directives) - { - if (!is_array($directives)) Zend_Cache::throwException('Directives parameter must be an array'); - foreach($directives as $name => $value) { - if (!is_string($name)) { - Zend_Cache::throwException("Incorrect option name : $name"); - } - $name = strtolower($name); - if (array_key_exists($name, $this->_directives)) { - $this->_directives[$name] = $value; - } - - } - - $this->_loggerSanity(); - } - - /** - * Set an option - * - * @param string $name - * @param mixed $value - * @throws Zend_Cache_Exception - * @return void - */ - public function setOption($name, $value) - { - if (!is_string($name)) { - Zend_Cache::throwException("Incorrect option name : $name"); - } - $name = strtolower($name); - if (array_key_exists($name, $this->_options)) { - $this->_options[$name] = $value; - } - } - - /** - * Returns an option - * - * @param string $name Optional, the options name to return - * @throws Zend_Cache_Exceptions - * @return mixed - */ - public function getOption($name) - { - $name = strtolower($name); - - if (array_key_exists($name, $this->_options)) { - return $this->_options[$name]; - } - - if (array_key_exists($name, $this->_directives)) { - return $this->_directives[$name]; - } - - Zend_Cache::throwException("Incorrect option name : {$name}"); - } - - /** - * Get the life time - * - * if $specificLifetime is not false, the given specific life time is used - * else, the global lifetime is used - * - * @param int $specificLifetime - * @return int Cache life time - */ - public function getLifetime($specificLifetime) - { - if ($specificLifetime === false) { - return $this->_directives['lifetime']; - } - return $specificLifetime; - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * DEPRECATED : use getCapabilities() instead - * - * @deprecated - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return true; - } - - /** - * Determine system TMP directory and detect if we have read access - * - * inspired from Zend_File_Transfer_Adapter_Abstract - * - * @return string - * @throws Zend_Cache_Exception if unable to determine directory - */ - public function getTmpDir() - { - $tmpdir = array(); - foreach (array($_ENV, $_SERVER) as $tab) { - foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $key) { - if (isset($tab[$key]) && is_string($tab[$key])) { - if (($key == 'windir') || ($key == 'SystemRoot')) { - $dir = realpath($tab[$key] . '\\temp'); - } else { - $dir = realpath($tab[$key]); - } - if ($this->_isGoodTmpDir($dir)) { - return $dir; - } - } - } - } - $upload = ini_get('upload_tmp_dir'); - if ($upload) { - $dir = realpath($upload); - if ($this->_isGoodTmpDir($dir)) { - return $dir; - } - } - if (function_exists('sys_get_temp_dir')) { - $dir = sys_get_temp_dir(); - if ($this->_isGoodTmpDir($dir)) { - return $dir; - } - } - // Attemp to detect by creating a temporary file - $tempFile = tempnam(md5(uniqid(rand(), TRUE)), ''); - if ($tempFile) { - $dir = realpath(dirname($tempFile)); - unlink($tempFile); - if ($this->_isGoodTmpDir($dir)) { - return $dir; - } - } - if ($this->_isGoodTmpDir('/tmp')) { - return '/tmp'; - } - if ($this->_isGoodTmpDir('\\temp')) { - return '\\temp'; - } - Zend_Cache::throwException('Could not determine temp directory, please specify a cache_dir manually'); - } - - /** - * Verify if the given temporary directory is readable and writable - * - * @param string $dir temporary directory - * @return boolean true if the directory is ok - */ - protected function _isGoodTmpDir($dir) - { - if (is_readable($dir)) { - if (is_writable($dir)) { - return true; - } - } - return false; - } - - /** - * Make sure if we enable logging that the Zend_Log class - * is available. - * Create a default log object if none is set. - * - * @throws Zend_Cache_Exception - * @return void - */ - protected function _loggerSanity() - { - if (!isset($this->_directives['logging']) || !$this->_directives['logging']) { - return; - } - - if (isset($this->_directives['logger'])) { - if ($this->_directives['logger'] instanceof Zend_Log) { - return; - } - Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); - } - - // Create a default logger to the standard output stream - #require_once 'Zend/Log.php'; - #require_once 'Zend/Log/Writer/Stream.php'; - #require_once 'Zend/Log/Filter/Priority.php'; - $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); - $logger->addFilter(new Zend_Log_Filter_Priority(Zend_Log::WARN, '<=')); - $this->_directives['logger'] = $logger; - } - - /** - * Log a message at the WARN (4) priority. - * - * @param string $message - * @param int $priority - * @return void - */ - protected function _log($message, $priority = 4) - { - if (!$this->_directives['logging']) { - return; - } - - if (!isset($this->_directives['logger'])) { - Zend_Cache::throwException('Logging is enabled but logger is not set.'); - } - $logger = $this->_directives['logger']; - if (!$logger instanceof Zend_Log) { - Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); - } - $logger->log($message, $priority); - } -} diff --git a/lib/Zend/Cache/Backend/Apc.php b/lib/Zend/Cache/Backend/Apc.php deleted file mode 100644 index 61888da6133..00000000000 --- a/lib/Zend/Cache/Backend/Apc.php +++ /dev/null @@ -1,355 +0,0 @@ - infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - $result = apcu_store($id, array($data, time(), $lifetime), $lifetime); - if (count($tags) > 0) { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_APC_BACKEND); - } - return $result; - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - return apcu_delete($id); - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode clean mode - * @param array $tags array of tags - * @throws Zend_Cache_Exception - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - return apcu_clear_cache('user'); - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_Apc::clean() : CLEANING_MODE_OLD is unsupported by the Apc backend"); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_APC_BACKEND); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * DEPRECATED : use getCapabilities() instead - * - * @deprecated - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return false; - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $mem = apcu_sma_info(true); - $memSize = $mem['num_seg'] * $mem['seg_size']; - $memAvailable= $mem['avail_mem']; - $memUsed = $memSize - $memAvailable; - if ($memSize == 0) { - Zend_Cache::throwException('can\'t get apcu memory size'); - } - if ($memUsed > $memSize) { - return 100; - } - return ((int) (100. * ($memUsed / $memSize))); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_APC_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_APC_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_APC_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_APC_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - $ids = array(); - $iterator = new APCIterator('user', null, APC_ITER_KEY); - foreach ($iterator as $item) { - $ids[] = $item['key']; - } - - return $ids; - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $tmp = apcu_fetch($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - // because this record is only with 1.7 release - // if old cache records are still there... - return false; - } - $lifetime = $tmp[2]; - return array( - 'expire' => $mtime + $lifetime, - 'tags' => array(), - 'mtime' => $mtime - ); - } - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - $tmp = apcu_fetch($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - // because this record is only with 1.7 release - // if old cache records are still there... - return false; - } - $lifetime = $tmp[2]; - $newLifetime = $lifetime - (time() - $mtime) + $extraLifetime; - if ($newLifetime <=0) { - return false; - } - apcu_store($id, array($data, time(), $newLifetime), $newLifetime); - return true; - } - return false; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => false, - 'tags' => false, - 'expired_read' => false, - 'priority' => false, - 'infinite_lifetime' => false, - 'get_list' => true - ); - } - -} diff --git a/lib/Zend/Cache/Backend/BlackHole.php b/lib/Zend/Cache/Backend/BlackHole.php deleted file mode 100644 index e7e9ce4356a..00000000000 --- a/lib/Zend/Cache/Backend/BlackHole.php +++ /dev/null @@ -1,250 +0,0 @@ - infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - return true; - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - return true; - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => remove too old cache entries ($tags is not used) - * 'matchingTag' => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * 'notMatchingTag' => remove cache entries not matching one of the given tags - * ($tags can be an array of strings or a single string) - * 'matchingAnyTag' => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode clean mode - * @param tags array $tags array of tags - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - return true; - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - return array(); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - return array(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - return array(); - } - - /** - * Return the filling percentage of the backend storage - * - * @return int integer between 0 and 100 - * @throws Zend_Cache_Exception - */ - public function getFillingPercentage() - { - return 0; - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - return false; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => true, - 'tags' => true, - 'expired_read' => true, - 'priority' => true, - 'infinite_lifetime' => true, - 'get_list' => true, - ); - } - - /** - * PUBLIC METHOD FOR UNIT TESTING ONLY ! - * - * Force a cache record to expire - * - * @param string $id cache id - */ - public function ___expire($id) - { - } -} diff --git a/lib/Zend/Cache/Backend/ExtendedInterface.php b/lib/Zend/Cache/Backend/ExtendedInterface.php deleted file mode 100644 index 184b89ad31b..00000000000 --- a/lib/Zend/Cache/Backend/ExtendedInterface.php +++ /dev/null @@ -1,126 +0,0 @@ - (string) cache_dir : - * - Directory where to put the cache files - * - * =====> (boolean) file_locking : - * - Enable / disable file_locking - * - Can avoid cache corruption under bad circumstances but it doesn't work on multithread - * webservers and on NFS filesystems for example - * - * =====> (boolean) read_control : - * - Enable / disable read control - * - If enabled, a control key is embeded in cache file and this key is compared with the one - * calculated after the reading. - * - * =====> (string) read_control_type : - * - Type of read control (only if read control is enabled). Available values are : - * 'md5' for a md5 hash control (best but slowest) - * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice) - * 'adler32' for an adler32 hash control (excellent choice too, faster than crc32) - * 'strlen' for a length only test (fastest) - * - * =====> (int) hashed_directory_level : - * - Hashed directory level - * - Set the hashed directory structure level. 0 means "no hashed directory - * structure", 1 means "one level of directory", 2 means "two levels"... - * This option can speed up the cache only when you have many thousands of - * cache file. Only specific benchs can help you to choose the perfect value - * for you. Maybe, 1 or 2 is a good start. - * - * =====> (int) hashed_directory_umask : - * - deprecated - * - Permissions for hashed directory structure - * - * =====> (int) hashed_directory_perm : - * - Permissions for hashed directory structure - * - * =====> (string) file_name_prefix : - * - prefix for cache files - * - be really carefull with this option because a too generic value in a system cache dir - * (like /tmp) can cause disasters when cleaning the cache - * - * =====> (int) cache_file_umask : - * - deprecated - * - Permissions for cache files - * - * =====> (int) cache_file_perm : - * - Permissions for cache files - * - * =====> (int) metatadatas_array_max_size : - * - max size for the metadatas array (don't change this value unless you - * know what you are doing) - * - * @var array available options - */ - protected $_options = array( - 'cache_dir' => null, - 'file_locking' => true, - 'read_control' => true, - 'read_control_type' => 'crc32', - 'hashed_directory_level' => 0, - 'hashed_directory_perm' => 0700, - 'file_name_prefix' => 'zend_cache', - 'cache_file_perm' => 0600, - 'metadatas_array_max_size' => 100 - ); - - /** - * Array of metadatas (each item is an associative array) - * - * @var array - */ - protected $_metadatasArray = array(); - - - /** - * Constructor - * - * @param array $options associative array of options - * @throws Zend_Cache_Exception - */ - public function __construct(array $options = array()) - { - parent::__construct($options); - if ($this->_options['cache_dir'] !== null) { // particular case for this option - $this->setCacheDir($this->_options['cache_dir']); - } else { - $this->setCacheDir(self::getTmpDir() . DIRECTORY_SEPARATOR, false); - } - if (isset($this->_options['file_name_prefix'])) { // particular case for this option - if (!preg_match('~^[a-zA-Z0-9_]+$~D', $this->_options['file_name_prefix'])) { - Zend_Cache::throwException('Invalid file_name_prefix : must use only [a-zA-Z0-9_]'); - } - } - if ($this->_options['metadatas_array_max_size'] < 10) { - Zend_Cache::throwException('Invalid metadatas_array_max_size, must be > 10'); - } - - if (isset($options['hashed_directory_umask'])) { - // See #ZF-12047 - trigger_error("'hashed_directory_umask' is deprecated -> please use 'hashed_directory_perm' instead", E_USER_NOTICE); - if (!isset($options['hashed_directory_perm'])) { - $options['hashed_directory_perm'] = $options['hashed_directory_umask']; - } - } - if (isset($options['hashed_directory_perm']) && is_string($options['hashed_directory_perm'])) { - // See #ZF-4422 - $this->_options['hashed_directory_perm'] = octdec($this->_options['hashed_directory_perm']); - } - - if (isset($options['cache_file_umask'])) { - // See #ZF-12047 - trigger_error("'cache_file_umask' is deprecated -> please use 'cache_file_perm' instead", E_USER_NOTICE); - if (!isset($options['cache_file_perm'])) { - $options['cache_file_perm'] = $options['cache_file_umask']; - } - } - if (isset($options['cache_file_perm']) && is_string($options['cache_file_perm'])) { - // See #ZF-4422 - $this->_options['cache_file_perm'] = octdec($this->_options['cache_file_perm']); - } - } - - /** - * Set the cache_dir (particular case of setOption() method) - * - * @param string $value - * @param boolean $trailingSeparator If true, add a trailing separator is necessary - * @throws Zend_Cache_Exception - * @return void - */ - public function setCacheDir($value, $trailingSeparator = true) - { - if (!is_dir($value)) { - Zend_Cache::throwException(sprintf('cache_dir "%s" must be a directory', $value)); - } - if (!is_writable($value)) { - Zend_Cache::throwException(sprintf('cache_dir "%s" is not writable', $value)); - } - if ($trailingSeparator) { - // add a trailing DIRECTORY_SEPARATOR if necessary - $value = rtrim(realpath($value), '\\/') . DIRECTORY_SEPARATOR; - } - $this->_options['cache_dir'] = $value; - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id cache id - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - if (!($this->_test($id, $doNotTestCacheValidity))) { - // The cache is not hit ! - return false; - } - $metadatas = $this->_getMetadatas($id); - $file = $this->_file($id); - $data = $this->_fileGetContents($file); - if ($this->_options['read_control']) { - $hashData = $this->_hash($data, $this->_options['read_control_type']); - $hashControl = $metadatas['hash']; - if ($hashData != $hashControl) { - // Problem detected by the read control ! - $this->_log('Zend_Cache_Backend_File::load() / read_control : stored hash and computed hash do not match'); - $this->remove($id); - return false; - } - } - return $data; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - clearstatcache(); - return $this->_test($id, false); - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param boolean|int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - clearstatcache(); - $file = $this->_file($id); - $path = $this->_path($id); - if ($this->_options['hashed_directory_level'] > 0) { - if (!is_writable($path)) { - // maybe, we just have to build the directory structure - $this->_recursiveMkdirAndChmod($id); - } - if (!is_writable($path)) { - return false; - } - } - if ($this->_options['read_control']) { - $hash = $this->_hash($data, $this->_options['read_control_type']); - } else { - $hash = ''; - } - $metadatas = array( - 'hash' => $hash, - 'mtime' => time(), - 'expire' => $this->_expireTime($this->getLifetime($specificLifetime)), - 'tags' => $tags - ); - $res = $this->_setMetadatas($id, $metadatas); - if (!$res) { - $this->_log('Zend_Cache_Backend_File::save() / error on saving metadata'); - return false; - } - $res = $this->_filePutContents($file, $data); - return $res; - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - $file = $this->_file($id); - $boolRemove = $this->_remove($file); - $boolMetadata = $this->_delMetadatas($id); - return $boolMetadata && $boolRemove; - } - - /** - * Clean some cache records - * - * Available modes are : - * - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode clean mode - * @param array $tags array of tags - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - // We use this protected method to hide the recursive stuff - clearstatcache(); - return $this->_clean($this->_options['cache_dir'], $mode, $tags); - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - return $this->_get($this->_options['cache_dir'], 'ids', array()); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - return $this->_get($this->_options['cache_dir'], 'tags', array()); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - return $this->_get($this->_options['cache_dir'], 'matching', $tags); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - return $this->_get($this->_options['cache_dir'], 'notMatching', $tags); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - return $this->_get($this->_options['cache_dir'], 'matchingAny', $tags); - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $free = disk_free_space($this->_options['cache_dir']); - $total = disk_total_space($this->_options['cache_dir']); - if ($total == 0) { - Zend_Cache::throwException('can\'t get disk_total_space'); - } else { - if ($free >= $total) { - return 100; - } - return ((int) (100. * ($total - $free) / $total)); - } - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $metadatas = $this->_getMetadatas($id); - if (!$metadatas) { - return false; - } - if (time() > $metadatas['expire']) { - return false; - } - return array( - 'expire' => $metadatas['expire'], - 'tags' => $metadatas['tags'], - 'mtime' => $metadatas['mtime'] - ); - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - $metadatas = $this->_getMetadatas($id); - if (!$metadatas) { - return false; - } - if (time() > $metadatas['expire']) { - return false; - } - $newMetadatas = array( - 'hash' => $metadatas['hash'], - 'mtime' => time(), - 'expire' => $metadatas['expire'] + $extraLifetime, - 'tags' => $metadatas['tags'] - ); - $res = $this->_setMetadatas($id, $newMetadatas); - if (!$res) { - return false; - } - return true; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => true, - 'tags' => true, - 'expired_read' => true, - 'priority' => false, - 'infinite_lifetime' => true, - 'get_list' => true - ); - } - - /** - * PUBLIC METHOD FOR UNIT TESTING ONLY ! - * - * Force a cache record to expire - * - * @param string $id cache id - */ - public function ___expire($id) - { - $metadatas = $this->_getMetadatas($id); - if ($metadatas) { - $metadatas['expire'] = 1; - $this->_setMetadatas($id, $metadatas); - } - } - - /** - * Get a metadatas record - * - * @param string $id Cache id - * @return array|false Associative array of metadatas - */ - protected function _getMetadatas($id) - { - if (isset($this->_metadatasArray[$id])) { - return $this->_metadatasArray[$id]; - } else { - $metadatas = $this->_loadMetadatas($id); - if (!$metadatas) { - return false; - } - $this->_setMetadatas($id, $metadatas, false); - return $metadatas; - } - } - - /** - * Set a metadatas record - * - * @param string $id Cache id - * @param array $metadatas Associative array of metadatas - * @param boolean $save optional pass false to disable saving to file - * @return boolean True if no problem - */ - protected function _setMetadatas($id, $metadatas, $save = true) - { - if (count($this->_metadatasArray) >= $this->_options['metadatas_array_max_size']) { - $n = (int) ($this->_options['metadatas_array_max_size'] / 10); - $this->_metadatasArray = array_slice($this->_metadatasArray, $n); - } - if ($save) { - $result = $this->_saveMetadatas($id, $metadatas); - if (!$result) { - return false; - } - } - $this->_metadatasArray[$id] = $metadatas; - return true; - } - - /** - * Drop a metadata record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - protected function _delMetadatas($id) - { - if (isset($this->_metadatasArray[$id])) { - unset($this->_metadatasArray[$id]); - } - $file = $this->_metadatasFile($id); - return $this->_remove($file); - } - - /** - * Clear the metadatas array - * - * @return void - */ - protected function _cleanMetadatas() - { - $this->_metadatasArray = array(); - } - - /** - * Load metadatas from disk - * - * @param string $id Cache id - * @return array|false Metadatas associative array - */ - protected function _loadMetadatas($id) - { - $file = $this->_metadatasFile($id); - $result = $this->_fileGetContents($file); - if (!$result) { - return false; - } - $tmp = @unserialize($result); - return $tmp; - } - - /** - * Save metadatas to disk - * - * @param string $id Cache id - * @param array $metadatas Associative array - * @return boolean True if no problem - */ - protected function _saveMetadatas($id, $metadatas) - { - $file = $this->_metadatasFile($id); - $result = $this->_filePutContents($file, serialize($metadatas)); - if (!$result) { - return false; - } - return true; - } - - /** - * Make and return a file name (with path) for metadatas - * - * @param string $id Cache id - * @return string Metadatas file name (with path) - */ - protected function _metadatasFile($id) - { - $path = $this->_path($id); - $fileName = $this->_idToFileName('internal-metadatas---' . $id); - return $path . $fileName; - } - - /** - * Check if the given filename is a metadatas one - * - * @param string $fileName File name - * @return boolean True if it's a metadatas one - */ - protected function _isMetadatasFile($fileName) - { - $id = $this->_fileNameToId($fileName); - if (substr($id, 0, 21) == 'internal-metadatas---') { - return true; - } else { - return false; - } - } - - /** - * Remove a file - * - * If we can't remove the file (because of locks or any problem), we will touch - * the file to invalidate it - * - * @param string $file Complete file path - * @return boolean True if ok - */ - protected function _remove($file) - { - if (!is_file($file)) { - return false; - } - if (!@unlink($file)) { - # we can't remove the file (because of locks or any problem) - $this->_log("Zend_Cache_Backend_File::_remove() : we can't remove $file"); - return false; - } - return true; - } - - /** - * Clean some cache records (protected method used for recursive stuff) - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $dir Directory to clean - * @param string $mode Clean mode - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - protected function _clean($dir, $mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - if (!is_dir($dir)) { - return false; - } - $result = true; - $prefix = $this->_options['file_name_prefix']; - $glob = @glob($dir . $prefix . '--*'); - if ($glob === false) { - // On some systems it is impossible to distinguish between empty match and an error. - return true; - } - $metadataFiles = array(); - foreach ($glob as $file) { - if (is_file($file)) { - $fileName = basename($file); - if ($this->_isMetadatasFile($fileName)) { - // In CLEANING_MODE_ALL, we drop anything, even remainings old metadatas files. - // To do that, we need to save the list of the metadata files first. - if ($mode == Zend_Cache::CLEANING_MODE_ALL) { - $metadataFiles[] = $file; - } - continue; - } - $id = $this->_fileNameToId($fileName); - $metadatas = $this->_getMetadatas($id); - if ($metadatas === FALSE) { - $metadatas = array('expire' => 1, 'tags' => array()); - } - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - $result = $result && $this->remove($id); - break; - case Zend_Cache::CLEANING_MODE_OLD: - if (time() > $metadatas['expire']) { - $result = $this->remove($id) && $result; - } - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - $matching = true; - foreach ($tags as $tag) { - if (!in_array($tag, $metadatas['tags'])) { - $matching = false; - break; - } - } - if ($matching) { - $result = $this->remove($id) && $result; - } - break; - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - $matching = false; - foreach ($tags as $tag) { - if (in_array($tag, $metadatas['tags'])) { - $matching = true; - break; - } - } - if (!$matching) { - $result = $this->remove($id) && $result; - } - break; - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $matching = false; - foreach ($tags as $tag) { - if (in_array($tag, $metadatas['tags'])) { - $matching = true; - break; - } - } - if ($matching) { - $result = $this->remove($id) && $result; - } - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { - // Recursive call - $result = $this->_clean($file . DIRECTORY_SEPARATOR, $mode, $tags) && $result; - if ($mode == Zend_Cache::CLEANING_MODE_ALL) { - // we try to drop the structure too - @rmdir($file); - } - } - } - - // cycle through metadataFiles and delete orphaned ones - foreach ($metadataFiles as $file) { - if (file_exists($file)) { - $result = $this->_remove($file) && $result; - } - } - - return $result; - } - - protected function _get($dir, $mode, $tags = array()) - { - if (!is_dir($dir)) { - return false; - } - $result = array(); - $prefix = $this->_options['file_name_prefix']; - $glob = @glob($dir . $prefix . '--*'); - if ($glob === false) { - // On some systems it is impossible to distinguish between empty match and an error. - return array(); - } - foreach ($glob as $file) { - if (is_file($file)) { - $fileName = basename($file); - $id = $this->_fileNameToId($fileName); - $metadatas = $this->_getMetadatas($id); - if ($metadatas === FALSE) { - continue; - } - if (time() > $metadatas['expire']) { - continue; - } - switch ($mode) { - case 'ids': - $result[] = $id; - break; - case 'tags': - $result = array_unique(array_merge($result, $metadatas['tags'])); - break; - case 'matching': - $matching = true; - foreach ($tags as $tag) { - if (!in_array($tag, $metadatas['tags'])) { - $matching = false; - break; - } - } - if ($matching) { - $result[] = $id; - } - break; - case 'notMatching': - $matching = false; - foreach ($tags as $tag) { - if (in_array($tag, $metadatas['tags'])) { - $matching = true; - break; - } - } - if (!$matching) { - $result[] = $id; - } - break; - case 'matchingAny': - $matching = false; - foreach ($tags as $tag) { - if (in_array($tag, $metadatas['tags'])) { - $matching = true; - break; - } - } - if ($matching) { - $result[] = $id; - } - break; - default: - Zend_Cache::throwException('Invalid mode for _get() method'); - break; - } - } - if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { - // Recursive call - $recursiveRs = $this->_get($file . DIRECTORY_SEPARATOR, $mode, $tags); - if ($recursiveRs === false) { - $this->_log('Zend_Cache_Backend_File::_get() / recursive call : can\'t list entries of "'.$file.'"'); - } else { - $result = array_unique(array_merge($result, $recursiveRs)); - } - } - } - return array_unique($result); - } - - /** - * Compute & return the expire time - * - * @param int $lifetime - * @return int expire time (unix timestamp) - */ - protected function _expireTime($lifetime) - { - if ($lifetime === null) { - return 9999999999; - } - return time() + $lifetime; - } - - /** - * Make a control key with the string containing datas - * - * @param string $data Data - * @param string $controlType Type of control 'md5', 'crc32' or 'strlen' - * @throws Zend_Cache_Exception - * @return string Control key - */ - protected function _hash($data, $controlType) - { - switch ($controlType) { - case 'md5': - return md5($data); - case 'crc32': - return crc32($data); - case 'strlen': - return strlen($data); - case 'adler32': - return hash('adler32', $data); - default: - Zend_Cache::throwException("Incorrect hash function : $controlType"); - } - } - - /** - * Transform a cache id into a file name and return it - * - * @param string $id Cache id - * @return string File name - */ - protected function _idToFileName($id) - { - $prefix = $this->_options['file_name_prefix']; - $result = $prefix . '---' . $id; - return $result; - } - - /** - * Make and return a file name (with path) - * - * @param string $id Cache id - * @return string File name (with path) - */ - protected function _file($id) - { - $path = $this->_path($id); - $fileName = $this->_idToFileName($id); - return $path . $fileName; - } - - /** - * Return the complete directory path of a filename (including hashedDirectoryStructure) - * - * @param string $id Cache id - * @param boolean $parts if true, returns array of directory parts instead of single string - * @return string Complete directory path - */ - protected function _path($id, $parts = false) - { - $partsArray = array(); - $root = $this->_options['cache_dir']; - $prefix = $this->_options['file_name_prefix']; - if ($this->_options['hashed_directory_level']>0) { - $hash = hash('adler32', $id); - for ($i=0 ; $i < $this->_options['hashed_directory_level'] ; $i++) { - $root = $root . $prefix . '--' . substr($hash, 0, $i + 1) . DIRECTORY_SEPARATOR; - $partsArray[] = $root; - } - } - if ($parts) { - return $partsArray; - } else { - return $root; - } - } - - /** - * Make the directory strucuture for the given id - * - * @param string $id cache id - * @return boolean true - */ - protected function _recursiveMkdirAndChmod($id) - { - if ($this->_options['hashed_directory_level'] <=0) { - return true; - } - $partsArray = $this->_path($id, true); - foreach ($partsArray as $part) { - if (!is_dir($part)) { - @mkdir($part, $this->_options['hashed_directory_perm']); - @chmod($part, $this->_options['hashed_directory_perm']); // see #ZF-320 (this line is required in some configurations) - } - } - return true; - } - - /** - * Test if the given cache id is available (and still valid as a cache record) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return boolean|mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - protected function _test($id, $doNotTestCacheValidity) - { - $metadatas = $this->_getMetadatas($id); - if (!$metadatas) { - return false; - } - if ($doNotTestCacheValidity || (time() <= $metadatas['expire'])) { - return $metadatas['mtime']; - } - return false; - } - - /** - * Return the file content of the given file - * - * @param string $file File complete path - * @return string File content (or false if problem) - */ - protected function _fileGetContents($file) - { - $result = false; - if (!is_file($file)) { - return false; - } - $f = @fopen($file, 'rb'); - if ($f) { - if ($this->_options['file_locking']) @flock($f, LOCK_SH); - $result = stream_get_contents($f); - if ($this->_options['file_locking']) @flock($f, LOCK_UN); - @fclose($f); - } - return $result; - } - - /** - * Put the given string into the given file - * - * @param string $file File complete path - * @param string $string String to put in file - * @return boolean true if no problem - */ - protected function _filePutContents($file, $string) - { - $result = false; - $f = @fopen($file, 'ab+'); - if ($f) { - if ($this->_options['file_locking']) @flock($f, LOCK_EX); - fseek($f, 0); - ftruncate($f, 0); - $tmp = @fwrite($f, $string); - if (!($tmp === FALSE)) { - $result = true; - } - @fclose($f); - } - @chmod($file, $this->_options['cache_file_perm']); - return $result; - } - - /** - * Transform a file name into cache id and return it - * - * @param string $fileName File name - * @return string Cache id - */ - protected function _fileNameToId($fileName) - { - $prefix = $this->_options['file_name_prefix']; - return preg_replace('~^' . $prefix . '---(.*)$~', '$1', $fileName); - } - -} diff --git a/lib/Zend/Cache/Backend/Interface.php b/lib/Zend/Cache/Backend/Interface.php deleted file mode 100644 index 1bd72d8c163..00000000000 --- a/lib/Zend/Cache/Backend/Interface.php +++ /dev/null @@ -1,99 +0,0 @@ - infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false); - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id); - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()); - -} diff --git a/lib/Zend/Cache/Backend/Libmemcached.php b/lib/Zend/Cache/Backend/Libmemcached.php deleted file mode 100644 index c2b7b755728..00000000000 --- a/lib/Zend/Cache/Backend/Libmemcached.php +++ /dev/null @@ -1,484 +0,0 @@ - (array) servers : - * an array of memcached server ; each memcached server is described by an associative array : - * 'host' => (string) : the name of the memcached server - * 'port' => (int) : the port of the memcached server - * 'weight' => (int) : number of buckets to create for this server which in turn control its - * probability of it being selected. The probability is relative to the total - * weight of all servers. - * =====> (array) client : - * an array of memcached client options ; the memcached client is described by an associative array : - * @see http://php.net/manual/memcached.constants.php - * - The option name can be the name of the constant without the prefix 'OPT_' - * or the integer value of this option constant - * - * @var array available options - */ - protected $_options = array( - 'servers' => array(array( - 'host' => self::DEFAULT_HOST, - 'port' => self::DEFAULT_PORT, - 'weight' => self::DEFAULT_WEIGHT, - )), - 'client' => array() - ); - - /** - * Memcached object - * - * @var mixed memcached object - */ - protected $_memcache = null; - - /** - * Constructor - * - * @param array $options associative array of options - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - if (!extension_loaded('memcached')) { - Zend_Cache::throwException('The memcached extension must be loaded for using this backend !'); - } - - // override default client options - $this->_options['client'] = array( - Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT, - Memcached::OPT_HASH => Memcached::HASH_MD5, - Memcached::OPT_LIBKETAMA_COMPATIBLE => true, - ); - - parent::__construct($options); - - if (isset($this->_options['servers'])) { - $value = $this->_options['servers']; - if (isset($value['host'])) { - // in this case, $value seems to be a simple associative array (one server only) - $value = array(0 => $value); // let's transform it into a classical array of associative arrays - } - $this->setOption('servers', $value); - } - $this->_memcache = new Memcached; - - // setup memcached client options - foreach ($this->_options['client'] as $name => $value) { - $optId = null; - if (is_int($name)) { - $optId = $name; - } else { - $optConst = 'Memcached::OPT_' . strtoupper($name); - if (defined($optConst)) { - $optId = constant($optConst); - } else { - $this->_log("Unknown memcached client option '{$name}' ({$optConst})"); - } - } - if (null !== $optId) { - if (!$this->_memcache->setOption($optId, $value)) { - $this->_log("Setting memcached client option '{$optId}' failed"); - } - } - } - - // setup memcached servers - $servers = array(); - foreach ($this->_options['servers'] as $server) { - if (!array_key_exists('port', $server)) { - $server['port'] = self::DEFAULT_PORT; - } - if (!array_key_exists('weight', $server)) { - $server['weight'] = self::DEFAULT_WEIGHT; - } - - $servers[] = array($server['host'], $server['port'], $server['weight']); - } - $this->_memcache->addServers($servers); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - $tmp = $this->_memcache->get($id); - if (isset($tmp[0])) { - return $tmp[0]; - } - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id Cache id - * @return int|false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $tmp = $this->_memcache->get($id); - if (isset($tmp[0], $tmp[1])) { - return (int)$tmp[1]; - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean True if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - - // ZF-8856: using set because add needs a second request if item already exists - $result = @$this->_memcache->set($id, array($data, time(), $lifetime), $lifetime); - if ($result === false) { - $rsCode = $this->_memcache->getResultCode(); - $rsMsg = $this->_memcache->getResultMessage(); - $this->_log("Memcached::set() failed: [{$rsCode}] {$rsMsg}"); - } - - if (count($tags) > 0) { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND); - } - - return $result; - } - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - return $this->_memcache->delete($id); - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - return $this->_memcache->flush(); - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_Libmemcached::clean() : CLEANING_MODE_OLD is unsupported by the Libmemcached backend"); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_LIBMEMCACHED_BACKEND); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return false; - } - - /** - * Set the frontend directives - * - * @param array $directives Assoc of directives - * @throws Zend_Cache_Exception - * @return void - */ - public function setDirectives($directives) - { - parent::setDirectives($directives); - $lifetime = $this->getLifetime(false); - if ($lifetime > 2592000) { - // #ZF-3490 : For the memcached backend, there is a lifetime limit of 30 days (2592000 seconds) - $this->_log('memcached backend has a limit of 30 days (2592000 seconds) for the lifetime'); - } - if ($lifetime === null) { - // #ZF-4614 : we tranform null to zero to get the maximal lifetime - parent::setDirectives(array('lifetime' => 0)); - } - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - $this->_log("Zend_Cache_Backend_Libmemcached::save() : getting the list of cache ids is unsupported by the Libmemcached backend"); - return array(); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND); - return array(); - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $mems = $this->_memcache->getStats(); - if ($mems === false) { - return 0; - } - - $memSize = null; - $memUsed = null; - foreach ($mems as $key => $mem) { - if ($mem === false) { - $this->_log('can\'t get stat from ' . $key); - continue; - } - - $eachSize = $mem['limit_maxbytes']; - $eachUsed = $mem['bytes']; - if ($eachUsed > $eachSize) { - $eachUsed = $eachSize; - } - - $memSize += $eachSize; - $memUsed += $eachUsed; - } - - if ($memSize === null || $memUsed === null) { - Zend_Cache::throwException('Can\'t get filling percentage'); - } - - return ((int) (100. * ($memUsed / $memSize))); - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $tmp = $this->_memcache->get($id); - if (isset($tmp[0], $tmp[1], $tmp[2])) { - $data = $tmp[0]; - $mtime = $tmp[1]; - $lifetime = $tmp[2]; - return array( - 'expire' => $mtime + $lifetime, - 'tags' => array(), - 'mtime' => $mtime - ); - } - - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - $tmp = $this->_memcache->get($id); - if (isset($tmp[0], $tmp[1], $tmp[2])) { - $data = $tmp[0]; - $mtime = $tmp[1]; - $lifetime = $tmp[2]; - $newLifetime = $lifetime - (time() - $mtime) + $extraLifetime; - if ($newLifetime <=0) { - return false; - } - // #ZF-5702 : we try replace() first becase set() seems to be slower - if (!($result = $this->_memcache->replace($id, array($data, time(), $newLifetime), $newLifetime))) { - $result = $this->_memcache->set($id, array($data, time(), $newLifetime), $newLifetime); - if ($result === false) { - $rsCode = $this->_memcache->getResultCode(); - $rsMsg = $this->_memcache->getResultMessage(); - $this->_log("Memcached::set() failed: [{$rsCode}] {$rsMsg}"); - } - } - return $result; - } - return false; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => false, - 'tags' => false, - 'expired_read' => false, - 'priority' => false, - 'infinite_lifetime' => false, - 'get_list' => false - ); - } - -} diff --git a/lib/Zend/Cache/Backend/Memcached.php b/lib/Zend/Cache/Backend/Memcached.php deleted file mode 100644 index 06b83fa23bb..00000000000 --- a/lib/Zend/Cache/Backend/Memcached.php +++ /dev/null @@ -1,509 +0,0 @@ - (array) servers : - * an array of memcached server ; each memcached server is described by an associative array : - * 'host' => (string) : the name of the memcached server - * 'port' => (int) : the port of the memcached server - * 'persistent' => (bool) : use or not persistent connections to this memcached server - * 'weight' => (int) : number of buckets to create for this server which in turn control its - * probability of it being selected. The probability is relative to the total - * weight of all servers. - * 'timeout' => (int) : value in seconds which will be used for connecting to the daemon. Think twice - * before changing the default value of 1 second - you can lose all the - * advantages of caching if your connection is too slow. - * 'retry_interval' => (int) : controls how often a failed server will be retried, the default value - * is 15 seconds. Setting this parameter to -1 disables automatic retry. - * 'status' => (bool) : controls if the server should be flagged as online. - * 'failure_callback' => (callback) : Allows the user to specify a callback function to run upon - * encountering an error. The callback is run before failover - * is attempted. The function takes two parameters, the hostname - * and port of the failed server. - * - * =====> (boolean) compression : - * true if you want to use on-the-fly compression - * - * =====> (boolean) compatibility : - * true if you use old memcache server or extension - * - * @var array available options - */ - protected $_options = array( - 'servers' => array(array( - 'host' => self::DEFAULT_HOST, - 'port' => self::DEFAULT_PORT, - 'persistent' => self::DEFAULT_PERSISTENT, - 'weight' => self::DEFAULT_WEIGHT, - 'timeout' => self::DEFAULT_TIMEOUT, - 'retry_interval' => self::DEFAULT_RETRY_INTERVAL, - 'status' => self::DEFAULT_STATUS, - 'failure_callback' => self::DEFAULT_FAILURE_CALLBACK - )), - 'compression' => false, - 'compatibility' => false, - ); - - /** - * Memcache object - * - * @var mixed memcache object - */ - protected $_memcache = null; - - /** - * Constructor - * - * @param array $options associative array of options - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - if (!extension_loaded('memcache')) { - Zend_Cache::throwException('The memcache extension must be loaded for using this backend !'); - } - parent::__construct($options); - if (isset($this->_options['servers'])) { - $value= $this->_options['servers']; - if (isset($value['host'])) { - // in this case, $value seems to be a simple associative array (one server only) - $value = array(0 => $value); // let's transform it into a classical array of associative arrays - } - $this->setOption('servers', $value); - } - $this->_memcache = new Memcache; - foreach ($this->_options['servers'] as $server) { - if (!array_key_exists('port', $server)) { - $server['port'] = self::DEFAULT_PORT; - } - if (!array_key_exists('persistent', $server)) { - $server['persistent'] = self::DEFAULT_PERSISTENT; - } - if (!array_key_exists('weight', $server)) { - $server['weight'] = self::DEFAULT_WEIGHT; - } - if (!array_key_exists('timeout', $server)) { - $server['timeout'] = self::DEFAULT_TIMEOUT; - } - if (!array_key_exists('retry_interval', $server)) { - $server['retry_interval'] = self::DEFAULT_RETRY_INTERVAL; - } - if (!array_key_exists('status', $server)) { - $server['status'] = self::DEFAULT_STATUS; - } - if (!array_key_exists('failure_callback', $server)) { - $server['failure_callback'] = self::DEFAULT_FAILURE_CALLBACK; - } - if ($this->_options['compatibility']) { - // No status for compatibility mode (#ZF-5887) - $this->_memcache->addServer($server['host'], $server['port'], $server['persistent'], - $server['weight'], $server['timeout'], - $server['retry_interval']); - } else { - $this->_memcache->addServer($server['host'], $server['port'], $server['persistent'], - $server['weight'], $server['timeout'], - $server['retry_interval'], - $server['status'], $server['failure_callback']); - } - } - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - $tmp = $this->_memcache->get($id); - if (is_array($tmp) && isset($tmp[0])) { - return $tmp[0]; - } - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id Cache id - * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $tmp = $this->_memcache->get($id); - if (is_array($tmp)) { - return $tmp[1]; - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean True if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - if ($this->_options['compression']) { - $flag = MEMCACHE_COMPRESSED; - } else { - $flag = 0; - } - - // ZF-8856: using set because add needs a second request if item already exists - $result = @$this->_memcache->set($id, array($data, time(), $lifetime), $flag, $lifetime); - - if (count($tags) > 0) { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_MEMCACHED_BACKEND); - } - - return $result; - } - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - return $this->_memcache->delete($id, 0); - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - return $this->_memcache->flush(); - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_Memcached::clean() : CLEANING_MODE_OLD is unsupported by the Memcached backend"); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_MEMCACHED_BACKEND); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return false; - } - - /** - * Set the frontend directives - * - * @param array $directives Assoc of directives - * @throws Zend_Cache_Exception - * @return void - */ - public function setDirectives($directives) - { - parent::setDirectives($directives); - $lifetime = $this->getLifetime(false); - if ($lifetime > 2592000) { - // #ZF-3490 : For the memcached backend, there is a lifetime limit of 30 days (2592000 seconds) - $this->_log('memcached backend has a limit of 30 days (2592000 seconds) for the lifetime'); - } - if ($lifetime === null) { - // #ZF-4614 : we tranform null to zero to get the maximal lifetime - parent::setDirectives(array('lifetime' => 0)); - } - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - $this->_log("Zend_Cache_Backend_Memcached::save() : getting the list of cache ids is unsupported by the Memcache backend"); - return array(); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_MEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_MEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_MEMCACHED_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_MEMCACHED_BACKEND); - return array(); - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $mems = $this->_memcache->getExtendedStats(); - - $memSize = null; - $memUsed = null; - foreach ($mems as $key => $mem) { - if ($mem === false) { - $this->_log('can\'t get stat from ' . $key); - continue; - } - - $eachSize = $mem['limit_maxbytes']; - - /** - * Couchbase 1.x uses 'mem_used' instead of 'bytes' - * @see https://www.couchbase.com/issues/browse/MB-3466 - */ - $eachUsed = isset($mem['bytes']) ? $mem['bytes'] : $mem['mem_used']; - if ($eachUsed > $eachSize) { - $eachUsed = $eachSize; - } - - $memSize += $eachSize; - $memUsed += $eachUsed; - } - - if ($memSize === null || $memUsed === null) { - Zend_Cache::throwException('Can\'t get filling percentage'); - } - - return ((int) (100. * ($memUsed / $memSize))); - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $tmp = $this->_memcache->get($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - // because this record is only with 1.7 release - // if old cache records are still there... - return false; - } - $lifetime = $tmp[2]; - return array( - 'expire' => $mtime + $lifetime, - 'tags' => array(), - 'mtime' => $mtime - ); - } - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - if ($this->_options['compression']) { - $flag = MEMCACHE_COMPRESSED; - } else { - $flag = 0; - } - $tmp = $this->_memcache->get($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - // because this record is only with 1.7 release - // if old cache records are still there... - return false; - } - $lifetime = $tmp[2]; - $newLifetime = $lifetime - (time() - $mtime) + $extraLifetime; - if ($newLifetime <=0) { - return false; - } - // #ZF-5702 : we try replace() first becase set() seems to be slower - if (!($result = $this->_memcache->replace($id, array($data, time(), $newLifetime), $flag, $newLifetime))) { - $result = $this->_memcache->set($id, array($data, time(), $newLifetime), $flag, $newLifetime); - } - return $result; - } - return false; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => false, - 'tags' => false, - 'expired_read' => false, - 'priority' => false, - 'infinite_lifetime' => false, - 'get_list' => false - ); - } - -} diff --git a/lib/Zend/Cache/Backend/Sqlite.php b/lib/Zend/Cache/Backend/Sqlite.php deleted file mode 100644 index 22fac1f0eb6..00000000000 --- a/lib/Zend/Cache/Backend/Sqlite.php +++ /dev/null @@ -1,678 +0,0 @@ - (string) cache_db_complete_path : - * - the complete path (filename included) of the SQLITE database - * - * ====> (int) automatic_vacuum_factor : - * - Disable / Tune the automatic vacuum process - * - The automatic vacuum process defragment the database file (and make it smaller) - * when a clean() or delete() is called - * 0 => no automatic vacuum - * 1 => systematic vacuum (when delete() or clean() methods are called) - * x (integer) > 1 => automatic vacuum randomly 1 times on x clean() or delete() - * - * @var array Available options - */ - protected $_options = array( - 'cache_db_complete_path' => null, - 'automatic_vacuum_factor' => 10 - ); - - /** - * DB ressource - * - * @var mixed $_db - */ - private $_db = null; - - /** - * Boolean to store if the structure has benn checked or not - * - * @var boolean $_structureChecked - */ - private $_structureChecked = false; - - /** - * Constructor - * - * @param array $options Associative array of options - * @throws Zend_cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - parent::__construct($options); - if ($this->_options['cache_db_complete_path'] === null) { - Zend_Cache::throwException('cache_db_complete_path option has to set'); - } - if (!extension_loaded('sqlite')) { - Zend_Cache::throwException("Cannot use SQLite storage because the 'sqlite' extension is not loaded in the current PHP environment"); - } - $this->_getConnection(); - } - - /** - * Destructor - * - * @return void - */ - public function __destruct() - { - @sqlite_close($this->_getConnection()); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false Cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - $this->_checkAndBuildStructure(); - $sql = "SELECT content FROM cache WHERE id='$id'"; - if (!$doNotTestCacheValidity) { - $sql = $sql . " AND (expire=0 OR expire>" . time() . ')'; - } - $result = $this->_query($sql); - $row = @sqlite_fetch_array($result); - if ($row) { - return $row['content']; - } - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id Cache id - * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $this->_checkAndBuildStructure(); - $sql = "SELECT lastModified FROM cache WHERE id='$id' AND (expire=0 OR expire>" . time() . ')'; - $result = $this->_query($sql); - $row = @sqlite_fetch_array($result); - if ($row) { - return ((int) $row['lastModified']); - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $this->_checkAndBuildStructure(); - $lifetime = $this->getLifetime($specificLifetime); - $data = @sqlite_escape_string($data); - $mktime = time(); - if ($lifetime === null) { - $expire = 0; - } else { - $expire = $mktime + $lifetime; - } - $this->_query("DELETE FROM cache WHERE id='$id'"); - $sql = "INSERT INTO cache (id, content, lastModified, expire) VALUES ('$id', '$data', $mktime, $expire)"; - $res = $this->_query($sql); - if (!$res) { - $this->_log("Zend_Cache_Backend_Sqlite::save() : impossible to store the cache id=$id"); - return false; - } - $res = true; - foreach ($tags as $tag) { - $res = $this->_registerTag($id, $tag) && $res; - } - return $res; - } - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - $this->_checkAndBuildStructure(); - $res = $this->_query("SELECT COUNT(*) AS nbr FROM cache WHERE id='$id'"); - $result1 = @sqlite_fetch_single($res); - $result2 = $this->_query("DELETE FROM cache WHERE id='$id'"); - $result3 = $this->_query("DELETE FROM tag WHERE id='$id'"); - $this->_automaticVacuum(); - return ($result1 && $result2 && $result3); - } - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean True if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - $this->_checkAndBuildStructure(); - $return = $this->_clean($mode, $tags); - $this->_automaticVacuum(); - return $return; - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - $this->_checkAndBuildStructure(); - $res = $this->_query("SELECT id FROM cache WHERE (expire=0 OR expire>" . time() . ")"); - $result = array(); - while ($id = @sqlite_fetch_single($res)) { - $result[] = $id; - } - return $result; - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - $this->_checkAndBuildStructure(); - $res = $this->_query("SELECT DISTINCT(name) AS name FROM tag"); - $result = array(); - while ($id = @sqlite_fetch_single($res)) { - $result[] = $id; - } - return $result; - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - $first = true; - $ids = array(); - foreach ($tags as $tag) { - $res = $this->_query("SELECT DISTINCT(id) AS id FROM tag WHERE name='$tag'"); - if (!$res) { - return array(); - } - $rows = @sqlite_fetch_all($res, SQLITE_ASSOC); - $ids2 = array(); - foreach ($rows as $row) { - $ids2[] = $row['id']; - } - if ($first) { - $ids = $ids2; - $first = false; - } else { - $ids = array_intersect($ids, $ids2); - } - } - $result = array(); - foreach ($ids as $id) { - $result[] = $id; - } - return $result; - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - $res = $this->_query("SELECT id FROM cache"); - $rows = @sqlite_fetch_all($res, SQLITE_ASSOC); - $result = array(); - foreach ($rows as $row) { - $id = $row['id']; - $matching = false; - foreach ($tags as $tag) { - $res = $this->_query("SELECT COUNT(*) AS nbr FROM tag WHERE name='$tag' AND id='$id'"); - if (!$res) { - return array(); - } - $nbr = (int) @sqlite_fetch_single($res); - if ($nbr > 0) { - $matching = true; - } - } - if (!$matching) { - $result[] = $id; - } - } - return $result; - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - $first = true; - $ids = array(); - foreach ($tags as $tag) { - $res = $this->_query("SELECT DISTINCT(id) AS id FROM tag WHERE name='$tag'"); - if (!$res) { - return array(); - } - $rows = @sqlite_fetch_all($res, SQLITE_ASSOC); - $ids2 = array(); - foreach ($rows as $row) { - $ids2[] = $row['id']; - } - if ($first) { - $ids = $ids2; - $first = false; - } else { - $ids = array_merge($ids, $ids2); - } - } - $result = array(); - foreach ($ids as $id) { - $result[] = $id; - } - return $result; - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $dir = dirname($this->_options['cache_db_complete_path']); - $free = disk_free_space($dir); - $total = disk_total_space($dir); - if ($total == 0) { - Zend_Cache::throwException('can\'t get disk_total_space'); - } else { - if ($free >= $total) { - return 100; - } - return ((int) (100. * ($total - $free) / $total)); - } - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $tags = array(); - $res = $this->_query("SELECT name FROM tag WHERE id='$id'"); - if ($res) { - $rows = @sqlite_fetch_all($res, SQLITE_ASSOC); - foreach ($rows as $row) { - $tags[] = $row['name']; - } - } - $this->_query('CREATE TABLE cache (id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)'); - $res = $this->_query("SELECT lastModified,expire FROM cache WHERE id='$id'"); - if (!$res) { - return false; - } - $row = @sqlite_fetch_array($res, SQLITE_ASSOC); - return array( - 'tags' => $tags, - 'mtime' => $row['lastModified'], - 'expire' => $row['expire'] - ); - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - $sql = "SELECT expire FROM cache WHERE id='$id' AND (expire=0 OR expire>" . time() . ')'; - $res = $this->_query($sql); - if (!$res) { - return false; - } - $expire = @sqlite_fetch_single($res); - $newExpire = $expire + $extraLifetime; - $res = $this->_query("UPDATE cache SET lastModified=" . time() . ", expire=$newExpire WHERE id='$id'"); - if ($res) { - return true; - } else { - return false; - } - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => true, - 'tags' => true, - 'expired_read' => true, - 'priority' => false, - 'infinite_lifetime' => true, - 'get_list' => true - ); - } - - /** - * PUBLIC METHOD FOR UNIT TESTING ONLY ! - * - * Force a cache record to expire - * - * @param string $id Cache id - */ - public function ___expire($id) - { - $time = time() - 1; - $this->_query("UPDATE cache SET lastModified=$time, expire=$time WHERE id='$id'"); - } - - /** - * Return the connection resource - * - * If we are not connected, the connection is made - * - * @throws Zend_Cache_Exception - * @return resource Connection resource - */ - private function _getConnection() - { - if (is_resource($this->_db)) { - return $this->_db; - } else { - $this->_db = @sqlite_open($this->_options['cache_db_complete_path']); - if (!(is_resource($this->_db))) { - Zend_Cache::throwException("Impossible to open " . $this->_options['cache_db_complete_path'] . " cache DB file"); - } - return $this->_db; - } - } - - /** - * Execute an SQL query silently - * - * @param string $query SQL query - * @return mixed|false query results - */ - private function _query($query) - { - $db = $this->_getConnection(); - if (is_resource($db)) { - $res = @sqlite_query($db, $query); - if ($res === false) { - return false; - } else { - return $res; - } - } - return false; - } - - /** - * Deal with the automatic vacuum process - * - * @return void - */ - private function _automaticVacuum() - { - if ($this->_options['automatic_vacuum_factor'] > 0) { - $rand = rand(1, $this->_options['automatic_vacuum_factor']); - if ($rand == 1) { - $this->_query('VACUUM'); - } - } - } - - /** - * Register a cache id with the given tag - * - * @param string $id Cache id - * @param string $tag Tag - * @return boolean True if no problem - */ - private function _registerTag($id, $tag) { - $res = $this->_query("DELETE FROM TAG WHERE name='$tag' AND id='$id'"); - $res = $this->_query("INSERT INTO tag (name, id) VALUES ('$tag', '$id')"); - if (!$res) { - $this->_log("Zend_Cache_Backend_Sqlite::_registerTag() : impossible to register tag=$tag on id=$id"); - return false; - } - return true; - } - - /** - * Build the database structure - * - * @return false - */ - private function _buildStructure() - { - $this->_query('DROP INDEX tag_id_index'); - $this->_query('DROP INDEX tag_name_index'); - $this->_query('DROP INDEX cache_id_expire_index'); - $this->_query('DROP TABLE version'); - $this->_query('DROP TABLE cache'); - $this->_query('DROP TABLE tag'); - $this->_query('CREATE TABLE version (num INTEGER PRIMARY KEY)'); - $this->_query('CREATE TABLE cache (id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)'); - $this->_query('CREATE TABLE tag (name TEXT, id TEXT)'); - $this->_query('CREATE INDEX tag_id_index ON tag(id)'); - $this->_query('CREATE INDEX tag_name_index ON tag(name)'); - $this->_query('CREATE INDEX cache_id_expire_index ON cache(id, expire)'); - $this->_query('INSERT INTO version (num) VALUES (1)'); - } - - /** - * Check if the database structure is ok (with the good version) - * - * @return boolean True if ok - */ - private function _checkStructureVersion() - { - $result = $this->_query("SELECT num FROM version"); - if (!$result) return false; - $row = @sqlite_fetch_array($result); - if (!$row) { - return false; - } - if (((int) $row['num']) != 1) { - // old cache structure - $this->_log('Zend_Cache_Backend_Sqlite::_checkStructureVersion() : old cache structure version detected => the cache is going to be dropped'); - return false; - } - return true; - } - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean True if no problem - */ - private function _clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - $res1 = $this->_query('DELETE FROM cache'); - $res2 = $this->_query('DELETE FROM tag'); - return $res1 && $res2; - break; - case Zend_Cache::CLEANING_MODE_OLD: - $mktime = time(); - $res1 = $this->_query("DELETE FROM tag WHERE id IN (SELECT id FROM cache WHERE expire>0 AND expire<=$mktime)"); - $res2 = $this->_query("DELETE FROM cache WHERE expire>0 AND expire<=$mktime"); - return $res1 && $res2; - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - $ids = $this->getIdsMatchingTags($tags); - $result = true; - foreach ($ids as $id) { - $result = $this->remove($id) && $result; - } - return $result; - break; - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - $ids = $this->getIdsNotMatchingTags($tags); - $result = true; - foreach ($ids as $id) { - $result = $this->remove($id) && $result; - } - return $result; - break; - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $ids = $this->getIdsMatchingAnyTags($tags); - $result = true; - foreach ($ids as $id) { - $result = $this->remove($id) && $result; - } - return $result; - break; - default: - break; - } - return false; - } - - /** - * Check if the database structure is ok (with the good version), if no : build it - * - * @throws Zend_Cache_Exception - * @return boolean True if ok - */ - private function _checkAndBuildStructure() - { - if (!($this->_structureChecked)) { - if (!$this->_checkStructureVersion()) { - $this->_buildStructure(); - if (!$this->_checkStructureVersion()) { - Zend_Cache::throwException("Impossible to build cache structure in " . $this->_options['cache_db_complete_path']); - } - } - $this->_structureChecked = true; - } - return true; - } - -} diff --git a/lib/Zend/Cache/Backend/Static.php b/lib/Zend/Cache/Backend/Static.php deleted file mode 100644 index 5a5477a3aad..00000000000 --- a/lib/Zend/Cache/Backend/Static.php +++ /dev/null @@ -1,579 +0,0 @@ - null, - 'sub_dir' => 'html', - 'file_extension' => '.html', - 'index_filename' => 'index', - 'file_locking' => true, - 'cache_file_perm' => 0600, - 'cache_directory_perm' => 0700, - 'debug_header' => false, - 'tag_cache' => null, - 'disable_caching' => false - ); - - /** - * Cache for handling tags - * @var Zend_Cache_Core - */ - protected $_tagCache = null; - - /** - * Tagged items - * @var array - */ - protected $_tagged = null; - - /** - * Interceptor child method to handle the case where an Inner - * Cache object is being set since it's not supported by the - * standard backend interface - * - * @param string $name - * @param mixed $value - * @return Zend_Cache_Backend_Static - */ - public function setOption($name, $value) - { - if ($name == 'tag_cache') { - $this->setInnerCache($value); - } else { - // See #ZF-12047 and #GH-91 - if ($name == 'cache_file_umask') { - trigger_error( - "'cache_file_umask' is deprecated -> please use 'cache_file_perm' instead", - E_USER_NOTICE - ); - - $name = 'cache_file_perm'; - } - if ($name == 'cache_directory_umask') { - trigger_error( - "'cache_directory_umask' is deprecated -> please use 'cache_directory_perm' instead", - E_USER_NOTICE - ); - - $name = 'cache_directory_perm'; - } - - parent::setOption($name, $value); - } - return $this; - } - - /** - * Retrieve any option via interception of the parent's statically held - * options including the local option for a tag cache. - * - * @param string $name - * @return mixed - */ - public function getOption($name) - { - $name = strtolower($name); - - if ($name == 'tag_cache') { - return $this->getInnerCache(); - } - - return parent::getOption($name); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * Note : return value is always "string" (unserialization is done by the core not by the backend) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - if (($id = (string)$id) === '') { - $id = $this->_detectId(); - } else { - $id = $this->_decodeId($id); - } - if (!$this->_verifyPath($id)) { - Zend_Cache::throwException('Invalid cache id: does not match expected public_dir path'); - } - if ($doNotTestCacheValidity) { - $this->_log("Zend_Cache_Backend_Static::load() : \$doNotTestCacheValidity=true is unsupported by the Static backend"); - } - - $fileName = basename($id); - if ($fileName === '') { - $fileName = $this->_options['index_filename']; - } - $pathName = $this->_options['public_dir'] . dirname($id); - $file = rtrim($pathName, '/') . '/' . $fileName . $this->_options['file_extension']; - if (file_exists($file)) { - $content = file_get_contents($file); - return $content; - } - - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return bool - */ - public function test($id) - { - $id = $this->_decodeId($id); - if (!$this->_verifyPath($id)) { - Zend_Cache::throwException('Invalid cache id: does not match expected public_dir path'); - } - - $fileName = basename($id); - if ($fileName === '') { - $fileName = $this->_options['index_filename']; - } - if ($this->_tagged === null && $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME)) { - $this->_tagged = $tagged; - } elseif (!$this->_tagged) { - return false; - } - $pathName = $this->_options['public_dir'] . dirname($id); - - // Switch extension if needed - if (isset($this->_tagged[$id])) { - $extension = $this->_tagged[$id]['extension']; - } else { - $extension = $this->_options['file_extension']; - } - $file = $pathName . '/' . $fileName . $extension; - if (file_exists($file)) { - return true; - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - if ($this->_options['disable_caching']) { - return true; - } - $extension = null; - if ($this->_isSerialized($data)) { - $data = unserialize($data); - $extension = '.' . ltrim($data[1], '.'); - $data = $data[0]; - } - - clearstatcache(); - if (($id = (string)$id) === '') { - $id = $this->_detectId(); - } else { - $id = $this->_decodeId($id); - } - - $fileName = basename($id); - if ($fileName === '') { - $fileName = $this->_options['index_filename']; - } - - $pathName = realpath($this->_options['public_dir']) . dirname($id); - $this->_createDirectoriesFor($pathName); - - if ($id === null || strlen($id) == 0) { - $dataUnserialized = unserialize($data); - $data = $dataUnserialized['data']; - } - $ext = $this->_options['file_extension']; - if ($extension) $ext = $extension; - $file = rtrim($pathName, '/') . '/' . $fileName . $ext; - if ($this->_options['file_locking']) { - $result = file_put_contents($file, $data, LOCK_EX); - } else { - $result = file_put_contents($file, $data); - } - @chmod($file, $this->_octdec($this->_options['cache_file_perm'])); - - if ($this->_tagged === null && $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME)) { - $this->_tagged = $tagged; - } elseif ($this->_tagged === null) { - $this->_tagged = array(); - } - if (!isset($this->_tagged[$id])) { - $this->_tagged[$id] = array(); - } - if (!isset($this->_tagged[$id]['tags'])) { - $this->_tagged[$id]['tags'] = array(); - } - $this->_tagged[$id]['tags'] = array_unique(array_merge($this->_tagged[$id]['tags'], $tags)); - $this->_tagged[$id]['extension'] = $ext; - $this->getInnerCache()->save($this->_tagged, self::INNER_CACHE_NAME); - return (bool) $result; - } - - /** - * Recursively create the directories needed to write the static file - */ - protected function _createDirectoriesFor($path) - { - if (!is_dir($path)) { - $oldUmask = umask(0); - if ( !@mkdir($path, $this->_octdec($this->_options['cache_directory_perm']), true)) { - $lastErr = error_get_last(); - umask($oldUmask); - Zend_Cache::throwException("Can't create directory: {$lastErr['message']}"); - } - umask($oldUmask); - } - } - - /** - * Detect serialization of data (cannot predict since this is the only way - * to obey the interface yet pass in another parameter). - * - * In future, ZF 2.0, check if we can just avoid the interface restraints. - * - * This format is the only valid one possible for the class, so it's simple - * to just run a regular expression for the starting serialized format. - */ - protected function _isSerialized($data) - { - return preg_match("/a:2:\{i:0;s:\d+:\"/", $data); - } - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - if (!$this->_verifyPath($id)) { - Zend_Cache::throwException('Invalid cache id: does not match expected public_dir path'); - } - $fileName = basename($id); - if ($this->_tagged === null && $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME)) { - $this->_tagged = $tagged; - } elseif (!$this->_tagged) { - return false; - } - if (isset($this->_tagged[$id])) { - $extension = $this->_tagged[$id]['extension']; - } else { - $extension = $this->_options['file_extension']; - } - if ($fileName === '') { - $fileName = $this->_options['index_filename']; - } - $pathName = $this->_options['public_dir'] . dirname($id); - $file = realpath($pathName) . '/' . $fileName . $extension; - if (!file_exists($file)) { - return false; - } - return unlink($file); - } - - /** - * Remove a cache record recursively for the given directory matching a - * REQUEST_URI based relative path (deletes the actual file matching this - * in addition to the matching directory) - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function removeRecursively($id) - { - if (!$this->_verifyPath($id)) { - Zend_Cache::throwException('Invalid cache id: does not match expected public_dir path'); - } - $fileName = basename($id); - if ($fileName === '') { - $fileName = $this->_options['index_filename']; - } - $pathName = $this->_options['public_dir'] . dirname($id); - $file = $pathName . '/' . $fileName . $this->_options['file_extension']; - $directory = $pathName . '/' . $fileName; - if (file_exists($directory)) { - if (!is_writable($directory)) { - return false; - } - if (is_dir($directory)) { - foreach (new DirectoryIterator($directory) as $file) { - if (true === $file->isFile()) { - if (false === unlink($file->getPathName())) { - return false; - } - } - } - } - rmdir($directory); - } - if (file_exists($file)) { - if (!is_writable($file)) { - return false; - } - return unlink($file); - } - return true; - } - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean true if no problem - * @throws Zend_Exception - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - $result = false; - switch ($mode) { - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - if (empty($tags)) { - throw new Zend_Exception('Cannot use tag matching modes as no tags were defined'); - } - if ($this->_tagged === null && $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME)) { - $this->_tagged = $tagged; - } elseif (!$this->_tagged) { - return true; - } - foreach ($tags as $tag) { - $urls = array_keys($this->_tagged); - foreach ($urls as $url) { - if (isset($this->_tagged[$url]['tags']) && in_array($tag, $this->_tagged[$url]['tags'])) { - $this->remove($url); - unset($this->_tagged[$url]); - } - } - } - $this->getInnerCache()->save($this->_tagged, self::INNER_CACHE_NAME); - $result = true; - break; - case Zend_Cache::CLEANING_MODE_ALL: - if ($this->_tagged === null) { - $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME); - $this->_tagged = $tagged; - } - if ($this->_tagged === null || empty($this->_tagged)) { - return true; - } - $urls = array_keys($this->_tagged); - foreach ($urls as $url) { - $this->remove($url); - unset($this->_tagged[$url]); - } - $this->getInnerCache()->save($this->_tagged, self::INNER_CACHE_NAME); - $result = true; - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_Static : Selected Cleaning Mode Currently Unsupported By This Backend"); - break; - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - if (empty($tags)) { - throw new Zend_Exception('Cannot use tag matching modes as no tags were defined'); - } - if ($this->_tagged === null) { - $tagged = $this->getInnerCache()->load(self::INNER_CACHE_NAME); - $this->_tagged = $tagged; - } - if ($this->_tagged === null || empty($this->_tagged)) { - return true; - } - $urls = array_keys($this->_tagged); - foreach ($urls as $url) { - $difference = array_diff($tags, $this->_tagged[$url]['tags']); - if (count($tags) == count($difference)) { - $this->remove($url); - unset($this->_tagged[$url]); - } - } - $this->getInnerCache()->save($this->_tagged, self::INNER_CACHE_NAME); - $result = true; - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - return $result; - } - - /** - * Set an Inner Cache, used here primarily to store Tags associated - * with caches created by this backend. Note: If Tags are lost, the cache - * should be completely cleaned as the mapping of tags to caches will - * have been irrevocably lost. - * - * @param Zend_Cache_Core - * @return void - */ - public function setInnerCache(Zend_Cache_Core $cache) - { - $this->_tagCache = $cache; - $this->_options['tag_cache'] = $cache; - } - - /** - * Get the Inner Cache if set - * - * @return Zend_Cache_Core - */ - public function getInnerCache() - { - if ($this->_tagCache === null) { - Zend_Cache::throwException('An Inner Cache has not been set; use setInnerCache()'); - } - return $this->_tagCache; - } - - /** - * Verify path exists and is non-empty - * - * @param string $path - * @return bool - */ - protected function _verifyPath($path) - { - $path = realpath($path); - $base = realpath($this->_options['public_dir']); - return strncmp($path, $base, strlen($base)) !== 0; - } - - /** - * Determine the page to save from the request - * - * @return string - */ - protected function _detectId() - { - return $_SERVER['REQUEST_URI']; - } - - /** - * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...) - * - * Throw an exception if a problem is found - * - * @param string $string Cache id or tag - * @throws Zend_Cache_Exception - * @return void - * @deprecated Not usable until perhaps ZF 2.0 - */ - protected static function _validateIdOrTag($string) - { - if (!is_string($string)) { - Zend_Cache::throwException('Invalid id or tag : must be a string'); - } - - // Internal only checked in Frontend - not here! - if (substr($string, 0, 9) == 'internal-') { - return; - } - - // Validation assumes no query string, fragments or scheme included - only the path - if (!preg_match( - '/^(?:\/(?:(?:%[[:xdigit:]]{2}|[A-Za-z0-9-_.!~*\'()\[\]:@&=+$,;])*)?)+$/', - $string - ) - ) { - Zend_Cache::throwException("Invalid id or tag '$string' : must be a valid URL path"); - } - } - - /** - * Detect an octal string and return its octal value for file permission ops - * otherwise return the non-string (assumed octal or decimal int already) - * - * @param string $val The potential octal in need of conversion - * @return int - */ - protected function _octdec($val) - { - if (is_string($val) && decoct(octdec($val)) == $val) { - return octdec($val); - } - return $val; - } - - /** - * Decode a request URI from the provided ID - * - * @param string $id - * @return string - */ - protected function _decodeId($id) - { - return pack('H*', $id); - } -} diff --git a/lib/Zend/Cache/Backend/Test.php b/lib/Zend/Cache/Backend/Test.php deleted file mode 100644 index 4e74138a0ec..00000000000 --- a/lib/Zend/Cache/Backend/Test.php +++ /dev/null @@ -1,416 +0,0 @@ -_addLog('construct', array($options)); - } - - /** - * Set the frontend directives - * - * @param array $directives assoc of directives - * @return void - */ - public function setDirectives($directives) - { - $this->_addLog('setDirectives', array($directives)); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * For this test backend only, if $id == 'false', then the method will return false - * if $id == 'serialized', the method will return a serialized array - * ('foo' else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string Cached datas (or false) - */ - public function load($id, $doNotTestCacheValidity = false) - { - $this->_addLog('get', array($id, $doNotTestCacheValidity)); - - if ( $id == 'false' - || $id == 'd8523b3ee441006261eeffa5c3d3a0a7' - || $id == 'e83249ea22178277d5befc2c5e2e9ace' - || $id == '40f649b94977c0a6e76902e2a0b43587' - || $id == '88161989b73a4cbfd0b701c446115a99' - || $id == '205fc79cba24f0f0018eb92c7c8b3ba4' - || $id == '170720e35f38150b811f68a937fb042d') - { - return false; - } - if ($id=='serialized') { - return serialize(array('foo')); - } - if ($id=='serialized2') { - return serialize(array('headers' => array(), 'data' => 'foo')); - } - if ( $id == '71769f39054f75894288e397df04e445' || $id == '615d222619fb20b527168340cebd0578' - || $id == '8a02d218a5165c467e7a5747cc6bd4b6' || $id == '648aca1366211d17cbf48e65dc570bee' - || $id == '4a923ef02d7f997ca14d56dfeae25ea7') { - return serialize(array('foo', 'bar')); - } - if ( $id == 'f53c7d912cc523d9a65834c8286eceb9') { - return serialize(array('foobar')); - } - return 'foo'; - } - - /** - * Test if a cache is available or not (for the given id) - * - * For this test backend only, if $id == 'false', then the method will return false - * (123456 else) - * - * @param string $id Cache id - * @return mixed|false false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $this->_addLog('test', array($id)); - if ($id=='false') { - return false; - } - if (($id=='3c439c922209e2cb0b54d6deffccd75a')) { - return false; - } - return 123456; - } - - /** - * Save some string datas into a cache record - * - * For this test backend only, if $id == 'false', then the method will return false - * (true else) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean True if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $this->_addLog('save', array($data, $id, $tags)); - if (substr($id,-5)=='false') { - return false; - } - return true; - } - - /** - * Remove a cache record - * - * For this test backend only, if $id == 'false', then the method will return false - * (true else) - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - $this->_addLog('remove', array($id)); - if (substr($id,-5)=='false') { - return false; - } - return true; - } - - /** - * Clean some cache records - * - * For this test backend only, if $mode == 'false', then the method will return false - * (true else) - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean True if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - $this->_addLog('clean', array($mode, $tags)); - if ($mode=='false') { - return false; - } - return true; - } - - /** - * Get the last log - * - * @return string The last log - */ - public function getLastLog() - { - return $this->_log[$this->_index - 1]; - } - - /** - * Get the log index - * - * @return int Log index - */ - public function getLogIndex() - { - return $this->_index; - } - - /** - * Get the complete log array - * - * @return array Complete log array - */ - public function getAllLogs() - { - return $this->_log; - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return true; - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - return array( - 'prefix_id1', 'prefix_id2' - ); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - return array( - 'tag1', 'tag2' - ); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - if ($tags == array('tag1', 'tag2')) { - return array('prefix_id1', 'prefix_id2'); - } - - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - if ($tags == array('tag3', 'tag4')) { - return array('prefix_id3', 'prefix_id4'); - } - - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - if ($tags == array('tag5', 'tag6')) { - return array('prefix_id5', 'prefix_id6'); - } - - return array(); - } - - /** - * Return the filling percentage of the backend storage - * - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - return 50; - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - return true; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => true, - 'tags' => true, - 'expired_read' => false, - 'priority' => true, - 'infinite_lifetime' => true, - 'get_list' => true - ); - } - - /** - * Add an event to the log array - * - * @param string $methodName MethodName - * @param array $args Arguments - * @return void - */ - private function _addLog($methodName, $args) - { - $this->_log[$this->_index] = array( - 'methodName' => $methodName, - 'args' => $args - ); - $this->_index = $this->_index + 1; - } - -} diff --git a/lib/Zend/Cache/Backend/TwoLevels.php b/lib/Zend/Cache/Backend/TwoLevels.php deleted file mode 100644 index 48835eb4259..00000000000 --- a/lib/Zend/Cache/Backend/TwoLevels.php +++ /dev/null @@ -1,548 +0,0 @@ - (string) slow_backend : - * - Slow backend name - * - Must implement the Zend_Cache_Backend_ExtendedInterface - * - Should provide a big storage - * - * =====> (string) fast_backend : - * - Flow backend name - * - Must implement the Zend_Cache_Backend_ExtendedInterface - * - Must be much faster than slow_backend - * - * =====> (array) slow_backend_options : - * - Slow backend options (see corresponding backend) - * - * =====> (array) fast_backend_options : - * - Fast backend options (see corresponding backend) - * - * =====> (int) stats_update_factor : - * - Disable / Tune the computation of the fast backend filling percentage - * - When saving a record into cache : - * 1 => systematic computation of the fast backend filling percentage - * x (integer) > 1 => computation of the fast backend filling percentage randomly 1 times on x cache write - * - * =====> (boolean) slow_backend_custom_naming : - * =====> (boolean) fast_backend_custom_naming : - * =====> (boolean) slow_backend_autoload : - * =====> (boolean) fast_backend_autoload : - * - See Zend_Cache::factory() method - * - * =====> (boolean) auto_fill_fast_cache - * - If true, automatically fill the fast cache when a cache record was not found in fast cache, but did - * exist in slow cache. This can be usefull when a non-persistent cache like APC or Memcached got - * purged for whatever reason. - * - * =====> (boolean) auto_refresh_fast_cache - * - If true, auto refresh the fast cache when a cache record is hit - * - * @var array available options - */ - protected $_options = array( - 'slow_backend' => 'File', - 'fast_backend' => 'Apc', - 'slow_backend_options' => array(), - 'fast_backend_options' => array(), - 'stats_update_factor' => 10, - 'slow_backend_custom_naming' => false, - 'fast_backend_custom_naming' => false, - 'slow_backend_autoload' => false, - 'fast_backend_autoload' => false, - 'auto_fill_fast_cache' => true, - 'auto_refresh_fast_cache' => true - ); - - /** - * Slow Backend - * - * @var Zend_Cache_Backend_ExtendedInterface - */ - protected $_slowBackend; - - /** - * Fast Backend - * - * @var Zend_Cache_Backend_ExtendedInterface - */ - protected $_fastBackend; - - /** - * Cache for the fast backend filling percentage - * - * @var int - */ - protected $_fastBackendFillingPercentage = null; - - /** - * Constructor - * - * @param array $options Associative array of options - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - parent::__construct($options); - - if ($this->_options['slow_backend'] === null) { - Zend_Cache::throwException('slow_backend option has to set'); - } elseif ($this->_options['slow_backend'] instanceof Zend_Cache_Backend_ExtendedInterface) { - $this->_slowBackend = $this->_options['slow_backend']; - } else { - $this->_slowBackend = Zend_Cache::_makeBackend( - $this->_options['slow_backend'], - $this->_options['slow_backend_options'], - $this->_options['slow_backend_custom_naming'], - $this->_options['slow_backend_autoload'] - ); - if (!in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_slowBackend))) { - Zend_Cache::throwException('slow_backend must implement the Zend_Cache_Backend_ExtendedInterface interface'); - } - } - - if ($this->_options['fast_backend'] === null) { - Zend_Cache::throwException('fast_backend option has to set'); - } elseif ($this->_options['fast_backend'] instanceof Zend_Cache_Backend_ExtendedInterface) { - $this->_fastBackend = $this->_options['fast_backend']; - } else { - $this->_fastBackend = Zend_Cache::_makeBackend( - $this->_options['fast_backend'], - $this->_options['fast_backend_options'], - $this->_options['fast_backend_custom_naming'], - $this->_options['fast_backend_autoload'] - ); - if (!in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_fastBackend))) { - Zend_Cache::throwException('fast_backend must implement the Zend_Cache_Backend_ExtendedInterface interface'); - } - } - - $this->_slowBackend->setDirectives($this->_directives); - $this->_fastBackend->setDirectives($this->_directives); - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $fastTest = $this->_fastBackend->test($id); - if ($fastTest) { - return $fastTest; - } else { - return $this->_slowBackend->test($id); - } - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false, $priority = 8) - { - $usage = $this->_getFastFillingPercentage('saving'); - $boolFast = true; - $lifetime = $this->getLifetime($specificLifetime); - $preparedData = $this->_prepareData($data, $lifetime, $priority); - if (($priority > 0) && (10 * $priority >= $usage)) { - $fastLifetime = $this->_getFastLifetime($lifetime, $priority); - $boolFast = $this->_fastBackend->save($preparedData, $id, array(), $fastLifetime); - $boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime); - } else { - $boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime); - if ($boolSlow === true) { - $boolFast = $this->_fastBackend->remove($id); - if (!$boolFast && !$this->_fastBackend->test($id)) { - // some backends return false on remove() even if the key never existed. (and it won't if fast is full) - // all we care about is that the key doesn't exist now - $boolFast = true; - } - } - } - - return ($boolFast && $boolSlow); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * Note : return value is always "string" (unserialization is done by the core not by the backend) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false) - { - $resultFast = $this->_fastBackend->load($id, $doNotTestCacheValidity); - if ($resultFast === false) { - $resultSlow = $this->_slowBackend->load($id, $doNotTestCacheValidity); - if ($resultSlow === false) { - // there is no cache at all for this id - return false; - } - } - $array = $resultFast !== false ? unserialize($resultFast) : unserialize($resultSlow); - - //In case no cache entry was found in the FastCache and auto-filling is enabled, copy data to FastCache - if ($resultFast === false && $this->_options['auto_fill_fast_cache']) { - $preparedData = $this->_prepareData($array['data'], $array['lifetime'], $array['priority']); - $this->_fastBackend->save($preparedData, $id, array(), $array['lifetime']); - } - // maybe, we have to refresh the fast cache ? - elseif ($this->_options['auto_refresh_fast_cache']) { - if ($array['priority'] == 10) { - // no need to refresh the fast cache with priority = 10 - return $array['data']; - } - $newFastLifetime = $this->_getFastLifetime($array['lifetime'], $array['priority'], time() - $array['expire']); - // we have the time to refresh the fast cache - $usage = $this->_getFastFillingPercentage('loading'); - if (($array['priority'] > 0) && (10 * $array['priority'] >= $usage)) { - // we can refresh the fast cache - $preparedData = $this->_prepareData($array['data'], $array['lifetime'], $array['priority']); - $this->_fastBackend->save($preparedData, $id, array(), $newFastLifetime); - } - } - return $array['data']; - } - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - $boolFast = $this->_fastBackend->remove($id); - $boolSlow = $this->_slowBackend->remove($id); - return $boolFast && $boolSlow; - } - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - $boolFast = $this->_fastBackend->clean(Zend_Cache::CLEANING_MODE_ALL); - $boolSlow = $this->_slowBackend->clean(Zend_Cache::CLEANING_MODE_ALL); - return $boolFast && $boolSlow; - break; - case Zend_Cache::CLEANING_MODE_OLD: - return $this->_slowBackend->clean(Zend_Cache::CLEANING_MODE_OLD); - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - $ids = $this->_slowBackend->getIdsMatchingTags($tags); - $res = true; - foreach ($ids as $id) { - $bool = $this->remove($id); - $res = $res && $bool; - } - return $res; - break; - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - $ids = $this->_slowBackend->getIdsNotMatchingTags($tags); - $res = true; - foreach ($ids as $id) { - $bool = $this->remove($id); - $res = $res && $bool; - } - return $res; - break; - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $ids = $this->_slowBackend->getIdsMatchingAnyTags($tags); - $res = true; - foreach ($ids as $id) { - $bool = $this->remove($id); - $res = $res && $bool; - } - return $res; - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - return $this->_slowBackend->getIds(); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - return $this->_slowBackend->getTags(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - return $this->_slowBackend->getIdsMatchingTags($tags); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - return $this->_slowBackend->getIdsNotMatchingTags($tags); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - return $this->_slowBackend->getIdsMatchingAnyTags($tags); - } - - /** - * Return the filling percentage of the backend storage - * - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - return $this->_slowBackend->getFillingPercentage(); - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - return $this->_slowBackend->getMetadatas($id); - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - return $this->_slowBackend->touch($id, $extraLifetime); - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - $slowBackendCapabilities = $this->_slowBackend->getCapabilities(); - return array( - 'automatic_cleaning' => $slowBackendCapabilities['automatic_cleaning'], - 'tags' => $slowBackendCapabilities['tags'], - 'expired_read' => $slowBackendCapabilities['expired_read'], - 'priority' => $slowBackendCapabilities['priority'], - 'infinite_lifetime' => $slowBackendCapabilities['infinite_lifetime'], - 'get_list' => $slowBackendCapabilities['get_list'] - ); - } - - /** - * Prepare a serialized array to store datas and metadatas informations - * - * @param string $data data to store - * @param int $lifetime original lifetime - * @param int $priority priority - * @return string serialize array to store into cache - */ - private function _prepareData($data, $lifetime, $priority) - { - $lt = $lifetime; - if ($lt === null) { - $lt = 9999999999; - } - return serialize(array( - 'data' => $data, - 'lifetime' => $lifetime, - 'expire' => time() + $lt, - 'priority' => $priority - )); - } - - /** - * Compute and return the lifetime for the fast backend - * - * @param int $lifetime original lifetime - * @param int $priority priority - * @param int $maxLifetime maximum lifetime - * @return int lifetime for the fast backend - */ - private function _getFastLifetime($lifetime, $priority, $maxLifetime = null) - { - if ($lifetime <= 0) { - // if no lifetime, we have an infinite lifetime - // we need to use arbitrary lifetimes - $fastLifetime = (int) (2592000 / (11 - $priority)); - } else { - // prevent computed infinite lifetime (0) by ceil - $fastLifetime = (int) ceil($lifetime / (11 - $priority)); - } - - if ($maxLifetime >= 0 && $fastLifetime > $maxLifetime) { - return $maxLifetime; - } - - return $fastLifetime; - } - - /** - * PUBLIC METHOD FOR UNIT TESTING ONLY ! - * - * Force a cache record to expire - * - * @param string $id cache id - */ - public function ___expire($id) - { - $this->_fastBackend->remove($id); - $this->_slowBackend->___expire($id); - } - - private function _getFastFillingPercentage($mode) - { - - if ($mode == 'saving') { - // mode saving - if ($this->_fastBackendFillingPercentage === null) { - $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage(); - } else { - $rand = rand(1, $this->_options['stats_update_factor']); - if ($rand == 1) { - // we force a refresh - $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage(); - } - } - } else { - // mode loading - // we compute the percentage only if it's not available in cache - if ($this->_fastBackendFillingPercentage === null) { - $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage(); - } - } - return $this->_fastBackendFillingPercentage; - } - -} diff --git a/lib/Zend/Cache/Backend/WinCache.php b/lib/Zend/Cache/Backend/WinCache.php deleted file mode 100644 index c6a51b4f40b..00000000000 --- a/lib/Zend/Cache/Backend/WinCache.php +++ /dev/null @@ -1,349 +0,0 @@ - infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - $result = wincache_ucache_set($id, array($data, time(), $lifetime), $lifetime); - if (count($tags) > 0) { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_WINCACHE_BACKEND); - } - return $result; - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - return wincache_ucache_delete($id); - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode clean mode - * @param array $tags array of tags - * @throws Zend_Cache_Exception - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - return wincache_ucache_clear(); - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_WinCache::clean() : CLEANING_MODE_OLD is unsupported by the WinCache backend"); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_WINCACHE_BACKEND); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * DEPRECATED : use getCapabilities() instead - * - * @deprecated - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return false; - } - - /** - * Return the filling percentage of the backend storage - * - * @throws Zend_Cache_Exception - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - $mem = wincache_ucache_meminfo(); - $memSize = $mem['memory_total']; - $memUsed = $memSize - $mem['memory_free']; - if ($memSize == 0) { - Zend_Cache::throwException('can\'t get WinCache memory size'); - } - if ($memUsed > $memSize) { - return 100; - } - return ((int) (100. * ($memUsed / $memSize))); - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_WINCACHE_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_WINCACHE_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_WINCACHE_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of any matching cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_WINCACHE_BACKEND); - return array(); - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - $res = array(); - $array = wincache_ucache_info(); - $records = $array['ucache_entries']; - foreach ($records as $record) { - $res[] = $record['key_name']; - } - return $res; - } - - /** - * Return an array of metadatas for the given cache id - * - * The array must include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - $tmp = wincache_ucache_get($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - return false; - } - $lifetime = $tmp[2]; - return array( - 'expire' => $mtime + $lifetime, - 'tags' => array(), - 'mtime' => $mtime - ); - } - return false; - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - $tmp = wincache_ucache_get($id); - if (is_array($tmp)) { - $data = $tmp[0]; - $mtime = $tmp[1]; - if (!isset($tmp[2])) { - return false; - } - $lifetime = $tmp[2]; - $newLifetime = $lifetime - (time() - $mtime) + $extraLifetime; - if ($newLifetime <=0) { - return false; - } - return wincache_ucache_set($id, array($data, time(), $newLifetime), $newLifetime); - } - return false; - } - - /** - * Return an associative array of capabilities (booleans) of the backend - * - * The array must include these keys : - * - automatic_cleaning (is automating cleaning necessary) - * - tags (are tags supported) - * - expired_read (is it possible to read expired cache records - * (for doNotTestCacheValidity option for example)) - * - priority does the backend deal with priority when saving - * - infinite_lifetime (is infinite lifetime can work with this backend) - * - get_list (is it possible to get the list of cache ids and the complete list of tags) - * - * @return array associative of with capabilities - */ - public function getCapabilities() - { - return array( - 'automatic_cleaning' => false, - 'tags' => false, - 'expired_read' => false, - 'priority' => false, - 'infinite_lifetime' => false, - 'get_list' => true - ); - } - -} diff --git a/lib/Zend/Cache/Backend/Xcache.php b/lib/Zend/Cache/Backend/Xcache.php deleted file mode 100644 index 504bcf73f8f..00000000000 --- a/lib/Zend/Cache/Backend/Xcache.php +++ /dev/null @@ -1,221 +0,0 @@ - (string) user : - * xcache.admin.user (necessary for the clean() method) - * - * =====> (string) password : - * xcache.admin.pass (clear, not MD5) (necessary for the clean() method) - * - * @var array available options - */ - protected $_options = array( - 'user' => null, - 'password' => null - ); - - /** - * Constructor - * - * @param array $options associative array of options - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - if (!extension_loaded('xcache')) { - Zend_Cache::throwException('The xcache extension must be loaded for using this backend !'); - } - parent::__construct($options); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * WARNING $doNotTestCacheValidity=true is unsupported by the Xcache backend - * - * @param string $id cache id - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string cached datas (or false) - */ - public function load($id, $doNotTestCacheValidity = false) - { - if ($doNotTestCacheValidity) { - $this->_log("Zend_Cache_Backend_Xcache::load() : \$doNotTestCacheValidity=true is unsupported by the Xcache backend"); - } - $tmp = xcache_get($id); - if (is_array($tmp)) { - return $tmp[0]; - } - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - if (xcache_isset($id)) { - $tmp = xcache_get($id); - if (is_array($tmp)) { - return $tmp[1]; - } - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data datas to cache - * @param string $id cache id - * @param array $tags array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime if != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - $result = xcache_set($id, array($data, time()), $lifetime); - if (count($tags) > 0) { - $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_XCACHE_BACKEND); - } - return $result; - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - return xcache_unset($id); - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode clean mode - * @param array $tags array of tags - * @throws Zend_Cache_Exception - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - // Necessary because xcache_clear_cache() need basic authentification - $backup = array(); - if (isset($_SERVER['PHP_AUTH_USER'])) { - $backup['PHP_AUTH_USER'] = $_SERVER['PHP_AUTH_USER']; - } - if (isset($_SERVER['PHP_AUTH_PW'])) { - $backup['PHP_AUTH_PW'] = $_SERVER['PHP_AUTH_PW']; - } - if ($this->_options['user']) { - $_SERVER['PHP_AUTH_USER'] = $this->_options['user']; - } - if ($this->_options['password']) { - $_SERVER['PHP_AUTH_PW'] = $this->_options['password']; - } - - $cnt = xcache_count(XC_TYPE_VAR); - for ($i=0; $i < $cnt; $i++) { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - - if (isset($backup['PHP_AUTH_USER'])) { - $_SERVER['PHP_AUTH_USER'] = $backup['PHP_AUTH_USER']; - $_SERVER['PHP_AUTH_PW'] = $backup['PHP_AUTH_PW']; - } - return true; - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_Xcache::clean() : CLEANING_MODE_OLD is unsupported by the Xcache backend"); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_XCACHE_BACKEND); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Return true if the automatic cleaning is available for the backend - * - * @return boolean - */ - public function isAutomaticCleaningAvailable() - { - return false; - } - -} diff --git a/lib/Zend/Cache/Backend/ZendPlatform.php b/lib/Zend/Cache/Backend/ZendPlatform.php deleted file mode 100644 index 97f4e1ae49c..00000000000 --- a/lib/Zend/Cache/Backend/ZendPlatform.php +++ /dev/null @@ -1,317 +0,0 @@ -_directives['lifetime']; - } - $res = output_cache_get($id, $lifetime); - if($res) { - return $res[0]; - } else { - return false; - } - } - - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id Cache id - * @return mixed|false false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id) - { - $result = output_cache_get($id, $this->_directives['lifetime']); - if ($result) { - return $result[1]; - } - return false; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Data to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - if (!($specificLifetime === false)) { - $this->_log("Zend_Cache_Backend_ZendPlatform::save() : non false specifc lifetime is unsuported for this backend"); - } - - $lifetime = $this->_directives['lifetime']; - $result1 = output_cache_put($id, array($data, time())); - $result2 = (count($tags) == 0); - - foreach ($tags as $tag) { - $tagid = self::TAGS_PREFIX.$tag; - $old_tags = output_cache_get($tagid, $lifetime); - if ($old_tags === false) { - $old_tags = array(); - } - $old_tags[$id] = $id; - output_cache_remove_key($tagid); - $result2 = output_cache_put($tagid, $old_tags); - } - - return $result1 && $result2; - } - - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id) - { - return output_cache_remove_key($id); - } - - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * This mode is not supported in this backend - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => unsupported - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - case Zend_Cache::CLEANING_MODE_OLD: - $cache_dir = ini_get('zend_accelerator.output_cache_dir'); - if (!$cache_dir) { - return false; - } - $cache_dir .= '/.php_cache_api/'; - return $this->_clean($cache_dir, $mode); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - $idlist = null; - foreach ($tags as $tag) { - $next_idlist = output_cache_get(self::TAGS_PREFIX.$tag, $this->_directives['lifetime']); - if ($idlist) { - $idlist = array_intersect_assoc($idlist, $next_idlist); - } else { - $idlist = $next_idlist; - } - if (count($idlist) == 0) { - // if ID list is already empty - we may skip checking other IDs - $idlist = null; - break; - } - } - if ($idlist) { - foreach ($idlist as $id) { - output_cache_remove_key($id); - } - } - return true; - break; - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - $this->_log("Zend_Cache_Backend_ZendPlatform::clean() : CLEANING_MODE_NOT_MATCHING_TAG is not supported by the Zend Platform backend"); - return false; - break; - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $idlist = null; - foreach ($tags as $tag) { - $next_idlist = output_cache_get(self::TAGS_PREFIX.$tag, $this->_directives['lifetime']); - if ($idlist) { - $idlist = array_merge_recursive($idlist, $next_idlist); - } else { - $idlist = $next_idlist; - } - if (count($idlist) == 0) { - // if ID list is already empty - we may skip checking other IDs - $idlist = null; - break; - } - } - if ($idlist) { - foreach ($idlist as $id) { - output_cache_remove_key($id); - } - } - return true; - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } - - /** - * Clean a directory and recursivly go over it's subdirectories - * - * Remove all the cached files that need to be cleaned (according to mode and files mtime) - * - * @param string $dir Path of directory ot clean - * @param string $mode The same parameter as in Zend_Cache_Backend_ZendPlatform::clean() - * @return boolean True if ok - */ - private function _clean($dir, $mode) - { - $d = @dir($dir); - if (!$d) { - return false; - } - $result = true; - while (false !== ($file = $d->read())) { - if ($file == '.' || $file == '..') { - continue; - } - $file = $d->path . $file; - if (is_dir($file)) { - $result = ($this->_clean($file .'/', $mode)) && ($result); - } else { - if ($mode == Zend_Cache::CLEANING_MODE_ALL) { - $result = ($this->_remove($file)) && ($result); - } else if ($mode == Zend_Cache::CLEANING_MODE_OLD) { - // Files older than lifetime get deleted from cache - if ($this->_directives['lifetime'] !== null) { - if ((time() - @filemtime($file)) > $this->_directives['lifetime']) { - $result = ($this->_remove($file)) && ($result); - } - } - } - } - } - $d->close(); - return $result; - } - - /** - * Remove a file - * - * If we can't remove the file (because of locks or any problem), we will touch - * the file to invalidate it - * - * @param string $file Complete file path - * @return boolean True if ok - */ - private function _remove($file) - { - if (!@unlink($file)) { - # If we can't remove the file (because of locks or any problem), we will touch - # the file to invalidate it - $this->_log("Zend_Cache_Backend_ZendPlatform::_remove() : we can't remove $file => we are going to try to invalidate it"); - if ($this->_directives['lifetime'] === null) { - return false; - } - if (!file_exists($file)) { - return false; - } - return @touch($file, time() - 2*abs($this->_directives['lifetime'])); - } - return true; - } - -} diff --git a/lib/Zend/Cache/Backend/ZendServer.php b/lib/Zend/Cache/Backend/ZendServer.php deleted file mode 100644 index 396c38ef2ec..00000000000 --- a/lib/Zend/Cache/Backend/ZendServer.php +++ /dev/null @@ -1,207 +0,0 @@ - (string) namespace : - * Namespace to be used for chaching operations - * - * @var array available options - */ - protected $_options = array( - 'namespace' => 'zendframework' - ); - - /** - * Store data - * - * @param mixed $data Object to store - * @param string $id Cache id - * @param int $timeToLive Time to live in seconds - * @throws Zend_Cache_Exception - */ - abstract protected function _store($data, $id, $timeToLive); - - /** - * Fetch data - * - * @param string $id Cache id - * @throws Zend_Cache_Exception - */ - abstract protected function _fetch($id); - - /** - * Unset data - * - * @param string $id Cache id - */ - abstract protected function _unset($id); - - /** - * Clear cache - */ - abstract protected function _clear(); - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id cache id - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string cached datas (or false) - */ - public function load($id, $doNotTestCacheValidity = false) - { - $tmp = $this->_fetch($id); - if ($tmp !== null) { - return $tmp; - } - return false; - } - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record - * @throws Zend_Cache_Exception - */ - public function test($id) - { - $tmp = $this->_fetch('internal-metadatas---' . $id); - if ($tmp !== false) { - if (!is_array($tmp) || !isset($tmp['mtime'])) { - Zend_Cache::throwException('Cache metadata for \'' . $id . '\' id is corrupted' ); - } - return $tmp['mtime']; - } - return false; - } - - /** - * Compute & return the expire time - * - * @return int expire time (unix timestamp) - */ - private function _expireTime($lifetime) - { - if ($lifetime === null) { - return 9999999999; - } - return time() + $lifetime; - } - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data datas to cache - * @param string $id cache id - * @param array $tags array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime if != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - $lifetime = $this->getLifetime($specificLifetime); - $metadatas = array( - 'mtime' => time(), - 'expire' => $this->_expireTime($lifetime), - ); - - if (count($tags) > 0) { - $this->_log('Zend_Cache_Backend_ZendServer::save() : tags are unsupported by the ZendServer backends'); - } - - return $this->_store($data, $id, $lifetime) && - $this->_store($metadatas, 'internal-metadatas---' . $id, $lifetime); - } - - /** - * Remove a cache record - * - * @param string $id cache id - * @return boolean true if no problem - */ - public function remove($id) - { - $result1 = $this->_unset($id); - $result2 = $this->_unset('internal-metadatas---' . $id); - - return $result1 && $result2; - } - - /** - * Clean some cache records - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => unsupported - * 'matchingTag' => unsupported - * 'notMatchingTag' => unsupported - * 'matchingAnyTag' => unsupported - * - * @param string $mode clean mode - * @param array $tags array of tags - * @throws Zend_Cache_Exception - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) - { - switch ($mode) { - case Zend_Cache::CLEANING_MODE_ALL: - $this->_clear(); - return true; - break; - case Zend_Cache::CLEANING_MODE_OLD: - $this->_log("Zend_Cache_Backend_ZendServer::clean() : CLEANING_MODE_OLD is unsupported by the Zend Server backends."); - break; - case Zend_Cache::CLEANING_MODE_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: - case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: - $this->_clear(); - $this->_log('Zend_Cache_Backend_ZendServer::clean() : tags are unsupported by the Zend Server backends.'); - break; - default: - Zend_Cache::throwException('Invalid mode for clean() method'); - break; - } - } -} diff --git a/lib/Zend/Cache/Backend/ZendServer/Disk.php b/lib/Zend/Cache/Backend/ZendServer/Disk.php deleted file mode 100644 index 74317da1eab..00000000000 --- a/lib/Zend/Cache/Backend/ZendServer/Disk.php +++ /dev/null @@ -1,101 +0,0 @@ -_options['namespace'] . '::' . $id, - $data, - $timeToLive) === false) { - $this->_log('Store operation failed.'); - return false; - } - return true; - } - - /** - * Fetch data - * - * @param string $id Cache id - * @return mixed|null - */ - protected function _fetch($id) - { - return zend_disk_cache_fetch($this->_options['namespace'] . '::' . $id); - } - - /** - * Unset data - * - * @param string $id Cache id - * @return boolean true if no problem - */ - protected function _unset($id) - { - return zend_disk_cache_delete($this->_options['namespace'] . '::' . $id); - } - - /** - * Clear cache - */ - protected function _clear() - { - zend_disk_cache_clear($this->_options['namespace']); - } -} diff --git a/lib/Zend/Cache/Backend/ZendServer/ShMem.php b/lib/Zend/Cache/Backend/ZendServer/ShMem.php deleted file mode 100644 index 668fa4ca54a..00000000000 --- a/lib/Zend/Cache/Backend/ZendServer/ShMem.php +++ /dev/null @@ -1,101 +0,0 @@ -_options['namespace'] . '::' . $id, - $data, - $timeToLive) === false) { - $this->_log('Store operation failed.'); - return false; - } - return true; - } - - /** - * Fetch data - * - * @param string $id Cache id - * @return mixed|null - */ - protected function _fetch($id) - { - return zend_shm_cache_fetch($this->_options['namespace'] . '::' . $id); - } - - /** - * Unset data - * - * @param string $id Cache id - * @return boolean true if no problem - */ - protected function _unset($id) - { - return zend_shm_cache_delete($this->_options['namespace'] . '::' . $id); - } - - /** - * Clear cache - */ - protected function _clear() - { - zend_shm_cache_clear($this->_options['namespace']); - } -} diff --git a/lib/Zend/Cache/Core.php b/lib/Zend/Cache/Core.php deleted file mode 100644 index 17c635f21ff..00000000000 --- a/lib/Zend/Cache/Core.php +++ /dev/null @@ -1,765 +0,0 @@ - (boolean) write_control : - * - Enable / disable write control (the cache is read just after writing to detect corrupt entries) - * - Enable write control will lightly slow the cache writing but not the cache reading - * Write control can detect some corrupt cache files but maybe it's not a perfect control - * - * ====> (boolean) caching : - * - Enable / disable caching - * (can be very useful for the debug of cached scripts) - * - * =====> (string) cache_id_prefix : - * - prefix for cache ids (namespace) - * - * ====> (boolean) automatic_serialization : - * - Enable / disable automatic serialization - * - It can be used to save directly datas which aren't strings (but it's slower) - * - * ====> (int) automatic_cleaning_factor : - * - Disable / Tune the automatic cleaning process - * - The automatic cleaning process destroy too old (for the given life time) - * cache files when a new cache file is written : - * 0 => no automatic cache cleaning - * 1 => systematic cache cleaning - * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write - * - * ====> (int) lifetime : - * - Cache lifetime (in seconds) - * - If null, the cache is valid forever. - * - * ====> (boolean) logging : - * - If set to true, logging is activated (but the system is slower) - * - * ====> (boolean) ignore_user_abort - * - If set to true, the core will set the ignore_user_abort PHP flag inside the - * save() method to avoid cache corruptions in some cases (default false) - * - * @var array $_options available options - */ - protected $_options = array( - 'write_control' => true, - 'caching' => true, - 'cache_id_prefix' => null, - 'automatic_serialization' => false, - 'automatic_cleaning_factor' => 10, - 'lifetime' => 3600, - 'logging' => false, - 'logger' => null, - 'ignore_user_abort' => false - ); - - /** - * Array of options which have to be transfered to backend - * - * @var array $_directivesList - */ - protected static $_directivesList = array('lifetime', 'logging', 'logger'); - - /** - * Not used for the core, just a sort a hint to get a common setOption() method (for the core and for frontends) - * - * @var array $_specificOptions - */ - protected $_specificOptions = array(); - - /** - * Last used cache id - * - * @var string $_lastId - */ - private $_lastId = null; - - /** - * True if the backend implements Zend_Cache_Backend_ExtendedInterface - * - * @var boolean $_extendedBackend - */ - protected $_extendedBackend = false; - - /** - * Array of capabilities of the backend (only if it implements Zend_Cache_Backend_ExtendedInterface) - * - * @var array - */ - protected $_backendCapabilities = array(); - - /** - * Constructor - * - * @param array|Zend_Config $options Associative array of options or Zend_Config instance - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - if (!is_array($options)) { - Zend_Cache::throwException("Options passed were not an array" - . " or Zend_Config instance."); - } - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - $this->_loggerSanity(); - } - - /** - * Set options using an instance of type Zend_Config - * - * @param Zend_Config $config - * @return Zend_Cache_Core - */ - public function setConfig(Zend_Config $config) - { - $options = $config->toArray(); - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - return $this; - } - - /** - * Set the backend - * - * @param Zend_Cache_Backend $backendObject - * @throws Zend_Cache_Exception - * @return void - */ - public function setBackend(Zend_Cache_Backend $backendObject) - { - $this->_backend= $backendObject; - // some options (listed in $_directivesList) have to be given - // to the backend too (even if they are not "backend specific") - $directives = array(); - foreach (Zend_Cache_Core::$_directivesList as $directive) { - $directives[$directive] = $this->_options[$directive]; - } - $this->_backend->setDirectives($directives); - if (in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_backend))) { - $this->_extendedBackend = true; - $this->_backendCapabilities = $this->_backend->getCapabilities(); - } - - } - - /** - * Returns the backend - * - * @return Zend_Cache_Backend backend object - */ - public function getBackend() - { - return $this->_backend; - } - - /** - * Public frontend to set an option - * - * There is an additional validation (relatively to the protected _setOption method) - * - * @param string $name Name of the option - * @param mixed $value Value of the option - * @throws Zend_Cache_Exception - * @return void - */ - public function setOption($name, $value) - { - if (!is_string($name)) { - Zend_Cache::throwException("Incorrect option name!"); - } - $name = strtolower($name); - if (array_key_exists($name, $this->_options)) { - // This is a Core option - $this->_setOption($name, $value); - return; - } - if (array_key_exists($name, $this->_specificOptions)) { - // This a specic option of this frontend - $this->_specificOptions[$name] = $value; - return; - } - } - - /** - * Public frontend to get an option value - * - * @param string $name Name of the option - * @throws Zend_Cache_Exception - * @return mixed option value - */ - public function getOption($name) - { - $name = strtolower($name); - - if (array_key_exists($name, $this->_options)) { - // This is a Core option - return $this->_options[$name]; - } - - if (array_key_exists($name, $this->_specificOptions)) { - // This a specic option of this frontend - return $this->_specificOptions[$name]; - } - - Zend_Cache::throwException("Incorrect option name : $name"); - } - - /** - * Set an option - * - * @param string $name Name of the option - * @param mixed $value Value of the option - * @throws Zend_Cache_Exception - * @return void - */ - private function _setOption($name, $value) - { - if (!is_string($name) || !array_key_exists($name, $this->_options)) { - Zend_Cache::throwException("Incorrect option name : $name"); - } - if ($name == 'lifetime' && empty($value)) { - $value = null; - } - $this->_options[$name] = $value; - } - - /** - * Force a new lifetime - * - * The new value is set for the core/frontend but for the backend too (directive) - * - * @param int $newLifetime New lifetime (in seconds) - * @return void - */ - public function setLifetime($newLifetime) - { - $this->_options['lifetime'] = $newLifetime; - $this->_backend->setDirectives(array( - 'lifetime' => $newLifetime - )); - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @param boolean $doNotUnserialize Do not serialize (even if automatic_serialization is true) => for internal use - * @return mixed|false Cached datas - */ - public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false) - { - if (!$this->_options['caching']) { - return false; - } - $id = $this->_id($id); // cache id may need prefix - $this->_lastId = $id; - $this->_validateIdOrTag($id); - - $this->_log("Zend_Cache_Core: load item '{$id}'", 7); - $data = $this->_backend->load($id, $doNotTestCacheValidity); - if ($data===false) { - // no cache available - return false; - } - if ((!$doNotUnserialize) && $this->_options['automatic_serialization']) { - // we need to unserialize before sending the result - return unserialize($data); - } - return $data; - } - - /** - * Test if a cache is available for the given id - * - * @param string $id Cache id - * @return int|false Last modified time of cache entry if it is available, false otherwise - */ - public function test($id) - { - if (!$this->_options['caching']) { - return false; - } - $id = $this->_id($id); // cache id may need prefix - $this->_validateIdOrTag($id); - $this->_lastId = $id; - - $this->_log("Zend_Cache_Core: test item '{$id}'", 7); - return $this->_backend->test($id); - } - - /** - * Save some data in a cache - * - * @param mixed $data Data to put in cache (can be another type than string if automatic_serialization is on) - * @param string $id Cache id (if not set, the last cache id will be used) - * @param array $tags Cache tags - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends - * @throws Zend_Cache_Exception - * @return boolean True if no problem - */ - public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8) - { - if (!$this->_options['caching']) { - return true; - } - if ($id === null) { - $id = $this->_lastId; - } else { - $id = $this->_id($id); - } - $this->_validateIdOrTag($id); - $this->_validateTagsArray($tags); - if ($this->_options['automatic_serialization']) { - // we need to serialize datas before storing them - $data = serialize($data); - } else { - if (!is_string($data)) { - Zend_Cache::throwException("Datas must be string or set automatic_serialization = true"); - } - } - - // automatic cleaning - if ($this->_options['automatic_cleaning_factor'] > 0) { - $rand = rand(1, $this->_options['automatic_cleaning_factor']); - if ($rand==1) { - // new way || deprecated way - if ($this->_extendedBackend || method_exists($this->_backend, 'isAutomaticCleaningAvailable')) { - $this->_log("Zend_Cache_Core::save(): automatic cleaning running", 7); - $this->clean(Zend_Cache::CLEANING_MODE_OLD); - } else { - $this->_log("Zend_Cache_Core::save(): automatic cleaning is not available/necessary with current backend", 4); - } - } - } - - $this->_log("Zend_Cache_Core: save item '{$id}'", 7); - if ($this->_options['ignore_user_abort']) { - $abort = ignore_user_abort(true); - } - if (($this->_extendedBackend) && ($this->_backendCapabilities['priority'])) { - $result = $this->_backend->save($data, $id, $tags, $specificLifetime, $priority); - } else { - $result = $this->_backend->save($data, $id, $tags, $specificLifetime); - } - if ($this->_options['ignore_user_abort']) { - ignore_user_abort($abort); - } - - if (!$result) { - // maybe the cache is corrupted, so we remove it ! - $this->_log("Zend_Cache_Core::save(): failed to save item '{$id}' -> removing it", 4); - $this->_backend->remove($id); - return false; - } - - if ($this->_options['write_control']) { - $data2 = $this->_backend->load($id, true); - if ($data!=$data2) { - $this->_log("Zend_Cache_Core::save(): write control of item '{$id}' failed -> removing it", 4); - $this->_backend->remove($id); - return false; - } - } - - return true; - } - - /** - * Remove a cache - * - * @param string $id Cache id to remove - * @return boolean True if ok - */ - public function remove($id) - { - if (!$this->_options['caching']) { - return true; - } - $id = $this->_id($id); // cache id may need prefix - $this->_validateIdOrTag($id); - - $this->_log("Zend_Cache_Core: remove item '{$id}'", 7); - return $this->_backend->remove($id); - } - - /** - * Clean cache entries - * - * Available modes are : - * 'all' (default) => remove all cache entries ($tags is not used) - * 'old' => remove too old cache entries ($tags is not used) - * 'matchingTag' => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * 'notMatchingTag' => remove cache entries not matching one of the given tags - * ($tags can be an array of strings or a single string) - * 'matchingAnyTag' => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode - * @param array|string $tags - * @throws Zend_Cache_Exception - * @return boolean True if ok - */ - public function clean($mode = 'all', $tags = array()) - { - if (!$this->_options['caching']) { - return true; - } - if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL, - Zend_Cache::CLEANING_MODE_OLD, - Zend_Cache::CLEANING_MODE_MATCHING_TAG, - Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG, - Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG))) { - Zend_Cache::throwException('Invalid cleaning mode'); - } - $this->_validateTagsArray($tags); - - return $this->_backend->clean($mode, $tags); - } - - /** - * Return an array of stored cache ids which match given tags - * - * In case of multiple tags, a logical AND is made between tags - * - * @param array $tags array of tags - * @return array array of matching cache ids (string) - */ - public function getIdsMatchingTags($tags = array()) - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - if (!($this->_backendCapabilities['tags'])) { - Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); - } - - $ids = $this->_backend->getIdsMatchingTags($tags); - - // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) - if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { - $prefix = & $this->_options['cache_id_prefix']; - $prefixLen = strlen($prefix); - foreach ($ids as &$id) { - if (strpos($id, $prefix) === 0) { - $id = substr($id, $prefixLen); - } - } - } - - return $ids; - } - - /** - * Return an array of stored cache ids which don't match given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of not matching cache ids (string) - */ - public function getIdsNotMatchingTags($tags = array()) - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - if (!($this->_backendCapabilities['tags'])) { - Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); - } - - $ids = $this->_backend->getIdsNotMatchingTags($tags); - - // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) - if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { - $prefix = & $this->_options['cache_id_prefix']; - $prefixLen = strlen($prefix); - foreach ($ids as &$id) { - if (strpos($id, $prefix) === 0) { - $id = substr($id, $prefixLen); - } - } - } - - return $ids; - } - - /** - * Return an array of stored cache ids which match any given tags - * - * In case of multiple tags, a logical OR is made between tags - * - * @param array $tags array of tags - * @return array array of matching any cache ids (string) - */ - public function getIdsMatchingAnyTags($tags = array()) - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - if (!($this->_backendCapabilities['tags'])) { - Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); - } - - $ids = $this->_backend->getIdsMatchingAnyTags($tags); - - // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) - if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { - $prefix = & $this->_options['cache_id_prefix']; - $prefixLen = strlen($prefix); - foreach ($ids as &$id) { - if (strpos($id, $prefix) === 0) { - $id = substr($id, $prefixLen); - } - } - } - - return $ids; - } - - /** - * Return an array of stored cache ids - * - * @return array array of stored cache ids (string) - */ - public function getIds() - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - - $ids = $this->_backend->getIds(); - - // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) - if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { - $prefix = & $this->_options['cache_id_prefix']; - $prefixLen = strlen($prefix); - foreach ($ids as &$id) { - if (strpos($id, $prefix) === 0) { - $id = substr($id, $prefixLen); - } - } - } - - return $ids; - } - - /** - * Return an array of stored tags - * - * @return array array of stored tags (string) - */ - public function getTags() - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - if (!($this->_backendCapabilities['tags'])) { - Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); - } - return $this->_backend->getTags(); - } - - /** - * Return the filling percentage of the backend storage - * - * @return int integer between 0 and 100 - */ - public function getFillingPercentage() - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - return $this->_backend->getFillingPercentage(); - } - - /** - * Return an array of metadatas for the given cache id - * - * The array will include these keys : - * - expire : the expire timestamp - * - tags : a string array of tags - * - mtime : timestamp of last modification time - * - * @param string $id cache id - * @return array array of metadatas (false if the cache id is not found) - */ - public function getMetadatas($id) - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - $id = $this->_id($id); // cache id may need prefix - return $this->_backend->getMetadatas($id); - } - - /** - * Give (if possible) an extra lifetime to the given cache id - * - * @param string $id cache id - * @param int $extraLifetime - * @return boolean true if ok - */ - public function touch($id, $extraLifetime) - { - if (!$this->_extendedBackend) { - Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); - } - $id = $this->_id($id); // cache id may need prefix - - $this->_log("Zend_Cache_Core: touch item '{$id}'", 7); - return $this->_backend->touch($id, $extraLifetime); - } - - /** - * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...) - * - * Throw an exception if a problem is found - * - * @param string $string Cache id or tag - * @throws Zend_Cache_Exception - * @return void - */ - protected function _validateIdOrTag($string) - { - if (!is_string($string)) { - Zend_Cache::throwException('Invalid id or tag : must be a string'); - } - if (substr($string, 0, 9) == 'internal-') { - Zend_Cache::throwException('"internal-*" ids or tags are reserved'); - } - if (!preg_match('~^[a-zA-Z0-9_]+$~D', $string)) { - Zend_Cache::throwException("Invalid id or tag '$string' : must use only [a-zA-Z0-9_]"); - } - } - - /** - * Validate a tags array (security, reliable filenames, reserved prefixes...) - * - * Throw an exception if a problem is found - * - * @param array $tags Array of tags - * @throws Zend_Cache_Exception - * @return void - */ - protected function _validateTagsArray($tags) - { - if (!is_array($tags)) { - Zend_Cache::throwException('Invalid tags array : must be an array'); - } - foreach($tags as $tag) { - $this->_validateIdOrTag($tag); - } - reset($tags); - } - - /** - * Make sure if we enable logging that the Zend_Log class - * is available. - * Create a default log object if none is set. - * - * @throws Zend_Cache_Exception - * @return void - */ - protected function _loggerSanity() - { - if (!isset($this->_options['logging']) || !$this->_options['logging']) { - return; - } - - if (isset($this->_options['logger']) && $this->_options['logger'] instanceof Zend_Log) { - return; - } - - // Create a default logger to the standard output stream - #require_once 'Zend/Log.php'; - #require_once 'Zend/Log/Writer/Stream.php'; - #require_once 'Zend/Log/Filter/Priority.php'; - $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); - $logger->addFilter(new Zend_Log_Filter_Priority(Zend_Log::WARN, '<=')); - $this->_options['logger'] = $logger; - } - - /** - * Log a message at the WARN (4) priority. - * - * @param string $message - * @throws Zend_Cache_Exception - * @return void - */ - protected function _log($message, $priority = 4) - { - if (!$this->_options['logging']) { - return; - } - if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) { - Zend_Cache::throwException('Logging is enabled but logger is not set'); - } - $logger = $this->_options['logger']; - $logger->log($message, $priority); - } - - /** - * Make and return a cache id - * - * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null - * - * @param string $id Cache id - * @return string Cache id (with or without prefix) - */ - protected function _id($id) - { - if (($id !== null) && isset($this->_options['cache_id_prefix'])) { - return $this->_options['cache_id_prefix'] . $id; // return with prefix - } - return $id; // no prefix, just return the $id passed - } - -} diff --git a/lib/Zend/Cache/Exception.php b/lib/Zend/Cache/Exception.php deleted file mode 100644 index 388007a01f8..00000000000 --- a/lib/Zend/Cache/Exception.php +++ /dev/null @@ -1,32 +0,0 @@ -_tags = $tags; - $this->_extension = $extension; - ob_start(array($this, '_flush')); - ob_implicit_flush(false); - $this->_idStack[] = $id; - return false; - } - - /** - * callback for output buffering - * (shouldn't really be called manually) - * - * @param string $data Buffered output - * @return string Data to send to browser - */ - public function _flush($data) - { - $id = array_pop($this->_idStack); - if ($id === null) { - Zend_Cache::throwException('use of _flush() without a start()'); - } - if ($this->_extension) { - $this->save(serialize(array($data, $this->_extension)), $id, $this->_tags); - } else { - $this->save($data, $id, $this->_tags); - } - return $data; - } -} diff --git a/lib/Zend/Cache/Frontend/Class.php b/lib/Zend/Cache/Frontend/Class.php deleted file mode 100644 index a9c7fd54755..00000000000 --- a/lib/Zend/Cache/Frontend/Class.php +++ /dev/null @@ -1,275 +0,0 @@ - (mixed) cached_entity : - * - if set to a class name, we will cache an abstract class and will use only static calls - * - if set to an object, we will cache this object methods - * - * ====> (boolean) cache_by_default : - * - if true, method calls will be cached by default - * - * ====> (array) cached_methods : - * - an array of method names which will be cached (even if cache_by_default = false) - * - * ====> (array) non_cached_methods : - * - an array of method names which won't be cached (even if cache_by_default = true) - * - * @var array available options - */ - protected $_specificOptions = array( - 'cached_entity' => null, - 'cache_by_default' => true, - 'cached_methods' => array(), - 'non_cached_methods' => array() - ); - - /** - * Tags array - * - * @var array - */ - protected $_tags = array(); - - /** - * SpecificLifetime value - * - * false => no specific life time - * - * @var bool|int - */ - protected $_specificLifetime = false; - - /** - * The cached object or the name of the cached abstract class - * - * @var mixed - */ - protected $_cachedEntity = null; - - /** - * The class name of the cached object or cached abstract class - * - * Used to differentiate between different classes with the same method calls. - * - * @var string - */ - protected $_cachedEntityLabel = ''; - - /** - * Priority (used by some particular backends) - * - * @var int - */ - protected $_priority = 8; - - /** - * Constructor - * - * @param array $options Associative array of options - * @throws Zend_Cache_Exception - */ - public function __construct(array $options = array()) - { - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - if ($this->_specificOptions['cached_entity'] === null) { - Zend_Cache::throwException('cached_entity must be set !'); - } - $this->setCachedEntity($this->_specificOptions['cached_entity']); - $this->setOption('automatic_serialization', true); - } - - /** - * Set a specific life time - * - * @param bool|int $specificLifetime - * @return void - */ - public function setSpecificLifetime($specificLifetime = false) - { - $this->_specificLifetime = $specificLifetime; - } - - /** - * Set the priority (used by some particular backends) - * - * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) - */ - public function setPriority($priority) - { - $this->_priority = $priority; - } - - /** - * Public frontend to set an option - * - * Just a wrapper to get a specific behaviour for cached_entity - * - * @param string $name Name of the option - * @param mixed $value Value of the option - * @throws Zend_Cache_Exception - * @return void - */ - public function setOption($name, $value) - { - if ($name == 'cached_entity') { - $this->setCachedEntity($value); - } else { - parent::setOption($name, $value); - } - } - - /** - * Specific method to set the cachedEntity - * - * if set to a class name, we will cache an abstract class and will use only static calls - * if set to an object, we will cache this object methods - * - * @param mixed $cachedEntity - */ - public function setCachedEntity($cachedEntity) - { - if (!is_string($cachedEntity) && !is_object($cachedEntity)) { - Zend_Cache::throwException( - 'cached_entity must be an object or a class name' - ); - } - - $this->_cachedEntity = $cachedEntity; - $this->_specificOptions['cached_entity'] = $cachedEntity; - - if (is_string($this->_cachedEntity)) { - $this->_cachedEntityLabel = $this->_cachedEntity; - } else { - $ro = new ReflectionObject($this->_cachedEntity); - $this->_cachedEntityLabel = $ro->getName(); - } - } - - /** - * Set the cache array - * - * @param array $tags - * @return void - */ - public function setTagsArray($tags = array()) - { - $this->_tags = $tags; - } - - /** - * Main method : call the specified method or get the result from cache - * - * @param string $name Method name - * @param array $parameters Method parameters - * @return mixed Result - * @throws Exception - */ - public function __call($name, $parameters) - { - $callback = array($this->_cachedEntity, $name); - - if (!is_callable($callback, false)) { - Zend_Cache::throwException('Invalid callback'); - } - - $cacheBool1 = $this->_specificOptions['cache_by_default']; - $cacheBool2 = in_array($name, $this->_specificOptions['cached_methods']); - $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_methods']); - $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3)); - - if (!$cache) { - // We do not have not cache - return call_user_func_array($callback, $parameters); - } - - $id = $this->makeId($name, $parameters); - if (($rs = $this->load($id)) && (array_key_exists(0, $rs)) - && (array_key_exists(1, $rs)) - ) { - // A cache is available - $output = $rs[0]; - $return = $rs[1]; - } else { - // A cache is not available (or not valid for this frontend) - ob_start(); - ob_implicit_flush(false); - - try { - $return = call_user_func_array($callback, $parameters); - $output = ob_get_clean(); - $data = array($output, $return); - - $this->save( - $data, $id, $this->_tags, $this->_specificLifetime, - $this->_priority - ); - } catch (Exception $e) { - ob_end_clean(); - throw $e; - } - } - - echo $output; - return $return; - } - - /** - * ZF-9970 - * - * @deprecated - */ - private function _makeId($name, $args) - { - return $this->makeId($name, $args); - } - - /** - * Make a cache id from the method name and parameters - * - * @param string $name Method name - * @param array $args Method parameters - * @return string Cache id - */ - public function makeId($name, array $args = array()) - { - return md5($this->_cachedEntityLabel . '__' . $name . '__' . serialize($args)); - } -} diff --git a/lib/Zend/Cache/Frontend/File.php b/lib/Zend/Cache/Frontend/File.php deleted file mode 100644 index 67dba624764..00000000000 --- a/lib/Zend/Cache/Frontend/File.php +++ /dev/null @@ -1,222 +0,0 @@ - (string) master_file : - * - a complete path of the master file - * - deprecated (see master_files) - * - * ====> (array) master_files : - * - an array of complete path of master files - * - this option has to be set ! - * - * ====> (string) master_files_mode : - * - Zend_Cache_Frontend_File::MODE_AND or Zend_Cache_Frontend_File::MODE_OR - * - if MODE_AND, then all master files have to be touched to get a cache invalidation - * - if MODE_OR (default), then a single touched master file is enough to get a cache invalidation - * - * ====> (boolean) ignore_missing_master_files - * - if set to true, missing master files are ignored silently - * - if set to false (default), an exception is thrown if there is a missing master file - * @var array available options - */ - protected $_specificOptions = array( - 'master_file' => null, - 'master_files' => null, - 'master_files_mode' => 'OR', - 'ignore_missing_master_files' => false - ); - - /** - * Master file mtimes - * - * Array of int - * - * @var array - */ - private $_masterFile_mtimes = null; - - /** - * Constructor - * - * @param array $options Associative array of options - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - if (!isset($this->_specificOptions['master_files'])) { - Zend_Cache::throwException('master_files option must be set'); - } - } - - /** - * Change the master_files option - * - * @param array $masterFiles the complete paths and name of the master files - */ - public function setMasterFiles(array $masterFiles) - { - $this->_specificOptions['master_file'] = null; // to keep a compatibility - $this->_specificOptions['master_files'] = null; - $this->_masterFile_mtimes = array(); - - clearstatcache(); - $i = 0; - foreach ($masterFiles as $masterFile) { - if (file_exists($masterFile)) { - $mtime = filemtime($masterFile); - } else { - $mtime = false; - } - - if (!$this->_specificOptions['ignore_missing_master_files'] && !$mtime) { - Zend_Cache::throwException('Unable to read master_file : ' . $masterFile); - } - - $this->_masterFile_mtimes[$i] = $mtime; - $this->_specificOptions['master_files'][$i] = $masterFile; - if ($i === 0) { // to keep a compatibility - $this->_specificOptions['master_file'] = $masterFile; - } - - $i++; - } - } - - /** - * Change the master_file option - * - * To keep the compatibility - * - * @deprecated - * @param string $masterFile the complete path and name of the master file - */ - public function setMasterFile($masterFile) - { - $this->setMasterFiles(array($masterFile)); - } - - /** - * Public frontend to set an option - * - * Just a wrapper to get a specific behaviour for master_file - * - * @param string $name Name of the option - * @param mixed $value Value of the option - * @throws Zend_Cache_Exception - * @return void - */ - public function setOption($name, $value) - { - if ($name == 'master_file') { - $this->setMasterFile($value); - } else if ($name == 'master_files') { - $this->setMasterFiles($value); - } else { - parent::setOption($name, $value); - } - } - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @param boolean $doNotUnserialize Do not serialize (even if automatic_serialization is true) => for internal use - * @return mixed|false Cached datas - */ - public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false) - { - if (!$doNotTestCacheValidity) { - if ($this->test($id)) { - return parent::load($id, true, $doNotUnserialize); - } - return false; - } - return parent::load($id, true, $doNotUnserialize); - } - - /** - * Test if a cache is available for the given id - * - * @param string $id Cache id - * @return int|false Last modified time of cache entry if it is available, false otherwise - */ - public function test($id) - { - $lastModified = parent::test($id); - if ($lastModified) { - if ($this->_specificOptions['master_files_mode'] == self::MODE_AND) { - // MODE_AND - foreach($this->_masterFile_mtimes as $masterFileMTime) { - if ($masterFileMTime) { - if ($lastModified > $masterFileMTime) { - return $lastModified; - } - } - } - } else { - // MODE_OR - $res = true; - foreach($this->_masterFile_mtimes as $masterFileMTime) { - if ($masterFileMTime) { - if ($lastModified <= $masterFileMTime) { - return false; - } - } - } - return $lastModified; - } - } - return false; - } - -} - diff --git a/lib/Zend/Cache/Frontend/Function.php b/lib/Zend/Cache/Frontend/Function.php deleted file mode 100644 index 234a8effaaa..00000000000 --- a/lib/Zend/Cache/Frontend/Function.php +++ /dev/null @@ -1,179 +0,0 @@ - (boolean) cache_by_default : - * - if true, function calls will be cached by default - * - * ====> (array) cached_functions : - * - an array of function names which will be cached (even if cache_by_default = false) - * - * ====> (array) non_cached_functions : - * - an array of function names which won't be cached (even if cache_by_default = true) - * - * @var array options - */ - protected $_specificOptions = array( - 'cache_by_default' => true, - 'cached_functions' => array(), - 'non_cached_functions' => array() - ); - - /** - * Constructor - * - * @param array $options Associative array of options - * @return void - */ - public function __construct(array $options = array()) - { - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } - $this->setOption('automatic_serialization', true); - } - - /** - * Main method : call the specified function or get the result from cache - * - * @param callback $callback A valid callback - * @param array $parameters Function parameters - * @param array $tags Cache tags - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends - * @return mixed Result - */ - public function call($callback, array $parameters = array(), $tags = array(), $specificLifetime = false, $priority = 8) - { - if (!is_callable($callback, true, $name)) { - Zend_Cache::throwException('Invalid callback'); - } - - $cacheBool1 = $this->_specificOptions['cache_by_default']; - $cacheBool2 = in_array($name, $this->_specificOptions['cached_functions']); - $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_functions']); - $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3)); - if (!$cache) { - // Caching of this callback is disabled - return call_user_func_array($callback, $parameters); - } - - $id = $this->_makeId($callback, $parameters); - if ( ($rs = $this->load($id)) && isset($rs[0], $rs[1])) { - // A cache is available - $output = $rs[0]; - $return = $rs[1]; - } else { - // A cache is not available (or not valid for this frontend) - ob_start(); - ob_implicit_flush(false); - $return = call_user_func_array($callback, $parameters); - $output = ob_get_clean(); - $data = array($output, $return); - $this->save($data, $id, $tags, $specificLifetime, $priority); - } - - echo $output; - return $return; - } - - /** - * ZF-9970 - * - * @deprecated - */ - private function _makeId($callback, array $args) - { - return $this->makeId($callback, $args); - } - - /** - * Make a cache id from the function name and parameters - * - * @param callback $callback A valid callback - * @param array $args Function parameters - * @throws Zend_Cache_Exception - * @return string Cache id - */ - public function makeId($callback, array $args = array()) - { - if (!is_callable($callback, true, $name)) { - Zend_Cache::throwException('Invalid callback'); - } - - // functions, methods and classnames are case-insensitive - $name = strtolower($name); - - // generate a unique id for object callbacks - if (is_object($callback)) { // Closures & __invoke - $object = $callback; - } elseif (isset($callback[0])) { // array($object, 'method') - $object = $callback[0]; - } - if (isset($object)) { - try { - $tmp = @serialize($callback); - } catch (Exception $e) { - Zend_Cache::throwException($e->getMessage()); - } - if (!$tmp) { - $lastErr = error_get_last(); - Zend_Cache::throwException("Can't serialize callback object to generate id: {$lastErr['message']}"); - } - $name.= '__' . $tmp; - } - - // generate a unique id for arguments - $argsStr = ''; - if ($args) { - try { - $argsStr = @serialize(array_values($args)); - } catch (Exception $e) { - Zend_Cache::throwException($e->getMessage()); - } - if (!$argsStr) { - $lastErr = error_get_last(); - throw Zend_Cache::throwException("Can't serialize arguments to generate id: {$lastErr['message']}"); - } - } - - return md5($name . $argsStr); - } - -} diff --git a/lib/Zend/Cache/Frontend/Output.php b/lib/Zend/Cache/Frontend/Output.php deleted file mode 100644 index fac6b4cdf09..00000000000 --- a/lib/Zend/Cache/Frontend/Output.php +++ /dev/null @@ -1,105 +0,0 @@ -_idStack = array(); - } - - /** - * Start the cache - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @param boolean $echoData If set to true, datas are sent to the browser if the cache is hit (simply returned else) - * @return mixed True if the cache is hit (false else) with $echoData=true (default) ; string else (datas) - */ - public function start($id, $doNotTestCacheValidity = false, $echoData = true) - { - $data = $this->load($id, $doNotTestCacheValidity); - if ($data !== false) { - if ( $echoData ) { - echo($data); - return true; - } else { - return $data; - } - } - ob_start(); - ob_implicit_flush(false); - $this->_idStack[] = $id; - return false; - } - - /** - * Stop the cache - * - * @param array $tags Tags array - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @param string $forcedDatas If not null, force written datas with this - * @param boolean $echoData If set to true, datas are sent to the browser - * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends - * @return void - */ - public function end($tags = array(), $specificLifetime = false, $forcedDatas = null, $echoData = true, $priority = 8) - { - if ($forcedDatas === null) { - $data = ob_get_clean(); - } else { - $data =& $forcedDatas; - } - $id = array_pop($this->_idStack); - if ($id === null) { - Zend_Cache::throwException('use of end() without a start()'); - } - $this->save($data, $id, $tags, $specificLifetime, $priority); - if ($echoData) { - echo($data); - } - } - -} diff --git a/lib/Zend/Cache/Frontend/Page.php b/lib/Zend/Cache/Frontend/Page.php deleted file mode 100644 index 032fe9ae133..00000000000 --- a/lib/Zend/Cache/Frontend/Page.php +++ /dev/null @@ -1,404 +0,0 @@ - (boolean) http_conditional : - * - if true, http conditional mode is on - * WARNING : http_conditional OPTION IS NOT IMPLEMENTED FOR THE MOMENT (TODO) - * - * ====> (boolean) debug_header : - * - if true, a debug text is added before each cached pages - * - * ====> (boolean) content_type_memorization : - * - deprecated => use memorize_headers instead - * - if the Content-Type header is sent after the cache was started, the - * corresponding value can be memorized and replayed when the cache is hit - * (if false (default), the frontend doesn't take care of Content-Type header) - * - * ====> (array) memorize_headers : - * - an array of strings corresponding to some HTTP headers name. Listed headers - * will be stored with cache datas and "replayed" when the cache is hit - * - * ====> (array) default_options : - * - an associative array of default options : - * - (boolean) cache : cache is on by default if true - * - (boolean) cacheWithXXXVariables (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') : - * if true, cache is still on even if there are some variables in this superglobal array - * if false, cache is off if there are some variables in this superglobal array - * - (boolean) makeIdWithXXXVariables (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') : - * if true, we have to use the content of this superglobal array to make a cache id - * if false, the cache id won't be dependent of the content of this superglobal array - * - (int) specific_lifetime : cache specific lifetime - * (false => global lifetime is used, null => infinite lifetime, - * integer => this lifetime is used), this "lifetime" is probably only - * usefull when used with "regexps" array - * - (array) tags : array of tags (strings) - * - (int) priority : integer between 0 (very low priority) and 10 (maximum priority) used by - * some particular backends - * - * ====> (array) regexps : - * - an associative array to set options only for some REQUEST_URI - * - keys are (pcre) regexps - * - values are associative array with specific options to set if the regexp matchs on $_SERVER['REQUEST_URI'] - * (see default_options for the list of available options) - * - if several regexps match the $_SERVER['REQUEST_URI'], only the last one will be used - * - * @var array options - */ - protected $_specificOptions = array( - 'http_conditional' => false, - 'debug_header' => false, - 'content_type_memorization' => false, - 'memorize_headers' => array(), - 'default_options' => array( - 'cache_with_get_variables' => false, - 'cache_with_post_variables' => false, - 'cache_with_session_variables' => false, - 'cache_with_files_variables' => false, - 'cache_with_cookie_variables' => false, - 'make_id_with_get_variables' => true, - 'make_id_with_post_variables' => true, - 'make_id_with_session_variables' => true, - 'make_id_with_files_variables' => true, - 'make_id_with_cookie_variables' => true, - 'cache' => true, - 'specific_lifetime' => false, - 'tags' => array(), - 'priority' => null - ), - 'regexps' => array() - ); - - /** - * Internal array to store some options - * - * @var array associative array of options - */ - protected $_activeOptions = array(); - - /** - * If true, the page won't be cached - * - * @var boolean - */ - protected $_cancel = false; - - /** - * Constructor - * - * @param array $options Associative array of options - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @throws Zend_Cache_Exception - * @return void - */ - public function __construct(array $options = array()) - { - foreach ($options as $name => $value) { - $name = strtolower($name); - switch ($name) { - case 'regexps': - $this->_setRegexps($value); - break; - case 'default_options': - $this->_setDefaultOptions($value); - break; - case 'content_type_memorization': - $this->_setContentTypeMemorization($value); - break; - default: - $this->setOption($name, $value); - } - } - if (isset($this->_specificOptions['http_conditional'])) { - if ($this->_specificOptions['http_conditional']) { - Zend_Cache::throwException('http_conditional is not implemented for the moment !'); - } - } - $this->setOption('automatic_serialization', true); - } - - /** - * Specific setter for the 'default_options' option (with some additional tests) - * - * @param array $options Associative array - * @throws Zend_Cache_Exception - * @return void - */ - protected function _setDefaultOptions($options) - { - if (!is_array($options)) { - Zend_Cache::throwException('default_options must be an array !'); - } - foreach ($options as $key=>$value) { - if (!is_string($key)) { - Zend_Cache::throwException("invalid option [$key] !"); - } - $key = strtolower($key); - if (isset($this->_specificOptions['default_options'][$key])) { - $this->_specificOptions['default_options'][$key] = $value; - } - } - } - - /** - * Set the deprecated contentTypeMemorization option - * - * @param boolean $value value - * @return void - * @deprecated - */ - protected function _setContentTypeMemorization($value) - { - $found = null; - foreach ($this->_specificOptions['memorize_headers'] as $key => $value) { - if (strtolower($value) == 'content-type') { - $found = $key; - } - } - if ($value) { - if (!$found) { - $this->_specificOptions['memorize_headers'][] = 'Content-Type'; - } - } else { - if ($found) { - unset($this->_specificOptions['memorize_headers'][$found]); - } - } - } - - /** - * Specific setter for the 'regexps' option (with some additional tests) - * - * @param array $options Associative array - * @throws Zend_Cache_Exception - * @return void - */ - protected function _setRegexps($regexps) - { - if (!is_array($regexps)) { - Zend_Cache::throwException('regexps option must be an array !'); - } - foreach ($regexps as $regexp=>$conf) { - if (!is_array($conf)) { - Zend_Cache::throwException('regexps option must be an array of arrays !'); - } - $validKeys = array_keys($this->_specificOptions['default_options']); - foreach ($conf as $key=>$value) { - if (!is_string($key)) { - Zend_Cache::throwException("unknown option [$key] !"); - } - $key = strtolower($key); - if (!in_array($key, $validKeys)) { - unset($regexps[$regexp][$key]); - } - } - } - $this->setOption('regexps', $regexps); - } - - /** - * Start the cache - * - * @param string $id (optional) A cache id (if you set a value here, maybe you have to use Output frontend instead) - * @param boolean $doNotDie For unit testing only ! - * @return boolean True if the cache is hit (false else) - */ - public function start($id = false, $doNotDie = false) - { - $this->_cancel = false; - $lastMatchingRegexp = null; - if (isset($_SERVER['REQUEST_URI'])) { - foreach ($this->_specificOptions['regexps'] as $regexp => $conf) { - if (preg_match("`$regexp`", $_SERVER['REQUEST_URI'])) { - $lastMatchingRegexp = $regexp; - } - } - } - $this->_activeOptions = $this->_specificOptions['default_options']; - if ($lastMatchingRegexp !== null) { - $conf = $this->_specificOptions['regexps'][$lastMatchingRegexp]; - foreach ($conf as $key=>$value) { - $this->_activeOptions[$key] = $value; - } - } - if (!($this->_activeOptions['cache'])) { - return false; - } - if (!$id) { - $id = $this->_makeId(); - if (!$id) { - return false; - } - } - $array = $this->load($id); - if ($array !== false) { - $data = $array['data']; - $headers = $array['headers']; - if (!headers_sent()) { - foreach ($headers as $key=>$headerCouple) { - $name = $headerCouple[0]; - $value = $headerCouple[1]; - header("$name: $value"); - } - } - if ($this->_specificOptions['debug_header']) { - echo 'DEBUG HEADER : This is a cached page !'; - } - echo $data; - if ($doNotDie) { - return true; - } - die(); - } - ob_start(array($this, '_flush')); - ob_implicit_flush(false); - return false; - } - - /** - * Cancel the current caching process - */ - public function cancel() - { - $this->_cancel = true; - } - - /** - * callback for output buffering - * (shouldn't really be called manually) - * - * @param string $data Buffered output - * @return string Data to send to browser - */ - public function _flush($data) - { - if ($this->_cancel) { - return $data; - } - $contentType = null; - $storedHeaders = array(); - $headersList = headers_list(); - foreach($this->_specificOptions['memorize_headers'] as $key=>$headerName) { - foreach ($headersList as $headerSent) { - $tmp = explode(':', $headerSent); - $headerSentName = trim(array_shift($tmp)); - if (strtolower($headerName) == strtolower($headerSentName)) { - $headerSentValue = trim(implode(':', $tmp)); - $storedHeaders[] = array($headerSentName, $headerSentValue); - } - } - } - $array = array( - 'data' => $data, - 'headers' => $storedHeaders - ); - $this->save($array, null, $this->_activeOptions['tags'], $this->_activeOptions['specific_lifetime'], $this->_activeOptions['priority']); - return $data; - } - - /** - * Make an id depending on REQUEST_URI and superglobal arrays (depending on options) - * - * @return mixed|false a cache id (string), false if the cache should have not to be used - */ - protected function _makeId() - { - $tmp = $_SERVER['REQUEST_URI']; - $array = explode('?', $tmp, 2); - $tmp = $array[0]; - foreach (array('Get', 'Post', 'Session', 'Files', 'Cookie') as $arrayName) { - $tmp2 = $this->_makePartialId($arrayName, $this->_activeOptions['cache_with_' . strtolower($arrayName) . '_variables'], $this->_activeOptions['make_id_with_' . strtolower($arrayName) . '_variables']); - if ($tmp2===false) { - return false; - } - $tmp = $tmp . $tmp2; - } - return md5($tmp); - } - - /** - * Make a partial id depending on options - * - * @param string $arrayName Superglobal array name - * @param bool $bool1 If true, cache is still on even if there are some variables in the superglobal array - * @param bool $bool2 If true, we have to use the content of the superglobal array to make a partial id - * @return mixed|false Partial id (string) or false if the cache should have not to be used - */ - protected function _makePartialId($arrayName, $bool1, $bool2) - { - switch ($arrayName) { - case 'Get': - $var = $_GET; - break; - case 'Post': - $var = $_POST; - break; - case 'Session': - if (isset($_SESSION)) { - $var = $_SESSION; - } else { - $var = null; - } - break; - case 'Cookie': - if (isset($_COOKIE)) { - $var = $_COOKIE; - } else { - $var = null; - } - break; - case 'Files': - $var = $_FILES; - break; - default: - return false; - } - if ($bool1) { - if ($bool2) { - return serialize($var); - } - return ''; - } - if (count($var) > 0) { - return false; - } - return ''; - } - -} diff --git a/lib/Zend/Cache/Manager.php b/lib/Zend/Cache/Manager.php deleted file mode 100644 index d9eb1d5ed8c..00000000000 --- a/lib/Zend/Cache/Manager.php +++ /dev/null @@ -1,308 +0,0 @@ - array( - 'frontend' => array( - 'name' => 'Core', - 'options' => array( - 'automatic_serialization' => true, - ), - ), - 'backend' => array( - 'name' => 'File', - 'options' => array( - // use system temp dir by default of file backend - // 'cache_dir' => '../cache', - ), - ), - ), - - // Static Page HTML Cache - 'page' => array( - 'frontend' => array( - 'name' => 'Capture', - 'options' => array( - 'ignore_user_abort' => true, - ), - ), - 'backend' => array( - 'name' => 'Static', - 'options' => array( - 'public_dir' => '../public', - ), - ), - ), - - // Tag Cache - 'pagetag' => array( - 'frontend' => array( - 'name' => 'Core', - 'options' => array( - 'automatic_serialization' => true, - 'lifetime' => null - ), - ), - 'backend' => array( - 'name' => 'File', - 'options' => array( - // use system temp dir by default of file backend - // 'cache_dir' => '../cache', - // use default umask of file backend - // 'cache_file_umask' => 0644 - ), - ), - ), - ); - - /** - * Set a new cache for the Cache Manager to contain - * - * @param string $name - * @param Zend_Cache_Core $cache - * @return Zend_Cache_Manager - */ - public function setCache($name, Zend_Cache_Core $cache) - { - $this->_caches[$name] = $cache; - return $this; - } - - /** - * Check if the Cache Manager contains the named cache object, or a named - * configuration template to lazy load the cache object - * - * @param string $name - * @return bool - */ - public function hasCache($name) - { - if (isset($this->_caches[$name]) - || $this->hasCacheTemplate($name) - ) { - return true; - } - return false; - } - - /** - * Fetch the named cache object, or instantiate and return a cache object - * using a named configuration template - * - * @param string $name - * @return Zend_Cache_Core - */ - public function getCache($name) - { - if (isset($this->_caches[$name])) { - return $this->_caches[$name]; - } - if (isset($this->_optionTemplates[$name])) { - if ($name == self::PAGECACHE - && (!isset($this->_optionTemplates[$name]['backend']['options']['tag_cache']) - || !$this->_optionTemplates[$name]['backend']['options']['tag_cache'] instanceof Zend_Cache_Core) - ) { - $this->_optionTemplates[$name]['backend']['options']['tag_cache'] - = $this->getCache(self::PAGETAGCACHE); - } - - $this->_caches[$name] = Zend_Cache::factory( - $this->_optionTemplates[$name]['frontend']['name'], - $this->_optionTemplates[$name]['backend']['name'], - isset($this->_optionTemplates[$name]['frontend']['options']) ? $this->_optionTemplates[$name]['frontend']['options'] : array(), - isset($this->_optionTemplates[$name]['backend']['options']) ? $this->_optionTemplates[$name]['backend']['options'] : array(), - isset($this->_optionTemplates[$name]['frontend']['customFrontendNaming']) ? $this->_optionTemplates[$name]['frontend']['customFrontendNaming'] : false, - isset($this->_optionTemplates[$name]['backend']['customBackendNaming']) ? $this->_optionTemplates[$name]['backend']['customBackendNaming'] : false, - isset($this->_optionTemplates[$name]['frontendBackendAutoload']) ? $this->_optionTemplates[$name]['frontendBackendAutoload'] : false - ); - - return $this->_caches[$name]; - } - } - - /** - * Fetch all available caches - * - * @return array An array of all available caches with it's names as key - */ - public function getCaches() - { - $caches = $this->_caches; - foreach ($this->_optionTemplates as $name => $tmp) { - if (!isset($caches[$name])) { - $caches[$name] = $this->getCache($name); - } - } - return $caches; - } - - /** - * Set a named configuration template from which a cache object can later - * be lazy loaded - * - * @param string $name - * @param array $options - * @return Zend_Cache_Manager - * @throws Zend_Cache_Exception - */ - public function setCacheTemplate($name, $options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (!is_array($options)) { - #require_once 'Zend/Cache/Exception.php'; - throw new Zend_Cache_Exception('Options passed must be in' - . ' an associative array or instance of Zend_Config'); - } - $this->_optionTemplates[$name] = $options; - return $this; - } - - /** - * Check if the named configuration template - * - * @param string $name - * @return bool - */ - public function hasCacheTemplate($name) - { - if (isset($this->_optionTemplates[$name])) { - return true; - } - return false; - } - - /** - * Get the named configuration template - * - * @param string $name - * @return array - */ - public function getCacheTemplate($name) - { - if (isset($this->_optionTemplates[$name])) { - return $this->_optionTemplates[$name]; - } - } - - /** - * Pass an array containing changes to be applied to a named - * configuration - * template - * - * @param string $name - * @param array $options - * @return Zend_Cache_Manager - * @throws Zend_Cache_Exception for invalid options format or if option templates do not have $name - */ - public function setTemplateOptions($name, $options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (!is_array($options)) { - #require_once 'Zend/Cache/Exception.php'; - throw new Zend_Cache_Exception('Options passed must be in' - . ' an associative array or instance of Zend_Config'); - } - if (!isset($this->_optionTemplates[$name])) { - throw new Zend_Cache_Exception('A cache configuration template' - . 'does not exist with the name "' . $name . '"'); - } - $this->_optionTemplates[$name] - = $this->_mergeOptions($this->_optionTemplates[$name], $options); - return $this; - } - - /** - * Simple method to merge two configuration arrays - * - * @param array $current - * @param array $options - * @return array - */ - protected function _mergeOptions(array $current, array $options) - { - if (isset($options['frontend']['name'])) { - $current['frontend']['name'] = $options['frontend']['name']; - } - if (isset($options['backend']['name'])) { - $current['backend']['name'] = $options['backend']['name']; - } - if (isset($options['frontend']['options'])) { - foreach ($options['frontend']['options'] as $key => $value) { - $current['frontend']['options'][$key] = $value; - } - } - if (isset($options['backend']['options'])) { - foreach ($options['backend']['options'] as $key => $value) { - $current['backend']['options'][$key] = $value; - } - } - if (isset($options['frontend']['customFrontendNaming'])) { - $current['frontend']['customFrontendNaming'] = $options['frontend']['customFrontendNaming']; - } - if (isset($options['backend']['customBackendNaming'])) { - $current['backend']['customBackendNaming'] = $options['backend']['customBackendNaming']; - } - if (isset($options['frontendBackendAutoload'])) { - $current['frontendBackendAutoload'] = $options['frontendBackendAutoload']; - } - return $current; - } -} diff --git a/lib/Zend/Captcha/Adapter.php b/lib/Zend/Captcha/Adapter.php deleted file mode 100644 index 70835f9fde1..00000000000 --- a/lib/Zend/Captcha/Adapter.php +++ /dev/null @@ -1,76 +0,0 @@ -_name; - } - - /** - * Set name - * - * @param string $name - * @return Zend_Captcha_Adapter - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * Constructor - * - * @param array|Zend_Config $options - */ - public function __construct($options = null) - { - // Set options - if (is_array($options)) { - $this->setOptions($options); - } else if ($options instanceof Zend_Config) { - $this->setConfig($options); - } - } - - /** - * Set single option for the object - * - * @param string $key - * @param string $value - * @return Zend_Form_Element - */ - public function setOption($key, $value) - { - if (in_array(strtolower($key), $this->_skipOptions)) { - return $this; - } - - $method = 'set' . ucfirst ($key); - if (method_exists ($this, $method)) { - // Setter exists; use it - $this->$method ($value); - $this->_options[$key] = $value; - } elseif (property_exists($this, $key)) { - // Assume it's metadata - $this->$key = $value; - $this->_options[$key] = $value; - } - return $this; - } - - /** - * Set object state from options array - * - * @param array $options - * @return Zend_Form_Element - */ - public function setOptions($options = null) - { - foreach ($options as $key => $value) { - $this->setOption($key, $value); - } - return $this; - } - - /** - * Retrieve options representing object state - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Set object state from config object - * - * @param Zend_Config $config - * @return Zend_Captcha_Base - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Get optional decorator - * - * By default, return null, indicating no extra decorator needed. - * - * @return null - */ - public function getDecorator() - { - return null; - } -} diff --git a/lib/Zend/Captcha/Dumb.php b/lib/Zend/Captcha/Dumb.php deleted file mode 100644 index 803f15e3d5d..00000000000 --- a/lib/Zend/Captcha/Dumb.php +++ /dev/null @@ -1,75 +0,0 @@ -_label = $label; - } - - /** - * Retrieve the label for the CAPTCHA - * @return string - */ - public function getLabel() - { - return $this->_label; - } - /** - * Render the captcha - * - * @param Zend_View_Interface $view - * @param mixed $element - * @return string - */ - public function render(Zend_View_Interface $view = null, $element = null) - { - return $this->getLabel() . ': ' - . strrev($this->getWord()) - . ''; - } -} diff --git a/lib/Zend/Captcha/Exception.php b/lib/Zend/Captcha/Exception.php deleted file mode 100644 index 71d75558834..00000000000 --- a/lib/Zend/Captcha/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_figlet = new Zend_Text_Figlet($options); - } - - /** - * Generate new captcha - * - * @return string - */ - public function generate() - { - $this->_useNumbers = false; - return parent::generate(); - } - - /** - * Display the captcha - * - * @param Zend_View_Interface $view - * @param mixed $element - * @return string - */ - public function render(Zend_View_Interface $view = null, $element = null) - { - return '
'
-             . $this->_figlet->render($this->getWord())
-             . "
\n"; - } -} diff --git a/lib/Zend/Captcha/Image.php b/lib/Zend/Captcha/Image.php deleted file mode 100644 index 542d56926b0..00000000000 --- a/lib/Zend/Captcha/Image.php +++ /dev/null @@ -1,625 +0,0 @@ -_imgAlt; - } - /** - * @return string - */ - public function getStartImage () - { - return $this->_startImage; - } - /** - * @return int - */ - public function getDotNoiseLevel () - { - return $this->_dotNoiseLevel; - } - /** - * @return int - */ - public function getLineNoiseLevel () - { - return $this->_lineNoiseLevel; - } - /** - * Get captcha expiration - * - * @return int - */ - public function getExpiration() - { - return $this->_expiration; - } - - /** - * Get garbage collection frequency - * - * @return int - */ - public function getGcFreq() - { - return $this->_gcFreq; - } - /** - * Get font to use when generating captcha - * - * @return string - */ - public function getFont() - { - return $this->_font; - } - - /** - * Get font size - * - * @return int - */ - public function getFontSize() - { - return $this->_fsize; - } - - /** - * Get captcha image height - * - * @return int - */ - public function getHeight() - { - return $this->_height; - } - - /** - * Get captcha image directory - * - * @return string - */ - public function getImgDir() - { - return $this->_imgDir; - } - /** - * Get captcha image base URL - * - * @return string - */ - public function getImgUrl() - { - return $this->_imgUrl; - } - /** - * Get captcha image file suffix - * - * @return string - */ - public function getSuffix() - { - return $this->_suffix; - } - /** - * Get captcha image width - * - * @return int - */ - public function getWidth() - { - return $this->_width; - } - - /** - * Set start image - * - * @param string $startImage - * @return Zend_Captcha_Image - */ - public function setStartImage ($startImage) - { - $this->_startImage = $startImage; - return $this; - } - - /** - * Set dot noise level - * - * @param int $dotNoiseLevel - * @return Zend_Captcha_Image - */ - public function setDotNoiseLevel ($dotNoiseLevel) - { - $this->_dotNoiseLevel = $dotNoiseLevel; - return $this; - } - - /** - * Set line noise level - * - * @param int $lineNoiseLevel - * @return Zend_Captcha_Image - */ - public function setLineNoiseLevel ($lineNoiseLevel) - { - $this->_lineNoiseLevel = $lineNoiseLevel; - return $this; - } - - /** - * Set captcha expiration - * - * @param int $expiration - * @return Zend_Captcha_Image - */ - public function setExpiration($expiration) - { - $this->_expiration = $expiration; - return $this; - } - - /** - * Set garbage collection frequency - * - * @param int $gcFreq - * @return Zend_Captcha_Image - */ - public function setGcFreq($gcFreq) - { - $this->_gcFreq = $gcFreq; - return $this; - } - - /** - * Set captcha font - * - * @param string $font - * @return Zend_Captcha_Image - */ - public function setFont($font) - { - $this->_font = $font; - return $this; - } - - /** - * Set captcha font size - * - * @param int $fsize - * @return Zend_Captcha_Image - */ - public function setFontSize($fsize) - { - $this->_fsize = $fsize; - return $this; - } - - /** - * Set captcha image height - * - * @param int $height - * @return Zend_Captcha_Image - */ - public function setHeight($height) - { - $this->_height = $height; - return $this; - } - - /** - * Set captcha image storage directory - * - * @param string $imgDir - * @return Zend_Captcha_Image - */ - public function setImgDir($imgDir) - { - $this->_imgDir = rtrim($imgDir, "/\\") . '/'; - return $this; - } - - /** - * Set captcha image base URL - * - * @param string $imgUrl - * @return Zend_Captcha_Image - */ - public function setImgUrl($imgUrl) - { - $this->_imgUrl = rtrim($imgUrl, "/\\") . '/'; - return $this; - } - - /** - * Set image alternative text - * - * @param string $imgAlt - * @return Zend_Captcha_Image - */ - public function setImgAlt ($imgAlt) - { - $this->_imgAlt = $imgAlt; - return $this; - } - - /** - * Set captch image filename suffix - * - * @param string $suffix - * @return Zend_Captcha_Image - */ - public function setSuffix($suffix) - { - $this->_suffix = $suffix; - return $this; - } - - /** - * Set captcha image width - * - * @param int $width - * @return Zend_Captcha_Image - */ - public function setWidth($width) - { - $this->_width = $width; - return $this; - } - - /** - * Generate random frequency - * - * @return float - */ - protected function _randomFreq() - { - return mt_rand(700000, 1000000) / 15000000; - } - - /** - * Generate random phase - * - * @return float - */ - protected function _randomPhase() - { - // random phase from 0 to pi - return mt_rand(0, 3141592) / 1000000; - } - - /** - * Generate random character size - * - * @return int - */ - protected function _randomSize() - { - return mt_rand(300, 700) / 100; - } - - /** - * Generate captcha - * - * @return string captcha ID - */ - public function generate() - { - $id = parent::generate(); - $tries = 5; - // If there's already such file, try creating a new ID - while($tries-- && file_exists($this->getImgDir() . $id . $this->getSuffix())) { - $id = $this->_generateRandomId(); - $this->_setId($id); - } - $this->_generateImage($id, $this->getWord()); - - if (mt_rand(1, $this->getGcFreq()) == 1) { - $this->_gc(); - } - return $id; - } - - /** - * Generate image captcha - * - * Override this function if you want different image generator - * Wave transform from http://www.captcha.ru/captchas/multiwave/ - * - * @param string $id Captcha ID - * @param string $word Captcha word - * @throws Zend_Captcha_Exception - */ - protected function _generateImage($id, $word) - { - if (!extension_loaded("gd")) { - #require_once 'Zend/Captcha/Exception.php'; - throw new Zend_Captcha_Exception("Image CAPTCHA requires GD extension"); - } - - if (!function_exists("imagepng")) { - #require_once 'Zend/Captcha/Exception.php'; - throw new Zend_Captcha_Exception("Image CAPTCHA requires PNG support"); - } - - if (!function_exists("imageftbbox")) { - #require_once 'Zend/Captcha/Exception.php'; - throw new Zend_Captcha_Exception("Image CAPTCHA requires FT fonts support"); - } - - $font = $this->getFont(); - - if (empty($font)) { - #require_once 'Zend/Captcha/Exception.php'; - throw new Zend_Captcha_Exception("Image CAPTCHA requires font"); - } - - $w = $this->getWidth(); - $h = $this->getHeight(); - $fsize = $this->getFontSize(); - - $img_file = $this->getImgDir() . $id . $this->getSuffix(); - if(empty($this->_startImage)) { - $img = imagecreatetruecolor($w, $h); - } else { - $img = imagecreatefrompng($this->_startImage); - if(!$img) { - #require_once 'Zend/Captcha/Exception.php'; - throw new Zend_Captcha_Exception("Can not load start image"); - } - $w = imagesx($img); - $h = imagesy($img); - } - $text_color = imagecolorallocate($img, 0, 0, 0); - $bg_color = imagecolorallocate($img, 255, 255, 255); - imagefilledrectangle($img, 0, 0, $w-1, $h-1, $bg_color); - $textbox = imageftbbox($fsize, 0, $font, $word); - $x = ($w - ($textbox[2] - $textbox[0])) / 2; - $y = ($h - ($textbox[7] - $textbox[1])) / 2; - imagefttext($img, $fsize, 0, $x, $y, $text_color, $font, $word); - - // generate noise - for ($i=0; $i<$this->_dotNoiseLevel; $i++) { - imagefilledellipse($img, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color); - } - for($i=0; $i<$this->_lineNoiseLevel; $i++) { - imageline($img, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color); - } - - // transformed image - $img2 = imagecreatetruecolor($w, $h); - $bg_color = imagecolorallocate($img2, 255, 255, 255); - imagefilledrectangle($img2, 0, 0, $w-1, $h-1, $bg_color); - // apply wave transforms - $freq1 = $this->_randomFreq(); - $freq2 = $this->_randomFreq(); - $freq3 = $this->_randomFreq(); - $freq4 = $this->_randomFreq(); - - $ph1 = $this->_randomPhase(); - $ph2 = $this->_randomPhase(); - $ph3 = $this->_randomPhase(); - $ph4 = $this->_randomPhase(); - - $szx = $this->_randomSize(); - $szy = $this->_randomSize(); - - for ($x = 0; $x < $w; $x++) { - for ($y = 0; $y < $h; $y++) { - $sx = $x + (sin($x*$freq1 + $ph1) + sin($y*$freq3 + $ph3)) * $szx; - $sy = $y + (sin($x*$freq2 + $ph2) + sin($y*$freq4 + $ph4)) * $szy; - - if ($sx < 0 || $sy < 0 || $sx >= $w - 1 || $sy >= $h - 1) { - continue; - } else { - $color = (imagecolorat($img, $sx, $sy) >> 16) & 0xFF; - $color_x = (imagecolorat($img, $sx + 1, $sy) >> 16) & 0xFF; - $color_y = (imagecolorat($img, $sx, $sy + 1) >> 16) & 0xFF; - $color_xy = (imagecolorat($img, $sx + 1, $sy + 1) >> 16) & 0xFF; - } - if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) { - // ignore background - continue; - } elseif ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) { - // transfer inside of the image as-is - $newcolor = 0; - } else { - // do antialiasing for border items - $frac_x = $sx-floor($sx); - $frac_y = $sy-floor($sy); - $frac_x1 = 1-$frac_x; - $frac_y1 = 1-$frac_y; - - $newcolor = $color * $frac_x1 * $frac_y1 - + $color_x * $frac_x * $frac_y1 - + $color_y * $frac_x1 * $frac_y - + $color_xy * $frac_x * $frac_y; - } - imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newcolor, $newcolor, $newcolor)); - } - } - - // generate noise - for ($i=0; $i<$this->_dotNoiseLevel; $i++) { - imagefilledellipse($img2, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color); - } - for ($i=0; $i<$this->_lineNoiseLevel; $i++) { - imageline($img2, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color); - } - - imagepng($img2, $img_file); - imagedestroy($img); - imagedestroy($img2); - } - - /** - * Remove old files from image directory - */ - protected function _gc() - { - $expire = time() - $this->getExpiration(); - $imgdir = $this->getImgDir(); - if(!$imgdir || strlen($imgdir) < 2) { - // safety guard - return; - } - $suffixLength = strlen($this->_suffix); - foreach (new DirectoryIterator($imgdir) as $file) { - if (!$file->isDot() && !$file->isDir()) { - if (file_exists($file->getPathname()) && $file->getMTime() < $expire) { - // only deletes files ending with $this->_suffix - if (substr($file->getFilename(), -($suffixLength)) == $this->_suffix) { - unlink($file->getPathname()); - } - } - } - } - } - - /** - * Display the captcha - * - * @param Zend_View_Interface $view - * @param mixed $element - * @return string - */ - public function render(Zend_View_Interface $view = null, $element = null) - { - $endTag = ' />'; - if (($view instanceof Zend_View_Abstract) && !$view->doctype()->isXhtml()) { - $endTag = '>'; - } - return '' . $this->getImgAlt()
-             . ' 'Missing captcha fields', - self::ERR_CAPTCHA => 'Failed to validate captcha', - self::BAD_CAPTCHA => 'Captcha value is wrong: %value%', - ); - - /** - * Retrieve ReCaptcha Private key - * - * @return string - */ - public function getPrivkey() - { - return $this->getService()->getPrivateKey(); - } - - /** - * Retrieve ReCaptcha Public key - * - * @return string - */ - public function getPubkey() - { - return $this->getService()->getPublicKey(); - } - - /** - * Set ReCaptcha Private key - * - * @param string $privkey - * @return Zend_Captcha_ReCaptcha - */ - public function setPrivkey($privkey) - { - $this->getService()->setPrivateKey($privkey); - return $this; - } - - /** - * Set ReCaptcha public key - * - * @param string $pubkey - * @return Zend_Captcha_ReCaptcha - */ - public function setPubkey($pubkey) - { - $this->getService()->setPublicKey($pubkey); - return $this; - } - - /** - * Constructor - * - * @param array|Zend_Config $options - */ - public function __construct($options = null) - { - $this->setService(new Zend_Service_ReCaptcha()); - $this->_serviceParams = $this->getService()->getParams(); - $this->_serviceOptions = $this->getService()->getOptions(); - - parent::__construct($options); - - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - if (!empty($options)) { - $this->setOptions($options); - } - } - - /** - * Set service object - * - * @param Zend_Service_ReCaptcha $service - * @return Zend_Captcha_ReCaptcha - */ - public function setService(Zend_Service_ReCaptcha $service) - { - $this->_service = $service; - return $this; - } - - /** - * Retrieve ReCaptcha service object - * - * @return Zend_Service_ReCaptcha - */ - public function getService() - { - return $this->_service; - } - - /** - * Set option - * - * If option is a service parameter, proxies to the service. The same - * goes for any service options (distinct from service params) - * - * @param string $key - * @param mixed $value - * @return Zend_Captcha_ReCaptcha - */ - public function setOption($key, $value) - { - $service = $this->getService(); - if (isset($this->_serviceParams[$key])) { - $service->setParam($key, $value); - return $this; - } - if (isset($this->_serviceOptions[$key])) { - $service->setOption($key, $value); - return $this; - } - return parent::setOption($key, $value); - } - - /** - * Generate captcha - * - * @see Zend_Form_Captcha_Adapter::generate() - * @return string - */ - public function generate() - { - return ""; - } - - /** - * Validate captcha - * - * @see Zend_Validate_Interface::isValid() - * @param mixed $value - * @param array|null $context - * @return boolean - */ - public function isValid($value, $context = null) - { - if (!is_array($value) && !is_array($context)) { - $this->_error(self::MISSING_VALUE); - return false; - } - - if (!is_array($value) && is_array($context)) { - $value = $context; - } - - if (empty($value[$this->_CHALLENGE]) || empty($value[$this->_RESPONSE])) { - $this->_error(self::MISSING_VALUE); - return false; - } - - $service = $this->getService(); - - $res = $service->verify($value[$this->_CHALLENGE], $value[$this->_RESPONSE]); - - if (!$res) { - $this->_error(self::ERR_CAPTCHA); - return false; - } - - if (!$res->isValid()) { - $this->_error(self::BAD_CAPTCHA, $res->getErrorCode()); - $service->setParam('error', $res->getErrorCode()); - return false; - } - - return true; - } - - /** - * Render captcha - * - * @param Zend_View_Interface $view - * @param mixed $element - * @return string - */ - public function render(Zend_View_Interface $view = null, $element = null) - { - $name = null; - if ($element instanceof Zend_Form_Element) { - $name = $element->getBelongsTo(); - } - return $this->getService()->getHTML($name); - } - - /** - * Get captcha decorator - * - * @return string - */ - public function getDecorator() - { - return "Captcha_ReCaptcha"; - } -} diff --git a/lib/Zend/Captcha/Word.php b/lib/Zend/Captcha/Word.php deleted file mode 100644 index 617bae19ff8..00000000000 --- a/lib/Zend/Captcha/Word.php +++ /dev/null @@ -1,419 +0,0 @@ - 'Empty captcha value', - self::MISSING_ID => 'Captcha ID field is missing', - self::BAD_CAPTCHA => 'Captcha value is wrong', - ); - - /** - * Length of the word to generate - * - * @var integer - */ - protected $_wordlen = 8; - - /** - * Retrieve session class to utilize - * - * @return string - */ - public function getSessionClass() - { - return $this->_sessionClass; - } - - /** - * Set session class for persistence - * - * @param string $_sessionClass - * @return Zend_Captcha_Word - */ - public function setSessionClass($_sessionClass) - { - $this->_sessionClass = $_sessionClass; - return $this; - } - - /** - * Retrieve word length to use when genrating captcha - * - * @return integer - */ - public function getWordlen() - { - return $this->_wordlen; - } - - /** - * Set word length of captcha - * - * @param integer $wordlen - * @return Zend_Captcha_Word - */ - public function setWordlen($wordlen) - { - $this->_wordlen = $wordlen; - return $this; - } - - /** - * Retrieve captcha ID - * - * @return string - */ - public function getId () - { - if (null === $this->_id) { - $this->_setId($this->_generateRandomId()); - } - return $this->_id; - } - - /** - * Set captcha identifier - * - * @param string $id - * @return Zend_Captcha_Word - */ - protected function _setId ($id) - { - $this->_id = $id; - return $this; - } - - /** - * Set timeout for session token - * - * @param int $ttl - * @return Zend_Captcha_Word - */ - public function setTimeout($ttl) - { - $this->_timeout = (int) $ttl; - return $this; - } - - /** - * Get session token timeout - * - * @return int - */ - public function getTimeout() - { - return $this->_timeout; - } - - /** - * Sets if session should be preserved on generate() - * - * @param bool $keepSession Should session be kept on generate()? - * @return Zend_Captcha_Word - */ - public function setKeepSession($keepSession) - { - $this->_keepSession = $keepSession; - return $this; - } - - /** - * Numbers should be included in the pattern? - * - * @return bool - */ - public function getUseNumbers() - { - return $this->_useNumbers; - } - - /** - * Set if numbers should be included in the pattern - * - * @param bool $_useNumbers numbers should be included in the pattern? - * @return Zend_Captcha_Word - */ - public function setUseNumbers($_useNumbers) - { - $this->_useNumbers = $_useNumbers; - return $this; - } - - /** - * Get session object - * - * @return Zend_Session_Namespace - */ - public function getSession() - { - if (!isset($this->_session) || (null === $this->_session)) { - $id = $this->getId(); - if (!class_exists($this->_sessionClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($this->_sessionClass); - } - $this->_session = new $this->_sessionClass('Zend_Form_Captcha_' . $id); - $this->_session->setExpirationHops(1, null, true); - $this->_session->setExpirationSeconds($this->getTimeout()); - } - return $this->_session; - } - - /** - * Set session namespace object - * - * @param Zend_Session_Namespace $session - * @return Zend_Captcha_Word - */ - public function setSession(Zend_Session_Namespace $session) - { - $this->_session = $session; - if($session) { - $this->_keepSession = true; - } - return $this; - } - - /** - * Get captcha word - * - * @return string - */ - public function getWord() - { - if (empty($this->_word)) { - $session = $this->getSession(); - $this->_word = $session->word; - } - return $this->_word; - } - - /** - * Set captcha word - * - * @param string $word - * @return Zend_Captcha_Word - */ - protected function _setWord($word) - { - $session = $this->getSession(); - $session->word = $word; - $this->_word = $word; - return $this; - } - - /** - * Generate new random word - * - * @return string - */ - protected function _generateWord() - { - $word = ''; - $wordLen = $this->getWordLen(); - $vowels = $this->_useNumbers ? self::$VN : self::$V; - $consonants = $this->_useNumbers ? self::$CN : self::$C; - - for ($i=0; $i < $wordLen; $i = $i + 2) { - // generate word with mix of vowels and consonants - $consonant = $consonants[array_rand($consonants)]; - $vowel = $vowels[array_rand($vowels)]; - $word .= $consonant . $vowel; - } - - if (strlen($word) > $wordLen) { - $word = substr($word, 0, $wordLen); - } - - return $word; - } - - /** - * Generate new session ID and new word - * - * @return string session ID - */ - public function generate() - { - if(!$this->_keepSession) { - $this->_session = null; - } - $id = $this->_generateRandomId(); - $this->_setId($id); - $word = $this->_generateWord(); - $this->_setWord($word); - return $id; - } - - protected function _generateRandomId() - { - return md5(mt_rand(0, 1000) . microtime(true)); - } - - /** - * Validate the word - * - * @see Zend_Validate_Interface::isValid() - * @param mixed $value - * @param array|null $context - * @return boolean - */ - public function isValid($value, $context = null) - { - if (!is_array($value) && !is_array($context)) { - $this->_error(self::MISSING_VALUE); - return false; - } - if (!is_array($value) && is_array($context)) { - $value = $context; - } - - $name = $this->getName(); - - if (isset($value[$name])) { - $value = $value[$name]; - } - - if (!isset($value['input'])) { - $this->_error(self::MISSING_VALUE); - return false; - } - $input = strtolower($value['input']); - $this->_setValue($input); - - if (!isset($value['id'])) { - $this->_error(self::MISSING_ID); - return false; - } - - $this->_id = $value['id']; - if ($input !== $this->getWord()) { - $this->_error(self::BAD_CAPTCHA); - return false; - } - - return true; - } - - /** - * Get captcha decorator - * - * @return string - */ - public function getDecorator() - { - return "Captcha_Word"; - } -} diff --git a/lib/Zend/Cloud/AbstractFactory.php b/lib/Zend/Cloud/AbstractFactory.php deleted file mode 100644 index 98d6cffc058..00000000000 --- a/lib/Zend/Cloud/AbstractFactory.php +++ /dev/null @@ -1,67 +0,0 @@ -toArray(); - } - - if (!isset($options[$adapterOption])) { - return null; - } - - $classname = $options[$adapterOption]; - unset($options[$adapterOption]); - if (!class_exists($classname)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($classname); - } - - return new $classname($options); - } -} diff --git a/lib/Zend/Cloud/DocumentService/Adapter.php b/lib/Zend/Cloud/DocumentService/Adapter.php deleted file mode 100644 index a60767fa449..00000000000 --- a/lib/Zend/Cloud/DocumentService/Adapter.php +++ /dev/null @@ -1,155 +0,0 @@ -_documentClass = (string) $class; - return $this; - } - - /** - * Get the class for document objects - * - * @return string - */ - public function getDocumentClass() - { - return $this->_documentClass; - } - - /** - * Set the class for document set objects - * - * @param string $class - * @return Zend_Cloud_DocumentService_Adapter_AbstractAdapter - */ - public function setDocumentSetClass($class) - { - $this->_documentSetClass = (string) $class; - return $this; - } - - /** - * Get the class for document set objects - * - * @return string - */ - public function getDocumentSetClass() - { - return $this->_documentSetClass; - } - - /** - * Set the query class for query objects - * - * @param string $class - * @return Zend_Cloud_DocumentService_Adapter_AbstractAdapter - */ - public function setQueryClass($class) - { - $this->_queryClass = (string) $class; - return $this; - } - - /** - * Get the class for query objects - * - * @return string - */ - public function getQueryClass() - { - return $this->_queryClass; - } -} diff --git a/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb.php b/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb.php deleted file mode 100644 index 35a61d75248..00000000000 --- a/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb.php +++ /dev/null @@ -1,468 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid options provided to constructor'); - } - - $this->_simpleDb = new Zend_Service_Amazon_SimpleDb( - $options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY] - ); - - if (isset($options[self::HTTP_ADAPTER])) { - $this->_simpleDb->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - - if (isset($options[self::DOCUMENT_CLASS])) { - $this->setDocumentClass($options[self::DOCUMENT_CLASS]); - } - - if (isset($options[self::DOCUMENTSET_CLASS])) { - $this->setDocumentSetClass($options[self::DOCUMENTSET_CLASS]); - } - - if (isset($options[self::QUERY_CLASS])) { - $this->setQueryClass($options[self::QUERY_CLASS]); - } - } - - /** - * Create collection. - * - * @param string $name - * @param array $options - * @return void - */ - public function createCollection($name, $options = null) - { - try { - $this->_simpleDb->createDomain($name); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on domain creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete collection. - * - * @param string $name - * @param array $options - * @return void - */ - public function deleteCollection($name, $options = null) - { - try { - $this->_simpleDb->deleteDomain($name); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on collection deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * List collections. - * - * @param array $options - * @return array - */ - public function listCollections($options = null) - { - try { - // TODO package this in Pages - $domains = $this->_simpleDb->listDomains()->getData(); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on collection deletion: '.$e->getMessage(), $e->getCode(), $e); - } - - return $domains; - } - - /** - * List documents - * - * Returns a key/value array of document names to document objects. - * - * @param string $collectionName Name of collection for which to list documents - * @param array|null $options - * @return Zend_Cloud_DocumentService_DocumentSet - */ - public function listDocuments($collectionName, array $options = null) - { - $query = $this->select('*')->from($collectionName); - $items = $this->query($collectionName, $query, $options); - return $items; - } - - /** - * Insert document - * - * @param string $collectionName Collection into which to insert document - * @param array|Zend_Cloud_DocumentService_Document $document - * @param array $options - * @return void - */ - public function insertDocument($collectionName, $document, $options = null) - { - if (is_array($document)) { - $document = $this->_getDocumentFromArray($document); - } - - if (!$document instanceof Zend_Cloud_DocumentService_Document) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); - } - - try { - $this->_simpleDb->putAttributes( - $collectionName, - $document->getID(), - $this->_makeAttributes($document->getID(), $document->getFields()) - ); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document insertion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Replace an existing document with a new version - * - * @param string $collectionName - * @param array|Zend_Cloud_DocumentService_Document $document - * @param array $options - * @return void - */ - public function replaceDocument($collectionName, $document, $options = null) - { - if (is_array($document)) { - $document = $this->_getDocumentFromArray($document); - } - - if (!$document instanceof Zend_Cloud_DocumentService_Document) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); - } - - // Delete document first, then insert. PutAttributes always keeps any - // fields not referenced in the payload, but present in the document - $documentId = $document->getId(); - $fields = $document->getFields(); - $docClass = get_class($document); - $this->deleteDocument($collectionName, $document, $options); - - $document = new $docClass($fields, $documentId); - $this->insertDocument($collectionName, $document); - } - - /** - * Update document. The new document replaces the existing document. - * - * Option 'merge' specifies to add all attributes (if true) or - * specific attributes ("attr" => true) instead of replacing them. - * By default, attributes are replaced. - * - * @param string $collectionName - * @param mixed|Zend_Cloud_DocumentService_Document $documentId Document ID, adapter-dependent - * @param array|Zend_Cloud_DocumentService_Document $fieldset Set of fields to update - * @param array $options - * @return boolean - */ - public function updateDocument($collectionName, $documentId, $fieldset = null, $options = null) - { - if (null === $fieldset && $documentId instanceof Zend_Cloud_DocumentService_Document) { - $fieldset = $documentId->getFields(); - if (empty($documentId)) { - $documentId = $documentId->getId(); - } - } elseif ($fieldset instanceof Zend_Cloud_DocumentService_Document) { - if (empty($documentId)) { - $documentId = $fieldset->getId(); - } - $fieldset = $fieldset->getFields(); - } - - $replace = array(); - if (empty($options[self::MERGE_OPTION])) { - // no merge option - we replace all - foreach ($fieldset as $key => $value) { - $replace[$key] = true; - } - } elseif (is_array($options[self::MERGE_OPTION])) { - foreach ($fieldset as $key => $value) { - if (empty($options[self::MERGE_OPTION][$key])) { - // if there's merge key, we add it, otherwise we replace it - $replace[$key] = true; - } - } - } // otherwise $replace is empty - all is merged - - try { - $this->_simpleDb->putAttributes( - $collectionName, - $documentId, - $this->_makeAttributes($documentId, $fieldset), - $replace - ); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document update: '.$e->getMessage(), $e->getCode(), $e); - } - return true; - } - - /** - * Delete document. - * - * @param string $collectionName Collection from which to delete document - * @param mixed $document Document ID or Document object. - * @param array $options - * @return boolean - */ - public function deleteDocument($collectionName, $document, $options = null) - { - if ($document instanceof Zend_Cloud_DocumentService_Document) { - $document = $document->getId(); - } - try { - $this->_simpleDb->deleteAttributes($collectionName, $document); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document deletion: '.$e->getMessage(), $e->getCode(), $e); - } - return true; - } - - /** - * Fetch single document by ID - * - * @param string $collectionName Collection name - * @param mixed $documentId Document ID, adapter-dependent - * @param array $options - * @return Zend_Cloud_DocumentService_Document - */ - public function fetchDocument($collectionName, $documentId, $options = null) - { - try { - $attributes = $this->_simpleDb->getAttributes($collectionName, $documentId); - if ($attributes == false || count($attributes) == 0) { - return false; - } - return $this->_resolveAttributes($attributes, true); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on fetching document: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Query for documents stored in the document service. If a string is passed in - * $query, the query string will be passed directly to the service. - * - * @param string $collectionName Collection name - * @param string $query - * @param array $options - * @return array Zend_Cloud_DocumentService_DocumentSet - */ - public function query($collectionName, $query, $options = null) - { - $returnDocs = isset($options[self::RETURN_DOCUMENTS]) - ? (bool) $options[self::RETURN_DOCUMENTS] - : true; - - try { - if ($query instanceof Zend_Cloud_DocumentService_Adapter_SimpleDb_Query) { - $query = $query->assemble($collectionName); - } - $result = $this->_simpleDb->select($query); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document query: '.$e->getMessage(), $e->getCode(), $e); - } - - return $this->_getDocumentSetFromResultSet($result, $returnDocs); - } - - /** - * Create query statement - * - * @param string $fields - * @return Zend_Cloud_DocumentService_Adapter_SimpleDb_Query - */ - public function select($fields = null) - { - $queryClass = $this->getQueryClass(); - if (!class_exists($queryClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($queryClass); - } - - $query = new $queryClass($this); - $defaultClass = self::DEFAULT_QUERY_CLASS; - if (!$query instanceof $defaultClass) { - throw new Zend_Cloud_DocumentService_Exception('Query class must extend ' . self::DEFAULT_QUERY_CLASS); - } - - $query->select($fields); - return $query; - } - - /** - * Get the concrete service client - * - * @return Zend_Service_Amazon_SimpleDb - */ - public function getClient() - { - return $this->_simpleDb; - } - - /** - * Convert array of key-value pairs to array of Amazon attributes - * - * @param string $name - * @param array $attributes - * @return array - */ - protected function _makeAttributes($name, $attributes) - { - $result = array(); - foreach ($attributes as $key => $attr) { - $result[] = new Zend_Service_Amazon_SimpleDb_Attribute($name, $key, $attr); - } - return $result; - } - - /** - * Convert array of Amazon attributes to array of key-value pairs - * - * @param array $attributes - * @return array - */ - protected function _resolveAttributes($attributes, $returnDocument = false) - { - $result = array(); - foreach ($attributes as $attr) { - $value = $attr->getValues(); - if (count($value) == 0) { - $value = null; - } elseif (count($value) == 1) { - $value = $value[0]; - } - $result[$attr->getName()] = $value; - } - - // Return as document object? - if ($returnDocument) { - $documentClass = $this->getDocumentClass(); - return new $documentClass($result, $attr->getItemName()); - } - - return $result; - } - - /** - * Create suitable document from array of fields - * - * @param array $document - * @return Zend_Cloud_DocumentService_Document - */ - protected function _getDocumentFromArray($document) - { - if (!isset($document[Zend_Cloud_DocumentService_Document::KEY_FIELD])) { - if (isset($document[self::ITEM_NAME])) { - $key = $document[self::ITEM_NAME]; - unset($document[self::ITEM_NAME]); - } else { - throw new Zend_Cloud_DocumentService_Exception('Fields array should contain the key field '.Zend_Cloud_DocumentService_Document::KEY_FIELD); - } - } else { - $key = $document[Zend_Cloud_DocumentService_Document::KEY_FIELD]; - unset($document[Zend_Cloud_DocumentService_Document::KEY_FIELD]); - } - - $documentClass = $this->getDocumentClass(); - return new $documentClass($document, $key); - } - - /** - * Create a DocumentSet from a SimpleDb resultset - * - * @param Zend_Service_Amazon_SimpleDb_Page $resultSet - * @param bool $returnDocs - * @return Zend_Cloud_DocumentService_DocumentSet - */ - protected function _getDocumentSetFromResultSet(Zend_Service_Amazon_SimpleDb_Page $resultSet, $returnDocs = true) - { - $docs = array(); - foreach ($resultSet->getData() as $item) { - $docs[] = $this->_resolveAttributes($item, $returnDocs); - } - - $setClass = $this->getDocumentSetClass(); - return new $setClass($docs); - } -} diff --git a/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php b/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php deleted file mode 100644 index 1477e0ea8ac..00000000000 --- a/lib/Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php +++ /dev/null @@ -1,175 +0,0 @@ -_adapter = $adapter; - if (null !== $collectionName) { - $this->from($collectionName); - } - } - - /** - * Get adapter - * - * @return Zend_Cloud_DocumentService_Adapter_SimpleDb - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Assemble the query into a format the adapter can utilize - * - * @var string $collectionName Name of collection from which to select - * @return string - */ - public function assemble($collectionName = null) - { - $adapter = $this->getAdapter()->getClient(); - $select = null; - $from = null; - $where = null; - $order = null; - $limit = null; - foreach ($this->getClauses() as $clause) { - list($name, $args) = $clause; - - switch ($name) { - case self::QUERY_SELECT: - $select = $args[0]; - break; - case self::QUERY_FROM: - if (null === $from) { - // Only allow setting FROM clause once - $from = $adapter->quoteName($args); - } - break; - case self::QUERY_WHERE: - $statement = $this->_parseWhere($args[0], $args[1]); - if (null === $where) { - $where = $statement; - } else { - $operator = empty($args[2]) ? 'AND' : $args[2]; - $where .= ' ' . $operator . ' ' . $statement; - } - break; - case self::QUERY_WHEREID: - $statement = $this->_parseWhere('ItemName() = ?', array($args)); - if (null === $where) { - $where = $statement; - } else { - $operator = empty($args[2]) ? 'AND' : $args[2]; - $where .= ' ' . $operator . ' ' . $statement; - } - break; - case self::QUERY_ORDER: - $order = $adapter->quoteName($args[0]); - if (isset($args[1])) { - $order .= ' ' . $args[1]; - } - break; - case self::QUERY_LIMIT: - $limit = $args; - break; - default: - // Ignore unknown clauses - break; - } - } - - if (empty($select)) { - $select = "*"; - } - if (empty($from)) { - if (null === $collectionName) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("Query requires a FROM clause"); - } - $from = $adapter->quoteName($collectionName); - } - $query = "select $select from $from"; - if (!empty($where)) { - $query .= " where $where"; - } - if (!empty($order)) { - $query .= " order by $order"; - } - if (!empty($limit)) { - $query .= " limit $limit"; - } - return $query; - } - - /** - * Parse a where statement into service-specific language - * - * @todo Ensure this fulfills the entire SimpleDB query specification for WHERE - * @param string $where - * @param array $args - * @return string - */ - protected function _parseWhere($where, $args) - { - if (!is_array($args)) { - $args = (array) $args; - } - $adapter = $this->getAdapter()->getClient(); - $i = 0; - while (false !== ($pos = strpos($where, '?'))) { - $where = substr_replace($where, $adapter->quote($args[$i]), $pos); - ++$i; - } - if (('(' != $where[0]) || (')' != $where[strlen($where) - 1])) { - $where = '(' . $where . ')'; - } - return $where; - } - } diff --git a/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure.php b/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure.php deleted file mode 100644 index 0f778d8f683..00000000000 --- a/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure.php +++ /dev/null @@ -1,628 +0,0 @@ -toArray(); - } - - if (empty($options)) { - $options = array(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid options provided'); - } - - if (isset($options[self::DOCUMENT_CLASS])) { - $this->setDocumentClass($options[self::DOCUMENT_CLASS]); - } - - if (isset($options[self::DOCUMENTSET_CLASS])) { - $this->setDocumentSetClass($options[self::DOCUMENTSET_CLASS]); - } - - if (isset($options[self::QUERY_CLASS])) { - $this->setQueryClass($options[self::QUERY_CLASS]); - } - - // Build Zend_Service_WindowsAzure_Storage_Blob instance - if (!isset($options[self::HOST])) { - $host = self::DEFAULT_HOST; - } else { - $host = $options[self::HOST]; - } - - if (! isset($options[self::ACCOUNT_NAME])) { - throw new Zend_Cloud_DocumentService_Exception('No Windows Azure account name provided.'); - } - - if (! isset($options[self::ACCOUNT_KEY])) { - throw new Zend_Cloud_DocumentService_Exception('No Windows Azure account key provided.'); - } - - // TODO: support $usePathStyleUri and $retryPolicy - try { - $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Table( - $host, $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]); - // Parse other options - if (! empty($options[self::PROXY_HOST])) { - $proxyHost = $options[self::PROXY_HOST]; - $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080; - $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : ''; - $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials); - } - if (isset($options[self::HTTP_ADAPTER])) { - $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]); - } - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document service creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Set the default partition key - * - * @param string $key - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure - */ - public function setDefaultPartitionKey($key) - { - $this->_validateKey($key); - $this->_defaultPartitionKey = $key; - return $this; - } - - /** - * Retrieve default partition key - * - * @return null|string - */ - public function getDefaultPartitionKey() - { - return $this->_defaultPartitionKey; - } - - /** - * Create collection. - * - * @param string $name - * @param array $options - * @return boolean - */ - public function createCollection($name, $options = null) - { - if (!preg_match('/^[A-Za-z][A-Za-z0-9]{2,}$/', $name)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid collection name; Windows Azure collection names must consist of alphanumeric characters only, and be at least 3 characters long'); - } - try { - $this->_storageClient->createTable($name); - } catch(Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "table specified already exists") === false) { - throw new Zend_Cloud_DocumentService_Exception('Error on collection creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - return true; - } - - /** - * Delete collection. - * - * @param string $name - * @param array $options - * @return boolean - */ - public function deleteCollection($name, $options = null) - { - try { - $this->_storageClient->deleteTable($name); - } catch(Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "does not exist") === false) { - throw new Zend_Cloud_DocumentService_Exception('Error on collection deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - return true; - } - - /** - * List collections. - * - * @param array $options - * @return array - */ - public function listCollections($options = null) - { - try { - $tables = $this->_storageClient->listTables(); - $restables = array(); - foreach ($tables as $table) { - $restables[] = $table->name; - } - return $restables; - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on collection list: '.$e->getMessage(), $e->getCode(), $e); - } - - return $tables; - } - - /** - * Create suitable document from array of fields - * - * @param array $document - * @param null|string $collectionName Collection to which this document belongs - * @return Zend_Cloud_DocumentService_Document - */ - protected function _getDocumentFromArray($document, $collectionName = null) - { - $key = null; - if (!isset($document[Zend_Cloud_DocumentService_Document::KEY_FIELD])) { - if (isset($document[self::ROW_KEY])) { - $rowKey = $document[self::ROW_KEY]; - unset($document[self::ROW_KEY]); - if (isset($document[self::PARTITION_KEY])) { - $key = array($document[self::PARTITION_KEY], $rowKey); - unset($document[self::PARTITION_KEY]); - } elseif (null !== ($partitionKey = $this->getDefaultPartitionKey())) { - $key = array($partitionKey, $rowKey); - } elseif (null !== $collectionName) { - $key = array($collectionName, $rowKey); - } - } - } else { - $key = $document[Zend_Cloud_DocumentService_Document::KEY_FIELD]; - unset($document[Zend_Cloud_DocumentService_Document::KEY_FIELD]); - } - - $documentClass = $this->getDocumentClass(); - return new $documentClass($document, $key); - } - - /** - * List all documents in a collection - * - * @param string $collectionName - * @param null|array $options - * @return Zend_Cloud_DocumentService_DocumentSet - */ - public function listDocuments($collectionName, array $options = null) - { - $select = $this->select()->from($collectionName); - return $this->query($collectionName, $select); - } - - /** - * Insert document - * - * @param array|Zend_Cloud_DocumentService_Document $document - * @param array $options - * @return boolean - */ - public function insertDocument($collectionName, $document, $options = null) - { - if (is_array($document)) { - $document = $this->_getDocumentFromArray($document, $collectionName); - } - - if (!$document instanceof Zend_Cloud_DocumentService_Document) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); - } - - $key = $this->_validateDocumentId($document->getId(), $collectionName); - $document->setId($key); - - $this->_validateCompositeKey($key); - $this->_validateFields($document); - try { - - $entity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($key[0], $key[1]); - $entity->setAzureValues($document->getFields(), true); - $this->_storageClient->insertEntity($collectionName, $entity); - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document insertion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Replace document. - * - * The new document replaces the existing document. - * - * @param Zend_Cloud_DocumentService_Document $document - * @param array $options - * @return boolean - */ - public function replaceDocument($collectionName, $document, $options = null) - { - if (is_array($document)) { - $document = $this->_getDocumentFromArray($document, $collectionName); - } - - if (!$document instanceof Zend_Cloud_DocumentService_Document) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); - } - - $key = $this->_validateDocumentId($document->getId(), $collectionName); - $this->_validateFields($document); - try { - $entity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($key[0], $key[1]); - $entity->setAzureValues($document->getFields(), true); - if (isset($options[self::VERIFY_ETAG])) { - $entity->setEtag($options[self::VERIFY_ETAG]); - } - - $this->_storageClient->updateEntity($collectionName, $entity, isset($options[self::VERIFY_ETAG])); - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document replace: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Update document. - * - * The new document is merged the existing document. - * - * @param string $collectionName - * @param mixed|Zend_Cloud_DocumentService_Document $documentId Document identifier or document contaiing updates - * @param null|array|Zend_Cloud_DocumentService_Document Fields to update (or new fields)) - * @param array $options - * @return boolean - */ - public function updateDocument($collectionName, $documentId, $fieldset = null, $options = null) - { - if (null === $fieldset && $documentId instanceof Zend_Cloud_DocumentService_Document) { - $fieldset = $documentId->getFields(); - $documentId = $documentId->getId(); - } elseif ($fieldset instanceof Zend_Cloud_DocumentService_Document) { - if ($documentId == null) { - $documentId = $fieldset->getId(); - } - $fieldset = $fieldset->getFields(); - } - - $this->_validateCompositeKey($documentId, $collectionName); - $this->_validateFields($fieldset); - try { - $entity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($documentId[0], $documentId[1]); - - // Ensure timestamp is set correctly - if (isset($fieldset[self::TIMESTAMP_KEY])) { - $entity->setTimestamp($fieldset[self::TIMESTAMP_KEY]); - unset($fieldset[self::TIMESTAMP_KEY]); - } - - $entity->setAzureValues($fieldset, true); - if (isset($options[self::VERIFY_ETAG])) { - $entity->setEtag($options[self::VERIFY_ETAG]); - } - - $this->_storageClient->mergeEntity($collectionName, $entity, isset($options[self::VERIFY_ETAG])); - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document update: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete document. - * - * @param mixed $document Document ID or Document object. - * @param array $options - * @return void - */ - public function deleteDocument($collectionName, $documentId, $options = null) - { - if ($documentId instanceof Zend_Cloud_DocumentService_Document) { - $documentId = $documentId->getId(); - } - - $documentId = $this->_validateDocumentId($documentId, $collectionName); - - try { - $entity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($documentId[0], $documentId[1]); - if (isset($options[self::VERIFY_ETAG])) { - $entity->setEtag($options[self::VERIFY_ETAG]); - } - $this->_storageClient->deleteEntity($collectionName, $entity, isset($options[self::VERIFY_ETAG])); - } catch(Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "does not exist") === false) { - throw new Zend_Cloud_DocumentService_Exception('Error on document deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - } - - /** - * Fetch single document by ID - * - * @param string $collectionName Collection name - * @param mixed $documentId Document ID, adapter-dependent - * @param array $options - * @return Zend_Cloud_DocumentService_Document - */ - public function fetchDocument($collectionName, $documentId, $options = null) - { - $documentId = $this->_validateDocumentId($documentId, $collectionName); - try { - $entity = $this->_storageClient->retrieveEntityById($collectionName, $documentId[0], $documentId[1]); - $documentClass = $this->getDocumentClass(); - return new $documentClass($this->_resolveAttributes($entity), array($entity->getPartitionKey(), $entity->getRowKey())); - } catch (Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "does not exist") !== false) { - return false; - } - throw new Zend_Cloud_DocumentService_Exception('Error on document fetch: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Query for documents stored in the document service. If a string is passed in - * $query, the query string will be passed directly to the service. - * - * @param string $collectionName Collection name - * @param string|Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query $query - * @param array $options - * @return array Zend_Cloud_DocumentService_DocumentSet - */ - public function query($collectionName, $query, $options = null) - { - try { - if ($query instanceof Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query) { - $entities = $this->_storageClient->retrieveEntities($query->assemble()); - } else { - $entities = $this->_storageClient->retrieveEntities($collectionName, $query); - } - - $documentClass = $this->getDocumentClass(); - $resultSet = array(); - foreach ($entities as $entity) { - $resultSet[] = new $documentClass( - $this->_resolveAttributes($entity), - array($entity->getPartitionKey(), $entity->getRowKey()) - ); - } - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_DocumentService_Exception('Error on document query: '.$e->getMessage(), $e->getCode(), $e); - } - - $setClass = $this->getDocumentSetClass(); - return new $setClass($resultSet); - } - - /** - * Create query statement - * - * @return Zend_Cloud_DocumentService_Query - */ - public function select($fields = null) - { - $queryClass = $this->getQueryClass(); - if (!class_exists($queryClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($queryClass); - } - - $query = new $queryClass(); - $defaultClass = self::DEFAULT_QUERY_CLASS; - if (!$query instanceof $defaultClass) { - throw new Zend_Cloud_DocumentService_Exception('Query class must extend ' . self::DEFAULT_QUERY_CLASS); - } - - $query->select($fields); - return $query; - } - - /** - * Get the concrete service client - * - * @return Zend_Service_WindowsAzure_Storage_Table - */ - public function getClient() - { - return $this->_storageClient; - } - - /** - * Resolve table values to attributes - * - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity - * @return array - */ - protected function _resolveAttributes(Zend_Service_WindowsAzure_Storage_TableEntity $entity) - { - $result = array(); - foreach ($entity->getAzureValues() as $attr) { - $result[$attr->Name] = $attr->Value; - } - return $result; - } - - - /** - * Validate a partition or row key - * - * @param string $key - * @return void - * @throws Zend_Cloud_DocumentService_Exception - */ - protected function _validateKey($key) - { - if (preg_match('@[/#?' . preg_quote('\\', '@') . ']@', $key)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid partition or row key provided; must not contain /, \\, #, or ? characters'); - } - } - - /** - * Validate a composite key - * - * @param array $key - * @return throws Zend_Cloud_DocumentService_Exception - */ - protected function _validateCompositeKey(array $key) - { - if (2 != count($key)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document key provided; must contain exactly two elements: a PartitionKey and a RowKey'); - } - foreach ($key as $k) { - $this->_validateKey($k); - } - } - - /** - * Validate a document identifier - * - * If the identifier is an array containing a valid partition and row key, - * returns it. If the identifier is a string: - * - if a default partition key is present, it creates an identifier using - * that and the provided document ID - * - if a collection name is provided, it will use that for the partition key - * - otherwise, it's invalid - * - * @param array|string $documentId - * @param null|string $collectionName - * @return array - * @throws Zend_Cloud_DocumentService_Exception - */ - protected function _validateDocumentId($documentId, $collectionName = false) - { - if (is_array($documentId)) { - $this->_validateCompositeKey($documentId); - return $documentId; - } - if (!is_string($documentId)) { - throw new Zend_Cloud_DocumentService_Exception('Invalid document identifier; must be a string or an array'); - } - - $this->_validateKey($documentId); - - if (null !== ($partitionKey = $this->getDefaultPartitionKey())) { - return array($partitionKey, $documentId); - } - if (null !== $collectionName) { - return array($collectionName, $documentId); - } - throw new Zend_Cloud_DocumentService_Exception('Cannot determine partition name; invalid document identifier'); - } - - /** - * Validate a document's fields for well-formedness - * - * Since Azure uses Atom, and fieldnames are included as part of XML - * element tag names, the field names must be valid XML names. - * - * @param Zend_Cloud_DocumentService_Document|array $document - * @return void - * @throws Zend_Cloud_DocumentService_Exception - */ - public function _validateFields($document) - { - if ($document instanceof Zend_Cloud_DocumentService_Document) { - $document = $document->getFields(); - } elseif (!is_array($document)) { - throw new Zend_Cloud_DocumentService_Exception('Cannot inspect fields; invalid type provided'); - } - - foreach (array_keys($document) as $key) { - $this->_validateFieldKey($key); - } - } - - /** - * Validate an individual field name for well-formedness - * - * Since Azure uses Atom, and fieldnames are included as part of XML - * element tag names, the field names must be valid XML names. - * - * While we could potentially normalize names, this could also lead to - * conflict with other field names -- which we should avoid. As such, - * invalid field names will raise an exception. - * - * @param string $key - * @return void - * @throws Zend_Cloud_DocumentService_Exception - */ - public function _validateFieldKey($key) - { - if (!preg_match('/^[_A-Za-z][-._A-Za-z0-9]*$/', $key)) { - throw new Zend_Cloud_DocumentService_Exception('Field keys must conform to XML names (^[_A-Za-z][-._A-Za-z0-9]*$); key "' . $key . '" does not match'); - } - } -} diff --git a/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php b/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php deleted file mode 100644 index 21eb039da0a..00000000000 --- a/lib/Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php +++ /dev/null @@ -1,171 +0,0 @@ -_azureSelect = $select; - } - - /** - * SELECT clause (fields to be selected) - * - * Does nothing for Azure. - * - * @param string $select - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - */ - public function select($select) - { - return $this; - } - - /** - * FROM clause (table name) - * - * @param string $from - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - */ - public function from($from) - { - $this->_azureSelect->from($from); - return $this; - } - - /** - * WHERE clause (conditions to be used) - * - * @param string $where - * @param mixed $value Value or array of values to be inserted instead of ? - * @param string $op Operation to use to join where clauses (AND/OR) - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - */ - public function where($where, $value = null, $op = 'and') - { - if (!empty($value) && !is_array($value)) { - // fix buglet in Azure - numeric values are quoted unless passed as an array - $value = array($value); - } - $this->_azureSelect->where($where, $value, $op); - return $this; - } - - /** - * WHERE clause for item ID - * - * This one should be used when fetching specific rows since some adapters - * have special syntax for primary keys - * - * @param array $value Row ID for the document (PartitionKey, RowKey) - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - */ - public function whereId($value) - { - if (!is_array($value)) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception('Invalid document key'); - } - $this->_azureSelect->wherePartitionKey($value[0])->whereRowKey($value[1]); - return $this; - } - - /** - * LIMIT clause (how many rows to return) - * - * @param int $limit - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - */ - public function limit($limit) - { - $this->_azureSelect->top($limit); - return $this; - } - - /** - * ORDER BY clause (sorting) - * - * @todo Azure service doesn't seem to support this yet; emulate? - * @param string $sort Column to sort by - * @param string $direction Direction - asc/desc - * @return Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query - * @throws Zend_Cloud_OperationNotAvailableException - */ - public function order($sort, $direction = 'asc') - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('No support for sorting for Azure yet'); - } - - /** - * Get Azure select query - * - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function getAzureSelect() - { - return $this->_azureSelect; - } - - /** - * Assemble query - * - * Simply return the WindowsAzure table entity query object - * - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function assemble() - { - return $this->getAzureSelect(); - } -} diff --git a/lib/Zend/Cloud/DocumentService/Document.php b/lib/Zend/Cloud/DocumentService/Document.php deleted file mode 100644 index 46aade2c414..00000000000 --- a/lib/Zend/Cloud/DocumentService/Document.php +++ /dev/null @@ -1,248 +0,0 @@ -_fields = $fields; - $this->setId($id); - } - - /** - * Set document identifier - * - * @param mixed $id - * @return Zend_Cloud_DocumentService_Document - */ - public function setId($id) - { - $this->_id = $id; - return $this; - } - - /** - * Get ID name. - * - * @return string - */ - public function getId() - { - return $this->_id; - } - - /** - * Get fields as array. - * - * @return array - */ - public function getFields() - { - return $this->_fields; - } - - /** - * Get field by name. - * - * @param string $name - * @return mixed - */ - public function getField($name) - { - if (isset($this->_fields[$name])) { - return $this->_fields[$name]; - } - return null; - } - - /** - * Set field by name. - * - * @param string $name - * @param mixed $value - * @return Zend_Cloud_DocumentService_Document - */ - public function setField($name, $value) - { - $this->_fields[$name] = $value; - return $this; - } - - /** - * Overloading: get value - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - return $this->getField($name); - } - - /** - * Overloading: set field - * - * @param string $name - * @param mixed $value - * @return void - */ - public function __set($name, $value) - { - $this->setField($name, $value); - } - - /** - * ArrayAccess: does field exist? - * - * @param string $name - * @return bool - */ - public function offsetExists($name) - { - return isset($this->_fields[$name]); - } - - /** - * ArrayAccess: get field by name - * - * @param string $name - * @return mixed - */ - public function offsetGet($name) - { - return $this->getField($name); - } - - /** - * ArrayAccess: set field to value - * - * @param string $name - * @param mixed $value - * @return void - */ - public function offsetSet($name, $value) - { - $this->setField($name, $value); - } - - /** - * ArrayAccess: remove field from document - * - * @param string $name - * @return void - */ - public function offsetUnset($name) - { - if ($this->offsetExists($name)) { - unset($this->_fields[$name]); - } - } - - /** - * Overloading: retrieve and set fields by name - * - * @param string $name - * @param mixed $args - * @return mixed - */ - public function __call($name, $args) - { - $prefix = substr($name, 0, 3); - if ($prefix == 'get') { - // Get value - $option = substr($name, 3); - return $this->getField($option); - } elseif ($prefix == 'set') { - // set value - $option = substr($name, 3); - return $this->setField($option, $args[0]); - } - - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException("Unknown operation $name"); - } - - /** - * Countable: return count of fields in document - * - * @return int - */ - public function count() - { - return count($this->_fields); - } - - /** - * IteratorAggregate: return iterator for iterating over fields - * - * @return Iterator - */ - public function getIterator() - { - return new ArrayIterator($this->_fields); - } -} diff --git a/lib/Zend/Cloud/DocumentService/DocumentSet.php b/lib/Zend/Cloud/DocumentService/DocumentSet.php deleted file mode 100644 index 3c8b541176a..00000000000 --- a/lib/Zend/Cloud/DocumentService/DocumentSet.php +++ /dev/null @@ -1,68 +0,0 @@ -_documentCount = count($documents); - $this->_documents = new ArrayIterator($documents); - } - - /** - * Countable: number of documents in set - * - * @return int - */ - public function count() - { - return $this->_documentCount; - } - - /** - * IteratorAggregate: retrieve iterator - * - * @return Traversable - */ - public function getIterator() - { - return $this->_documents; - } -} diff --git a/lib/Zend/Cloud/DocumentService/Exception.php b/lib/Zend/Cloud/DocumentService/Exception.php deleted file mode 100644 index c77c698f181..00000000000 --- a/lib/Zend/Cloud/DocumentService/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -foo('bar') - * but concrete adapters should be able to recognise it - * - * The call will be iterpreted as clause 'foo' with argument 'bar' - * - * @param string $name Clause/method name - * @param mixed $args - * @return Zend_Cloud_DocumentService_Query - */ - public function __call($name, $args) - { - $this->_clauses[] = array(strtolower($name), $args); - return $this; - } - - /** - * SELECT clause (fields to be selected) - * - * @param null|string|array $select - * @return Zend_Cloud_DocumentService_Query - */ - public function select($select) - { - if (empty($select)) { - return $this; - } - if (!is_string($select) && !is_array($select)) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("SELECT argument must be a string or an array of strings"); - } - $this->_clauses[] = array(self::QUERY_SELECT, $select); - return $this; - } - - /** - * FROM clause - * - * @param string $name Field names - * @return Zend_Cloud_DocumentService_Query - */ - public function from($name) - { - if(!is_string($name)) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("FROM argument must be a string"); - } - $this->_clauses[] = array(self::QUERY_FROM, $name); - return $this; - } - - /** - * WHERE query - * - * @param string $cond Condition - * @param array $args Arguments to substitute instead of ?'s in condition - * @param string $op relation to other clauses - and/or - * @return Zend_Cloud_DocumentService_Query - */ - public function where($cond, $value = null, $op = 'and') - { - if (!is_string($cond)) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("WHERE argument must be a string"); - } - $this->_clauses[] = array(self::QUERY_WHERE, array($cond, $value, $op)); - return $this; - } - - /** - * Select record or fields by ID - * - * @param string|int $value Identifier to select by - * @return Zend_Cloud_DocumentService_Query - */ - public function whereId($value) - { - if (!is_scalar($value)) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("WHEREID argument must be a scalar"); - } - $this->_clauses[] = array(self::QUERY_WHEREID, $value); - return $this; - } - - /** - * LIMIT clause (how many items to return) - * - * @param int $limit - * @return Zend_Cloud_DocumentService_Query - */ - public function limit($limit) - { - if ($limit != (int) $limit) { - #require_once 'Zend/Cloud/DocumentService/Exception.php'; - throw new Zend_Cloud_DocumentService_Exception("LIMIT argument must be an integer"); - } - $this->_clauses[] = array(self::QUERY_LIMIT, $limit); - return $this; - } - - /** - * ORDER clause; field or fields to sort by, and direction to sort - * - * @param string|int|array $sort - * @param string $direction - * @return Zend_Cloud_DocumentService_Query - */ - public function order($sort, $direction = 'asc') - { - $this->_clauses[] = array(self::QUERY_ORDER, array($sort, $direction)); - return $this; - } - - /** - * "Assemble" the query - * - * Simply returns the clauses present. - * - * @return array - */ - public function assemble() - { - return $this->getClauses(); - } - - /** - * Return query clauses as an array - * - * @return array Clauses in the query - */ - public function getClauses() - { - return $this->_clauses; - } -} diff --git a/lib/Zend/Cloud/DocumentService/QueryAdapter.php b/lib/Zend/Cloud/DocumentService/QueryAdapter.php deleted file mode 100644 index b4216c3e395..00000000000 --- a/lib/Zend/Cloud/DocumentService/QueryAdapter.php +++ /dev/null @@ -1,102 +0,0 @@ -_clientException = $clientException; - parent::__construct($message, $code, $clientException); - } - - public function getClientException() { - return $this->_getPrevious(); - } -} - diff --git a/lib/Zend/Cloud/Infrastructure/Adapter.php b/lib/Zend/Cloud/Infrastructure/Adapter.php deleted file mode 100644 index bc3c1cdec32..00000000000 --- a/lib/Zend/Cloud/Infrastructure/Adapter.php +++ /dev/null @@ -1,167 +0,0 @@ -adapterResult; - } - - /** - * Wait for status $status with a timeout of $timeout seconds - * - * @param string $id - * @param string $status - * @param integer $timeout - * @return boolean - */ - public function waitStatusInstance($id, $status, $timeout = self::TIMEOUT_STATUS_CHANGE) - { - if (empty($id) || empty($status)) { - return false; - } - - $num = 0; - while (($num<$timeout) && ($this->statusInstance($id) != $status)) { - sleep(self::TIME_STEP_STATUS_CHANGE); - $num += self::TIME_STEP_STATUS_CHANGE; - } - return ($num < $timeout); - } - - /** - * Run arbitrary shell script on an instance - * - * @param string $id - * @param array $param - * @param string|array $cmd - * @return string|array - */ - public function deployInstance($id, $params, $cmd) - { - if (!function_exists("ssh2_connect")) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Deployment requires the PHP "SSH" extension (ext/ssh2)'); - } - - if (empty($id)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the instance where to deploy'); - } - - if (empty($cmd)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the shell commands to run on the instance'); - } - - if (empty($params) - || empty($params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME]) - || (empty($params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD]) - && empty($params[Zend_Cloud_Infrastructure_Instance::SSH_KEY])) - ) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the params for the SSH connection'); - } - - $host = $this->publicDnsInstance($id); - if (empty($host)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf( - 'The instance identified by "%s" does not exist', - $id - )); - } - - $conn = ssh2_connect($host); - if (!ssh2_auth_password($conn, $params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME], - $params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD])) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('SSH authentication failed'); - } - - if (is_array($cmd)) { - $result = array(); - foreach ($cmd as $command) { - $stream = ssh2_exec($conn, $command); - $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR); - - stream_set_blocking($errorStream, true); - stream_set_blocking($stream, true); - - $output = stream_get_contents($stream); - $error = stream_get_contents($errorStream); - - if (empty($error)) { - $result[$command] = $output; - } else { - $result[$command] = $error; - } - } - } else { - $stream = ssh2_exec($conn, $cmd); - $result = stream_set_blocking($stream, true); - $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR); - - stream_set_blocking($errorStream, true); - stream_set_blocking($stream, true); - - $output = stream_get_contents($stream); - $error = stream_get_contents($errorStream); - - if (empty($error)) { - $result = $output; - } else { - $result = $error; - } - } - return $result; - } -} diff --git a/lib/Zend/Cloud/Infrastructure/Adapter/Ec2.php b/lib/Zend/Cloud/Infrastructure/Adapter/Ec2.php deleted file mode 100644 index defb5633c77..00000000000 --- a/lib/Zend/Cloud/Infrastructure/Adapter/Ec2.php +++ /dev/null @@ -1,496 +0,0 @@ - Zend_Cloud_Infrastructure_Instance::STATUS_RUNNING, - 'terminated' => Zend_Cloud_Infrastructure_Instance::STATUS_TERMINATED, - 'pending' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'shutting-down' => Zend_Cloud_Infrastructure_Instance::STATUS_SHUTTING_DOWN, - 'stopping' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'stopped' => Zend_Cloud_Infrastructure_Instance::STATUS_STOPPED, - 'rebooting' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING, - ); - - /** - * Map monitor metrics between Infrastructure and EC2 - * - * @var array - */ - protected $mapMetrics= array ( - Zend_Cloud_Infrastructure_Instance::MONITOR_CPU => 'CPUUtilization', - Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_READ => 'DiskReadBytes', - Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_WRITE => 'DiskWriteBytes', - Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_IN => 'NetworkIn', - Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_OUT => 'NetworkOut', - ); - - /** - * Constructor - * - * @param array|Zend_Config $options - * @return void - */ - public function __construct($options = array()) - { - if (is_object($options)) { - if (method_exists($options, 'toArray')) { - $options= $options->toArray(); - } elseif ($options instanceof Traversable) { - $options = iterator_to_array($options); - } - } - - if (empty($options) || !is_array($options)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Invalid options provided'); - } - - if (!isset($options[self::AWS_ACCESS_KEY]) - || !isset($options[self::AWS_SECRET_KEY]) - ) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('AWS keys not specified!'); - } - - $this->accessKey = $options[self::AWS_ACCESS_KEY]; - $this->accessSecret = $options[self::AWS_SECRET_KEY]; - $this->region = ''; - - if (isset($options[self::AWS_REGION])) { - $this->region= $options[self::AWS_REGION]; - } - - try { - $this->ec2 = new Zend_Service_Amazon_Ec2_Instance($options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY], $this->region); - } catch (Exception $e) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Error on create: ' . $e->getMessage(), $e->getCode(), $e); - } - - if (isset($options[self::HTTP_ADAPTER])) { - $this->ec2->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - } - - /** - * Convert the attributes of EC2 into attributes of Infrastructure - * - * @param array $attr - * @return array|boolean - */ - private function convertAttributes($attr) - { - $result = array(); - if (!empty($attr) && is_array($attr)) { - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ID] = $attr['instanceId']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STATUS] = $this->mapStatus[$attr['instanceState']['name']]; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_IMAGEID] = $attr['imageId']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = $attr['availabilityZone']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_LAUNCHTIME] = $attr['launchTime']; - - switch ($attr['instanceType']) { - case Zend_Service_Amazon_Ec2_Instance::MICRO: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '1 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '613MB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '0GB'; - break; - case Zend_Service_Amazon_Ec2_Instance::SMALL: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '1 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '1.7GB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '160GB'; - break; - case Zend_Service_Amazon_Ec2_Instance::LARGE: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '2 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '7.5GB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '850GB'; - break; - case Zend_Service_Amazon_Ec2_Instance::XLARGE: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '4 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '15GB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '1690GB'; - break; - case Zend_Service_Amazon_Ec2_Instance::HCPU_MEDIUM: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '2 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '1.7GB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '350GB'; - break; - case Zend_Service_Amazon_Ec2_Instance::HCPU_XLARGE: - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '8 virtual core'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '7GB'; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '1690GB'; - break; - } - } - return $result; - } - - /** - * Return a list of the available instancies - * - * @return Zend_Cloud_Infrastructure_InstanceList - */ - public function listInstances() - { - $this->adapterResult = $this->ec2->describe(); - - $result = array(); - foreach ($this->adapterResult['instances'] as $instance) { - $result[]= $this->convertAttributes($instance); - } - return new Zend_Cloud_Infrastructure_InstanceList($this, $result); - } - - /** - * Return the status of an instance - * - * @param string - * @return string|boolean - */ - public function statusInstance($id) - { - $this->adapterResult = $this->ec2->describe($id); - if (empty($this->adapterResult['instances'])) { - return false; - } - $result = $this->adapterResult['instances'][0]; - return $this->mapStatus[$result['instanceState']['name']]; - } - - /** - * Return the public DNS name of the instance - * - * @param string $id - * @return string|boolean - */ - public function publicDnsInstance($id) - { - $this->adapterResult = $this->ec2->describe($id); - if (empty($this->adapterResult['instances'])) { - return false; - } - $result = $this->adapterResult['instances'][0]; - return $result['dnsName']; - } - - /** - * Reboot an instance - * - * @param string $id - * @return boolean - */ - public function rebootInstance($id) - { - $this->adapterResult= $this->ec2->reboot($id); - return $this->adapterResult; - } - - /** - * Create a new instance - * - * @param string $name - * @param array $options - * @return Instance|boolean - */ - public function createInstance($name, $options) - { - // @todo instance's name management? - $this->adapterResult = $this->ec2->run($options); - if (empty($this->adapterResult['instances'])) { - return false; - } - $this->error= false; - return new Zend_Cloud_Infrastructure_Instance($this, $this->convertAttributes($this->adapterResult['instances'][0])); - } - - /** - * Stop an instance - * - * @param string $id - * @return boolean - */ - public function stopInstance($id) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The stopInstance method is not implemented in the adapter'); - } - - /** - * Start an instance - * - * @param string $id - * @return boolean - */ - public function startInstance($id) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The startInstance method is not implemented in the adapter'); - } - - /** - * Destroy an instance - * - * @param string $id - * @return boolean - */ - public function destroyInstance($id) - { - $this->adapterResult = $this->ec2->terminate($id); - return (!empty($this->adapterResult)); - } - - /** - * Return a list of all the available instance images - * - * @return ImageList - */ - public function imagesInstance() - { - if (!isset($this->ec2Image)) { - $this->ec2Image = new Zend_Service_Amazon_Ec2_Image($this->accessKey, $this->accessSecret, $this->region); - } - - $this->adapterResult = $this->ec2Image->describe(); - - $images = array(); - - foreach ($this->adapterResult as $result) { - switch (strtolower($result['platform'])) { - case 'windows' : - $platform = Zend_Cloud_Infrastructure_Image::IMAGE_WINDOWS; - break; - default: - $platform = Zend_Cloud_Infrastructure_Image::IMAGE_LINUX; - break; - } - - $images[]= array ( - Zend_Cloud_Infrastructure_Image::IMAGE_ID => $result['imageId'], - Zend_Cloud_Infrastructure_Image::IMAGE_NAME => '', - Zend_Cloud_Infrastructure_Image::IMAGE_DESCRIPTION => $result['imageLocation'], - Zend_Cloud_Infrastructure_Image::IMAGE_OWNERID => $result['imageOwnerId'], - Zend_Cloud_Infrastructure_Image::IMAGE_ARCHITECTURE => $result['architecture'], - Zend_Cloud_Infrastructure_Image::IMAGE_PLATFORM => $platform, - ); - } - return new Zend_Cloud_Infrastructure_ImageList($images,$this->ec2Image); - } - - /** - * Return all the available zones - * - * @return array - */ - public function zonesInstance() - { - if (!isset($this->ec2Zone)) { - $this->ec2Zone = new Zend_Service_Amazon_Ec2_AvailabilityZones($this->accessKey,$this->accessSecret,$this->region); - } - $this->adapterResult = $this->ec2Zone->describe(); - - $zones = array(); - foreach ($this->adapterResult as $zone) { - if (strtolower($zone['zoneState']) === 'available') { - $zones[] = array ( - Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE => $zone['zoneName'], - ); - } - } - return $zones; - } - - /** - * Return the system information about the $metric of an instance - * - * @param string $id - * @param string $metric - * @param null|array $options - * @return array - */ - public function monitorInstance($id, $metric, $options = null) - { - if (empty($id) || empty($metric)) { - return false; - } - - if (!in_array($metric,$this->validMetrics)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf( - 'The metric "%s" is not valid', - $metric - )); - } - - if (!empty($options) && !is_array($options)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The options must be an array'); - } - - if (!empty($options) - && (empty($options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME]) - || empty($options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME])) - ) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf( - 'The options array must contain: "%s" and "%s"', - $options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME], - $options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME] - )); - } - - if (!isset($this->ec2Monitor)) { - $this->ec2Monitor = new Zend_Service_Amazon_Ec2_CloudWatch($this->accessKey, $this->accessSecret, $this->region); - } - - $param = array( - 'MeasureName' => $this->mapMetrics[$metric], - 'Statistics' => array('Average'), - 'Dimensions' => array('InstanceId' => $id), - ); - - if (!empty($options)) { - $param['StartTime'] = $options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME]; - $param['EndTime'] = $options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME]; - } - - $this->adapterResult = $this->ec2Monitor->getMetricStatistics($param); - - $monitor = array(); - $num = 0; - $average = 0; - - if (!empty($this->adapterResult['datapoints'])) { - foreach ($this->adapterResult['datapoints'] as $result) { - $monitor['series'][] = array ( - 'timestamp' => $result['Timestamp'], - 'value' => $result['Average'], - ); - $average += $result['Average']; - $num++; - } - } - - if ($num > 0) { - $monitor['average'] = $average / $num; - } - - return $monitor; - } - - /** - * Get the adapter - * - * @return Zend_Service_Amazon_Ec2_Instance - */ - public function getAdapter() - { - return $this->ec2; - } - - /** - * Get last HTTP request - * - * @return string - */ - public function getLastHttpRequest() - { - return $this->ec2->getHttpClient()->getLastRequest(); - } - - /** - * Get the last HTTP response - * - * @return Zend_Http_Response - */ - public function getLastHttpResponse() - { - return $this->ec2->getHttpClient()->getLastResponse(); - } -} diff --git a/lib/Zend/Cloud/Infrastructure/Adapter/Rackspace.php b/lib/Zend/Cloud/Infrastructure/Adapter/Rackspace.php deleted file mode 100644 index c23f627e76f..00000000000 --- a/lib/Zend/Cloud/Infrastructure/Adapter/Rackspace.php +++ /dev/null @@ -1,483 +0,0 @@ - Zend_Cloud_Infrastructure_Instance::STATUS_RUNNING, - 'SUSPENDED' => Zend_Cloud_Infrastructure_Instance::STATUS_STOPPED, - 'BUILD' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, - 'REBUILD' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, - 'QUEUE_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'PREP_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, - 'VERIFY_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, - 'PASSWORD' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'RESCUE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'REBOOT' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING, - 'HARD_REBOOT' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING, - 'SHARE_IP' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'SHARE_IP_NO_CONFIG' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'DELETE_IP' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, - 'UNKNOWN' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING - ); - /** - * Constructor - * - * @param array|Zend_Config $options - * @return void - */ - public function __construct($options = array()) - { - if (is_object($options)) { - if (method_exists($options, 'toArray')) { - $options= $options->toArray(); - } elseif ($options instanceof Traversable) { - $options = iterator_to_array($options); - } - } - - if (empty($options) || !is_array($options)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Invalid options provided'); - } - - if (!isset($options[self::RACKSPACE_USER])) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Rackspace access user not specified!'); - } - - if (!isset($options[self::RACKSPACE_KEY])) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Rackspace access key not specified!'); - } - - $this->accessUser = $options[self::RACKSPACE_USER]; - $this->accessKey = $options[self::RACKSPACE_KEY]; - - if (isset($options[self::RACKSPACE_REGION])) { - switch ($options[self::RACKSPACE_REGION]) { - case self::RACKSPACE_ZONE_UK: - $this->region= Zend_Service_Rackspace_Servers::UK_AUTH_URL; - break; - case self::RACKSPACE_ZONE_USA: - $this->region = Zend_Service_Rackspace_Servers::US_AUTH_URL; - break; - default: - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The region is not valid'); - } - } else { - $this->region = Zend_Service_Rackspace_Servers::US_AUTH_URL; - } - - try { - $this->rackspace = new Zend_Service_Rackspace_Servers($this->accessUser,$this->accessKey, $this->region); - } catch (Exception $e) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Error on create: ' . $e->getMessage(), $e->getCode(), $e); - } - - if (isset($options[self::HTTP_ADAPTER])) { - $this->rackspace->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - - } - /** - * Convert the attributes of Rackspace server into attributes of Infrastructure - * - * @param array $attr - * @return array|boolean - */ - protected function convertAttributes($attr) - { - $result = array(); - if (!empty($attr) && is_array($attr)) { - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ID] = $attr['id']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_NAME] = $attr['name']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STATUS] = $this->mapStatus[$attr['status']]; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_IMAGEID] = $attr['imageId']; - if ($this->region==Zend_Service_Rackspace_Servers::US_AUTH_URL) { - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = self::RACKSPACE_ZONE_USA; - } else { - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = self::RACKSPACE_ZONE_UK; - } - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = $this->flavors[$attr['flavorId']]['ram']; - $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = $this->flavors[$attr['flavorId']]['disk']; - } - return $result; - } - /** - * Return a list of the available instancies - * - * @return InstanceList|boolean - */ - public function listInstances() - { - $this->adapterResult = $this->rackspace->listServers(true); - if ($this->adapterResult===false) { - return false; - } - $array= $this->adapterResult->toArray(); - $result = array(); - foreach ($array as $instance) { - $result[]= $this->convertAttributes($instance); - } - return new Zend_Cloud_Infrastructure_InstanceList($this, $result); - } - /** - * Return the status of an instance - * - * @param string - * @return string|boolean - */ - public function statusInstance($id) - { - $this->adapterResult = $this->rackspace->getServer($id); - if ($this->adapterResult===false) { - return false; - } - $array= $this->adapterResult->toArray(); - return $this->mapStatus[$array['status']]; - } - /** - * Return the public DNS name/Ip address of the instance - * - * @param string $id - * @return string|boolean - */ - public function publicDnsInstance($id) - { - $this->adapterResult = $this->rackspace->getServerPublicIp($id); - if (empty($this->adapterResult)) { - return false; - } - return $this->adapterResult[0]; - } - /** - * Reboot an instance - * - * @param string $id - * @return boolean - */ - public function rebootInstance($id) - { - return $this->rackspace->rebootServer($id,true); - } - /** - * Create a new instance - * - * @param string $name - * @param array $options - * @return Instance|boolean - */ - public function createInstance($name, $options) - { - if (empty($name)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the name of the instance'); - } - if (empty($options) || !is_array($options)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The options must be an array'); - } - // @todo create an generic abstract definition for an instance? - $metadata= array(); - if (isset($options['metadata'])) { - $metadata= $options['metadata']; - unset($options['metadata']); - } - $files= array(); - if (isset($options['files'])) { - $files= $options['files']; - unset($options['files']); - } - $options['name']= $name; - $this->adapterResult = $this->rackspace->createServer($options,$metadata,$files); - if ($this->adapterResult===false) { - return false; - } - return new Zend_Cloud_Infrastructure_Instance($this, $this->convertAttributes($this->adapterResult->toArray())); - } - /** - * Stop an instance - * - * @param string $id - * @return boolean - */ - public function stopInstance($id) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The stopInstance method is not implemented in the adapter'); - } - - /** - * Start an instance - * - * @param string $id - * @return boolean - */ - public function startInstance($id) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The startInstance method is not implemented in the adapter'); - } - - /** - * Destroy an instance - * - * @param string $id - * @return boolean - */ - public function destroyInstance($id) - { - $this->adapterResult= $this->rackspace->deleteServer($id); - return $this->adapterResult; - } - /** - * Return a list of all the available instance images - * - * @return ImageList|boolean - */ - public function imagesInstance() - { - $this->adapterResult = $this->rackspace->listImages(true); - if ($this->adapterResult===false) { - return false; - } - - $images= $this->adapterResult->toArray(); - $result= array(); - - foreach ($images as $image) { - if (strtolower($image['status'])==='active') { - if (strpos($image['name'],'Windows')!==false) { - $platform = Zend_Cloud_Infrastructure_Image::IMAGE_WINDOWS; - } else { - $platform = Zend_Cloud_Infrastructure_Image::IMAGE_LINUX; - } - if (strpos($image['name'],'x64')!==false) { - $arch = Zend_Cloud_Infrastructure_Image::ARCH_64BIT; - } else { - $arch = Zend_Cloud_Infrastructure_Image::ARCH_32BIT; - } - $result[]= array ( - Zend_Cloud_Infrastructure_Image::IMAGE_ID => $image['id'], - Zend_Cloud_Infrastructure_Image::IMAGE_NAME => $image['name'], - Zend_Cloud_Infrastructure_Image::IMAGE_DESCRIPTION => $image['name'], - Zend_Cloud_Infrastructure_Image::IMAGE_ARCHITECTURE => $arch, - Zend_Cloud_Infrastructure_Image::IMAGE_PLATFORM => $platform, - ); - } - } - return new Zend_Cloud_Infrastructure_ImageList($result,$this->adapterResult); - } - /** - * Return all the available zones - * - * @return array - */ - public function zonesInstance() - { - return array(self::RACKSPACE_ZONE_USA,self::RACKSPACE_ZONE_UK); - } - /** - * Return the system information about the $metric of an instance - * NOTE: it works only for Linux servers - * - * @param string $id - * @param string $metric - * @param null|array $options - * @return array|boolean - */ - public function monitorInstance($id, $metric, $options = null) - { - if (!function_exists("ssh2_connect")) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Monitor requires the PHP "SSH" extension (ext/ssh2)'); - } - if (empty($id)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the id of the instance to monitor'); - } - if (empty($metric)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must specify the metric to monitor'); - } - if (!in_array($metric,$this->validMetrics)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf('The metric "%s" is not valid', $metric)); - } - if (!empty($options) && !is_array($options)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The options must be an array'); - } - - switch ($metric) { - case Zend_Cloud_Infrastructure_Instance::MONITOR_CPU: - $cmd= 'top -b -n '.self::MONITOR_CPU_SAMPLES.' | grep \'Cpu\''; - break; - case Zend_Cloud_Infrastructure_Instance::MONITOR_RAM: - $cmd= 'top -b -n 1 | grep \'Mem\''; - break; - case Zend_Cloud_Infrastructure_Instance::MONITOR_DISK: - $cmd= 'df --total | grep total'; - break; - } - if (empty($cmd)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('The metric specified is not supported by the adapter'); - } - - $params= array( - Zend_Cloud_Infrastructure_Instance::SSH_USERNAME => $options['username'], - Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD => $options['password'] - ); - $exec_time= time(); - $result= $this->deployInstance($id,$params,$cmd); - - if (empty($result)) { - return false; - } - - $monitor = array(); - $num = 0; - $average = 0; - - $outputs= explode("\n",$result); - foreach ($outputs as $output) { - if (!empty($output)) { - switch ($metric) { - case Zend_Cloud_Infrastructure_Instance::MONITOR_CPU: - if (preg_match('/(\d+\.\d)%us/', $output,$match)) { - $usage = (float) $match[1]; - } - break; - case Zend_Cloud_Infrastructure_Instance::MONITOR_RAM: - if (preg_match('/(\d+)k total/', $output,$match)) { - $total = (integer) $match[1]; - } - if (preg_match('/(\d+)k used/', $output,$match)) { - $used = (integer) $match[1]; - } - if ($total>0) { - $usage= (float) $used/$total; - } - break; - case Zend_Cloud_Infrastructure_Instance::MONITOR_DISK: - if (preg_match('/(\d+)%/', $output,$match)) { - $usage = (float) $match[1]; - } - break; - } - - $monitor['series'][] = array ( - 'timestamp' => $exec_time, - 'value' => number_format($usage,2).'%' - ); - - $average += $usage; - $exec_time+= 60; // seconds - $num++; - } - } - - if ($num>0) { - $monitor['average'] = number_format($average/$num,2).'%'; - } - return $monitor; - } - /** - * Get the adapter - * - * @return Zend_Service_Rackspace_Servers - */ - public function getAdapter() - { - return $this->rackspace; - } - /** - * Get last HTTP request - * - * @return string - */ - public function getLastHttpRequest() - { - return $this->rackspace->getHttpClient()->getLastRequest(); - } - /** - * Get the last HTTP response - * - * @return Zend_Http_Response - */ - public function getLastHttpResponse() - { - return $this->rackspace->getHttpClient()->getLastResponse(); - } -} diff --git a/lib/Zend/Cloud/Infrastructure/Exception.php b/lib/Zend/Cloud/Infrastructure/Exception.php deleted file mode 100644 index 0f1a0700497..00000000000 --- a/lib/Zend/Cloud/Infrastructure/Exception.php +++ /dev/null @@ -1,25 +0,0 @@ -toArray(); - } elseif ($data instanceof Traversable) { - $data = iterator_to_array($data); - } - } - - if (empty($data) || !is_array($data)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You must pass an array of parameters'); - } - - foreach ($this->attributeRequired as $key) { - if (empty($data[$key])) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf( - 'The param "%s" is a required parameter for class %s', - $key, - __CLASS__ - )); - } - } - - $this->attributes = $data; - $this->adapter = $adapter; - } - - /** - * Get Attribute with a specific key - * - * @param array $data - * @return misc|boolean - */ - public function getAttribute($key) - { - if (!empty($this->attributes[$key])) { - return $this->attributes[$key]; - } - return false; - } - - /** - * Get all the attributes - * - * @return array - */ - public function getAttributes() - { - return $this->attributes; - } - - /** - * Get the image ID - * - * @return string - */ - public function getId() - { - return $this->attributes[self::IMAGE_ID]; - } - - /** - * Get the Owner ID - * - * @return string - */ - public function getOwnerId() - { - return $this->attributes[self::IMAGE_OWNERID]; - } - - /** - * Get the name - * - * @return string - */ - public function getName() - { - return $this->attributes[self::IMAGE_NAME]; - } - - /** - * Get the description - * - * @return string - */ - public function getDescription() - { - return $this->attributes[self::IMAGE_DESCRIPTION]; - } - - /** - * Get the platform - * - * @return string - */ - public function getPlatform() - { - return $this->attributes[self::IMAGE_PLATFORM]; - } - - /** - * Get the architecture - * - * @return string - */ - public function getArchitecture() - { - return $this->attributes[self::IMAGE_ARCHITECTURE]; - } -} diff --git a/lib/Zend/Cloud/Infrastructure/ImageList.php b/lib/Zend/Cloud/Infrastructure/ImageList.php deleted file mode 100644 index 7fea82495ea..00000000000 --- a/lib/Zend/Cloud/Infrastructure/ImageList.php +++ /dev/null @@ -1,218 +0,0 @@ -adapter = $adapter; - $this->constructFromArray($images); - } - - /** - * Transforms the Array to array of Instances - * - * @param array $list - * @return void - */ - protected function constructFromArray(array $list) - { - foreach ($list as $image) { - $this->addImage(new Zend_Cloud_Infrastructure_Image($image, $this->adapter)); - } - } - - /** - * Add an image - * - * @param Image - * @return ImageList - */ - protected function addImage(Zend_Cloud_Infrastructure_Image $image) - { - $this->images[] = $image; - return $this; - } - - /** - * Return number of images - * - * Implement Countable::count() - * - * @return int - */ - public function count() - { - return count($this->images); - } - - /** - * Return the current element - * - * Implement Iterator::current() - * - * @return Image - */ - public function current() - { - return $this->images[$this->iteratorKey]; - } - - /** - * Return the key of the current element - * - * Implement Iterator::key() - * - * @return int - */ - public function key() - { - return $this->iteratorKey; - } - - /** - * Move forward to next element - * - * Implement Iterator::next() - * - * @return void - */ - public function next() - { - $this->iteratorKey++; - } - - /** - * Rewind the Iterator to the first element - * - * Implement Iterator::rewind() - * - * @return void - */ - public function rewind() - { - $this->iteratorKey = 0; - } - - /** - * Check if there is a current element after calls to rewind() or next() - * - * Implement Iterator::valid() - * - * @return bool - */ - public function valid() - { - $numItems = $this->count(); - if ($numItems > 0 && $this->iteratorKey < $numItems) { - return true; - } - return false; - } - - /** - * Whether the offset exists - * - * Implement ArrayAccess::offsetExists() - * - * @param int $offset - * @return bool - */ - public function offsetExists($offset) - { - return ($offset < $this->count()); - } - - /** - * Return value at given offset - * - * Implement ArrayAccess::offsetGet() - * - * @param int $offset - * @throws Zend_Cloud_Infrastructure_Exception - * @return Image - */ - public function offsetGet($offset) - { - if (!$this->offsetExists($offset)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Illegal index'); - } - return $this->images[$offset]; - } - - /** - * Throws exception because all values are read-only - * - * Implement ArrayAccess::offsetSet() - * - * @param int $offset - * @param string $value - * @throws Zend_Cloud_Infrastructure_Exception - */ - public function offsetSet($offset, $value) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You are trying to set read-only property'); - } - - /** - * Throws exception because all values are read-only - * - * Implement ArrayAccess::offsetUnset() - * - * @param int $offset - * @throws Zend_Cloud_Infrastructure_Exception - */ - public function offsetUnset($offset) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You are trying to unset read-only property'); - } -} diff --git a/lib/Zend/Cloud/Infrastructure/Instance.php b/lib/Zend/Cloud/Infrastructure/Instance.php deleted file mode 100644 index 77f70648698..00000000000 --- a/lib/Zend/Cloud/Infrastructure/Instance.php +++ /dev/null @@ -1,320 +0,0 @@ -toArray(); - } elseif ($data instanceof Traversable) { - $data = iterator_to_array($data); - } - } - - if (empty($data) || !is_array($data)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception("You must pass an array of parameters"); - } - - foreach ($this->attributeRequired as $key) { - if (empty($data[$key])) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception(sprintf( - 'The param "%s" is a required param for %s', - $key, - __CLASS__ - )); - } - } - - $this->adapter = $adapter; - $this->attributes = $data; - } - - /** - * Get Attribute with a specific key - * - * @param array $data - * @return misc|false - */ - public function getAttribute($key) - { - if (!empty($this->attributes[$key])) { - return $this->attributes[$key]; - } - return false; - } - - /** - * Get all the attributes - * - * @return array - */ - public function getAttributes() - { - return $this->attributes; - } - - /** - * Get the instance's id - * - * @return string - */ - public function getId() - { - return $this->attributes[self::INSTANCE_ID]; - } - - /** - * Get the instance's image id - * - * @return string - */ - public function getImageId() - { - return $this->attributes[self::INSTANCE_IMAGEID]; - } - - /** - * Get the instance's name - * - * @return string - */ - public function getName() - { - return $this->attributes[self::INSTANCE_NAME]; - } - - /** - * Get the status of the instance - * - * @return string|boolean - */ - public function getStatus() - { - return $this->adapter->statusInstance($this->attributes[self::INSTANCE_ID]); - } - - /** - * Wait for status $status with a timeout of $timeout seconds - * - * @param string $status - * @param integer $timeout - * @return boolean - */ - public function waitStatus($status, $timeout = Adapter::TIMEOUT_STATUS_CHANGE) - { - return $this->adapter->waitStatusInstance($this->attributes[self::INSTANCE_ID], $status, $timeout); - } - - /** - * Get the public DNS of the instance - * - * @return string - */ - public function getPublicDns() - { - if (!isset($this->attributes[self::INSTANCE_PUBLICDNS])) { - $this->attributes[self::INSTANCE_PUBLICDNS] = $this->adapter->publicDnsInstance($this->attributes[self::INSTANCE_ID]); - } - return $this->attributes[self::INSTANCE_PUBLICDNS]; - } - - /** - * Get the instance's CPU - * - * @return string - */ - public function getCpu() - { - return $this->attributes[self::INSTANCE_CPU]; - } - - /** - * Get the instance's RAM size - * - * @return string - */ - public function getRamSize() - { - return $this->attributes[self::INSTANCE_RAM]; - } - - /** - * Get the instance's storage size - * - * @return string - */ - public function getStorageSize() - { - return $this->attributes[self::INSTANCE_STORAGE]; - } - - /** - * Get the instance's zone - * - * @return string - */ - public function getZone() - { - return $this->attributes[self::INSTANCE_ZONE]; - } - - /** - * Get the instance's launch time - * - * @return string - */ - public function getLaunchTime() - { - return $this->attributes[self::INSTANCE_LAUNCHTIME]; - } - - /** - * Reboot the instance - * - * @return boolean - */ - public function reboot() - { - return $this->adapter->rebootInstance($this->attributes[self::INSTANCE_ID]); - } - - /** - * Stop the instance - * - * @return boolean - */ - public function stop() - { - return $this->adapter->stopInstance($this->attributes[self::INSTANCE_ID]); - } - - /** - * Start the instance - * - * @return boolean - */ - public function start() - { - return $this->adapter->startInstance($this->attributes[self::INSTANCE_ID]); - } - - /** - * Destroy the instance - * - * @return boolean - */ - public function destroy() - { - return $this->adapter->destroyInstance($this->attributes[self::INSTANCE_ID]); - } - - /** - * Return the system informations about the $metric of an instance - * - * @param string $metric - * @param null|array $options - * @return array|boolean - */ - public function monitor($metric, $options = null) - { - return $this->adapter->monitorInstance($this->attributes[self::INSTANCE_ID], $metric, $options); - } - - /** - * Run arbitrary shell script on the instance - * - * @param array $param - * @param string|array $cmd - * @return string|array - */ - public function deploy($params, $cmd) - { - return $this->adapter->deployInstance($this->attributes[self::INSTANCE_ID], $params, $cmd); - } -} diff --git a/lib/Zend/Cloud/Infrastructure/InstanceList.php b/lib/Zend/Cloud/Infrastructure/InstanceList.php deleted file mode 100644 index 46fe895da3b..00000000000 --- a/lib/Zend/Cloud/Infrastructure/InstanceList.php +++ /dev/null @@ -1,219 +0,0 @@ -adapter = $adapter; - $this->constructFromArray($instances); - } - - /** - * Transforms the Array to array of Instances - * - * @param array $list - * @return void - */ - protected function constructFromArray(array $list) - { - foreach ($list as $instance) { - $this->addInstance(new Zend_Cloud_Infrastructure_Instance($this->adapter,$instance)); - } - } - - /** - * Add an instance - * - * @param Instance - * @return InstanceList - */ - protected function addInstance(Zend_Cloud_Infrastructure_Instance $instance) - { - $this->instances[] = $instance; - return $this; - } - - /** - * Return number of instances - * - * Implement Countable::count() - * - * @return int - */ - public function count() - { - return count($this->instances); - } - - /** - * Return the current element - * - * Implement Iterator::current() - * - * @return Instance - */ - public function current() - { - return $this->instances[$this->iteratorKey]; - } - - /** - * Return the key of the current element - * - * Implement Iterator::key() - * - * @return int - */ - public function key() - { - return $this->iteratorKey; - } - - /** - * Move forward to next element - * - * Implement Iterator::next() - * - * @return void - */ - public function next() - { - $this->iteratorKey++; - } - - /** - * Rewind the Iterator to the first element - * - * Implement Iterator::rewind() - * - * @return void - */ - public function rewind() - { - $this->iteratorKey = 0; - } - - /** - * Check if there is a current element after calls to rewind() or next() - * - * Implement Iterator::valid() - * - * @return bool - */ - public function valid() - { - $numItems = $this->count(); - if ($numItems > 0 && $this->iteratorKey < $numItems) { - return true; - } - return false; - } - - /** - * Whether the offset exists - * - * Implement ArrayAccess::offsetExists() - * - * @param int $offset - * @return bool - */ - public function offsetExists($offset) - { - return ($offset < $this->count()); - } - - /** - * Return value at given offset - * - * Implement ArrayAccess::offsetGet() - * - * @param int $offset - * @return Instance - * @throws Zend_Cloud_Infrastructure_Exception - */ - public function offsetGet($offset) - { - if (!$this->offsetExists($offset)) { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('Illegal index'); - } - return $this->instances[$offset]; - } - - /** - * Throws exception because all values are read-only - * - * Implement ArrayAccess::offsetSet() - * - * @param int $offset - * @param string $value - * @throws Zend_Cloud_Infrastructure_Exception - */ - public function offsetSet($offset, $value) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You are trying to set read-only property'); - } - - /** - * Throws exception because all values are read-only - * - * Implement ArrayAccess::offsetUnset() - * - * @param int $offset - * @throws Zend_Cloud_Infrastructure_Exception - */ - public function offsetUnset($offset) - { - #require_once 'Zend/Cloud/Infrastructure/Exception.php'; - throw new Zend_Cloud_Infrastructure_Exception('You are trying to unset read-only property'); - } -} diff --git a/lib/Zend/Cloud/OperationNotAvailableException.php b/lib/Zend/Cloud/OperationNotAvailableException.php deleted file mode 100644 index b447b0d8592..00000000000 --- a/lib/Zend/Cloud/OperationNotAvailableException.php +++ /dev/null @@ -1,34 +0,0 @@ -_messageClass = (string) $class; - return $this; - } - - /** - * Get class to use for message objects - * - * @return string - */ - public function getMessageClass() - { - return $this->_messageClass; - } - - /** - * Set class to use for message collection objects - * - * @param string $class - * @return Zend_Cloud_QueueService_Adapter_AbstractAdapter - */ - public function setMessageSetClass($class) - { - $this->_messageSetClass = (string) $class; - return $this; - } - - /** - * Get class to use for message collection objects - * - * @return string - */ - public function getMessageSetClass() - { - return $this->_messageSetClass; - } -} diff --git a/lib/Zend/Cloud/QueueService/Adapter/Sqs.php b/lib/Zend/Cloud/QueueService/Adapter/Sqs.php deleted file mode 100644 index 4457c497620..00000000000 --- a/lib/Zend/Cloud/QueueService/Adapter/Sqs.php +++ /dev/null @@ -1,278 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_QueueService_Exception('Invalid options provided'); - } - - if (isset($options[self::MESSAGE_CLASS])) { - $this->setMessageClass($options[self::MESSAGE_CLASS]); - } - - if (isset($options[self::MESSAGESET_CLASS])) { - $this->setMessageSetClass($options[self::MESSAGESET_CLASS]); - } - - try { - $this->_sqs = new Zend_Service_Amazon_Sqs( - $options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY] - ); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e); - } - - if(isset($options[self::HTTP_ADAPTER])) { - $this->_sqs->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - } - - /** - * Create a queue. Returns the ID of the created queue (typically the URL). - * It may take some time to create the queue. Check your vendor's - * documentation for details. - * - * @param string $name - * @param array $options - * @return string Queue ID (typically URL) - */ - public function createQueue($name, $options = null) - { - try { - return $this->_sqs->create($name, $options[self::CREATE_TIMEOUT]); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete a queue. All messages in the queue will also be deleted. - * - * @param string $queueId - * @param array $options - * @return boolean true if successful, false otherwise - */ - public function deleteQueue($queueId, $options = null) -{ - try { - return $this->_sqs->delete($queueId); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * List all queues. - * - * @param array $options - * @return array Queue IDs - */ - public function listQueues($options = null) - { - try { - return $this->_sqs->getQueues(); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on listing queues: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get a key/value array of metadata for the given queue. - * - * @param string $queueId - * @param array $options - * @return array - */ - public function fetchQueueMetadata($queueId, $options = null) - { - try { - // TODO: ZF-9050 Fix the SQS client library in trunk to return all attribute values - $attributes = $this->_sqs->getAttribute($queueId, 'All'); - if(is_array($attributes)) { - return $attributes; - } else { - return array('All' => $this->_sqs->getAttribute($queueId, 'All')); - } - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on fetching queue metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store a key/value array of metadata for the specified queue. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. Some adapters may not support this method. - * - * @param array $metadata - * @param string $queueId - * @param array $options - * @return void - */ - public function storeQueueMetadata($queueId, $metadata, $options = null) - { - // TODO Add support for SetQueueAttributes to client library - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Amazon SQS doesn\'t currently support storing metadata'); - } - - /** - * Send a message to the specified queue. - * - * @param string $message - * @param string $queueId - * @param array $options - * @return string Message ID - */ - public function sendMessage($queueId, $message, $options = null) - { - try { - return $this->_sqs->send($queueId, $message); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on sending message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Recieve at most $max messages from the specified queue and return the - * message IDs for messages recieved. - * - * @param string $queueId - * @param int $max - * @param array $options - * @return array - */ - public function receiveMessages($queueId, $max = 1, $options = null) - { - try { - return $this->_makeMessages($this->_sqs->receive($queueId, $max, $options[self::VISIBILITY_TIMEOUT])); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on recieving messages: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Create Zend_Cloud_QueueService_Message array for - * Sqs messages. - * - * @param array $messages - * @return Zend_Cloud_QueueService_Message[] - */ - protected function _makeMessages($messages) - { - $messageClass = $this->getMessageClass(); - $setClass = $this->getMessageSetClass(); - $result = array(); - foreach($messages as $message) { - $result[] = new $messageClass($message['body'], $message); - } - return new $setClass($result); - } - - /** - * Delete the specified message from the specified queue. - * - * @param string $queueId - * @param Zend_Cloud_QueueService_Message $message - * @param array $options - * @return void - */ - public function deleteMessage($queueId, $message, $options = null) - { - try { - if($message instanceof Zend_Cloud_QueueService_Message) { - $message = $message->getMessage(); - } - $messageId = $message['handle']; - return $this->_sqs->deleteMessage($queueId, $messageId); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on deleting a message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Peek at the messages from the specified queue without removing them. - * - * @param string $queueId - * @param int $num How many messages - * @param array $options - * @return Zend_Cloud_QueueService_Message[] - */ - public function peekMessages($queueId, $num = 1, $options = null) - { - try { - return $this->_makeMessages($this->_sqs->receive($queueId, $num, 0)); - } catch(Zend_Service_Amazon_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on peeking messages: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get SQS implementation - * @return Zend_Service_Amazon_Sqs - */ - public function getClient() - { - return $this->_sqs; - } -} diff --git a/lib/Zend/Cloud/QueueService/Adapter/WindowsAzure.php b/lib/Zend/Cloud/QueueService/Adapter/WindowsAzure.php deleted file mode 100644 index cd7eef2010e..00000000000 --- a/lib/Zend/Cloud/QueueService/Adapter/WindowsAzure.php +++ /dev/null @@ -1,343 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_QueueService_Exception('Invalid options provided'); - } - - if (isset($options[self::MESSAGE_CLASS])) { - $this->setMessageClass($options[self::MESSAGE_CLASS]); - } - - if (isset($options[self::MESSAGESET_CLASS])) { - $this->setMessageSetClass($options[self::MESSAGESET_CLASS]); - } - - // Build Zend_Service_WindowsAzure_Storage_Blob instance - if (!isset($options[self::HOST])) { - $host = self::DEFAULT_HOST; - } else { - $host = $options[self::HOST]; - } - if (! isset($options[self::ACCOUNT_NAME])) { - throw new Zend_Cloud_Storage_Exception('No Windows Azure account name provided.'); - } - if (! isset($options[self::ACCOUNT_KEY])) { - throw new Zend_Cloud_Storage_Exception('No Windows Azure account key provided.'); - } - try { - // TODO: support $usePathStyleUri and $retryPolicy - $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Queue( - $host, $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]); - // Parse other options - if (! empty($options[self::PROXY_HOST])) { - $proxyHost = $options[self::PROXY_HOST]; - $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080; - $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : ''; - $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials); - } - if (isset($options[self::HTTP_ADAPTER])) { - $this->_storageClient->setHttpClientChannel($httpAdapter); - } - } catch(Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e); - } - - } - - /** - * Create a queue. Returns the ID of the created queue (typically the URL). - * It may take some time to create the queue. Check your vendor's - * documentation for details. - * - * @param string $name - * @param array $options - * @return string Queue ID (typically URL) - */ - public function createQueue($name, $options = null) - { - try { - $queue = $this->_storageClient->createQueue($name, $options); - return $queue->Name; - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete a queue. All messages in the queue will also be deleted. - * - * @param string $queueId - * @param array $options - * @return boolean true if successful, false otherwise - */ - public function deleteQueue($queueId, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - return $this->_storageClient->deleteQueue($queueId); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * List all queues. - * - * @param array $options - * @return array Queue IDs - */ - public function listQueues($options = null) - { - $prefix = $maxResults = null; - if (is_array($options)) { - isset($options[self::LIST_PREFIX]) ? $prefix = $options[self::LIST_PREFIX] : null; - isset($options[self::LIST_MAX_RESULTS]) ? $maxResults = $options[self::LIST_MAX_RESULTS] : null; - } - try { - $queues = $this->_storageClient->listQueues($prefix, $maxResults); - $result = array(); - foreach ($queues as $queue) { - $result[] = $queue->Name; - } - return $result; - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on listing queues: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get a key/value array of metadata for the given queue. - * - * @param string $queueId - * @param array $options - * @return array - */ - public function fetchQueueMetadata($queueId, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - return $this->_storageClient->getQueueMetadata($queueId); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on fetching queue metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store a key/value array of metadata for the specified queue. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. Some adapters may not support this method. - * - * @param string $queueId - * @param array $metadata - * @param array $options - * @return void - */ - public function storeQueueMetadata($queueId, $metadata, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - return $this->_storageClient->setQueueMetadata($queueId, $metadata); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on setting queue metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Send a message to the specified queue. - * - * @param string $queueId - * @param string $message - * @param array $options - * @return string Message ID - */ - public function sendMessage($queueId, $message, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - return $this->_storageClient->putMessage( - $queueId, $message, $options[self::MESSAGE_TTL] - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on sending message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Recieve at most $max messages from the specified queue and return the - * message IDs for messages recieved. - * - * @param string $queueId - * @param int $max - * @param array $options - * @return Zend_Cloud_QueueService_Message[] - */ - public function receiveMessages($queueId, $max = 1, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - if (isset($options[self::VISIBILITY_TIMEOUT])) { - $visibility = $options[self::VISIBILITY_TIMEOUT]; - } else { - $visibility = self::DEFAULT_TIMEOUT; - } - return $this->_makeMessages($this->_storageClient->getMessages($queueId, $max, $visibility, false)); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on recieving messages: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Create Zend_Cloud_QueueService_Message array for - * Azure messages. - * - * @param array $messages - * @return Zend_Cloud_QueueService_Message[] - */ - protected function _makeMessages($messages) - { - $messageClass = $this->getMessageClass(); - $setClass = $this->getMessageSetClass(); - $result = array(); - foreach ($messages as $message) { - $result[] = new $messageClass($message->MessageText, $message); - } - return new $setClass($result); - } - - /** - * Delete the specified message from the specified queue. - * - * @param string $queueId - * @param Zend_Cloud_QueueService_Message $message Message ID or message - * @param array $options - * @return void - */ - public function deleteMessage($queueId, $message, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - if ($message instanceof Zend_Cloud_QueueService_Message) { - $message = $message->getMessage(); - } - if ($message instanceof Zend_Service_WindowsAzure_Storage_QueueMessage) { - return $this->_storageClient->deleteMessage($queueId, $message); - } else { - throw new Zend_Cloud_QueueService_Exception('Cannot delete the message: message object required'); - } - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on deleting a message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Peek at the messages from the specified queue without removing them. - * - * @param string $queueId - * @param int $num How many messages - * @param array $options - * @return Zend_Cloud_QueueService_Message[] - */ - public function peekMessages($queueId, $num = 1, $options = null) - { - try { - if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) { - $queueId = $queueId->Name; - } - return $this->_makeMessages($this->_storageClient->peekMessages($queueId, $num)); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on peeking messages: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get Azure implementation - * @return Zend_Service_Azure_Storage_Queue - */ - public function getClient() - { - return $this->_storageClient; - } -} diff --git a/lib/Zend/Cloud/QueueService/Adapter/ZendQueue.php b/lib/Zend/Cloud/QueueService/Adapter/ZendQueue.php deleted file mode 100644 index 0672695e12b..00000000000 --- a/lib/Zend/Cloud/QueueService/Adapter/ZendQueue.php +++ /dev/null @@ -1,301 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_QueueService_Exception('Invalid options provided'); - } - - if (isset($options[self::MESSAGE_CLASS])) { - $this->setMessageClass($options[self::MESSAGE_CLASS]); - } - - if (isset($options[self::MESSAGESET_CLASS])) { - $this->setMessageSetClass($options[self::MESSAGESET_CLASS]); - } - - // Build Zend_Service_WindowsAzure_Storage_Blob instance - if (!isset($options[self::ADAPTER])) { - throw new Zend_Cloud_QueueService_Exception('No Zend_Queue adapter provided'); - } else { - $adapter = $options[self::ADAPTER]; - unset($options[self::ADAPTER]); - } - try { - $this->_queue = new Zend_Queue($adapter, $options); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Create a queue. Returns the ID of the created queue (typically the URL). - * It may take some time to create the queue. Check your vendor's - * documentation for details. - * - * @param string $name - * @param array $options - * @return string Queue ID (typically URL) - */ - public function createQueue($name, $options = null) - { - try { - $this->_queues[$name] = $this->_queue->createQueue($name, isset($options[Zend_Queue::TIMEOUT])?$options[Zend_Queue::TIMEOUT]:null); - return $name; - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue creation: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete a queue. All messages in the queue will also be deleted. - * - * @param string $queueId - * @param array $options - * @return boolean true if successful, false otherwise - */ - public function deleteQueue($queueId, $options = null) - { - if (!isset($this->_queues[$queueId])) { - return false; - } - try { - if ($this->_queues[$queueId]->deleteQueue()) { - unset($this->_queues[$queueId]); - return true; - } - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on queue deletion: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * List all queues. - * - * @param array $options - * @return array Queue IDs - */ - public function listQueues($options = null) - { - try { - return $this->_queue->getQueues(); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on listing queues: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get a key/value array of metadata for the given queue. - * - * @param string $queueId - * @param array $options - * @return array - */ - public function fetchQueueMetadata($queueId, $options = null) - { - if (!isset($this->_queues[$queueId])) { - return false; - } - try { - return $this->_queues[$queueId]->getOptions(); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on fetching queue metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store a key/value array of metadata for the specified queue. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. Some adapters may not support this method. - * - * @param string $queueId - * @param array $metadata - * @param array $options - * @return void - */ - public function storeQueueMetadata($queueId, $metadata, $options = null) - { - if (!isset($this->_queues[$queueId])) { - throw new Zend_Cloud_QueueService_Exception("No such queue: $queueId"); - } - try { - return $this->_queues[$queueId]->setOptions($metadata); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on setting queue metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Send a message to the specified queue. - * - * @param string $queueId - * @param string $message - * @param array $options - * @return string Message ID - */ - public function sendMessage($queueId, $message, $options = null) - { - if (!isset($this->_queues[$queueId])) { - throw new Zend_Cloud_QueueService_Exception("No such queue: $queueId"); - } - try { - return $this->_queues[$queueId]->send($message); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on sending message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Recieve at most $max messages from the specified queue and return the - * message IDs for messages recieved. - * - * @param string $queueId - * @param int $max - * @param array $options - * @return array - */ - public function receiveMessages($queueId, $max = 1, $options = null) - { - if (!isset($this->_queues[$queueId])) { - throw new Zend_Cloud_QueueService_Exception("No such queue: $queueId"); - } - try { - $res = $this->_queues[$queueId]->receive($max, isset($options[Zend_Queue::TIMEOUT])?$options[Zend_Queue::TIMEOUT]:null); - if ($res instanceof Iterator) { - return $this->_makeMessages($res); - } else { - return $this->_makeMessages(array($res)); - } - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on recieving messages: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Create Zend_Cloud_QueueService_Message array for - * Azure messages. - * - * @param array $messages - * @return Zend_Cloud_QueueService_Message[] - */ - protected function _makeMessages($messages) - { - $messageClass = $this->getMessageClass(); - $setClass = $this->getMessageSetClass(); - $result = array(); - foreach ($messages as $message) { - $result[] = new $messageClass($message->body, $message); - } - return new $setClass($result); - } - - /** - * Delete the specified message from the specified queue. - * - * @param string $queueId - * @param Zend_Cloud_QueueService_Message $message Message ID or message - * @param array $options - * @return void - */ - public function deleteMessage($queueId, $message, $options = null) - { - if (!isset($this->_queues[$queueId])) { - throw new Zend_Cloud_QueueService_Exception("No such queue: $queueId"); - } - try { - if ($message instanceof Zend_Cloud_QueueService_Message) { - $message = $message->getMessage(); - } - if (!($message instanceof Zend_Queue_Message)) { - throw new Zend_Cloud_QueueService_Exception('Cannot delete the message: Zend_Queue_Message object required'); - } - - return $this->_queues[$queueId]->deleteMessage($message); - } catch (Zend_Queue_Exception $e) { - throw new Zend_Cloud_QueueService_Exception('Error on deleting a message: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Peek at the messages from the specified queue without removing them. - * - * @param string $queueId - * @param int $num How many messages - * @param array $options - * @return Zend_Cloud_QueueService_Message[] - */ - public function peekMessages($queueId, $num = 1, $options = null) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('ZendQueue doesn\'t currently support message peeking'); - } - - /** - * Get Azure implementation - * @return Zend_Queue - */ - public function getClient() - { - return $this->_queue; - } -} diff --git a/lib/Zend/Cloud/QueueService/Exception.php b/lib/Zend/Cloud/QueueService/Exception.php deleted file mode 100644 index 54882cad293..00000000000 --- a/lib/Zend/Cloud/QueueService/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_body = $body; - $this->_clientMessage = $message; - } - - /** - * Get the message body - * @return string - */ - public function getBody() - { - return $this->_body; - } - - /** - * Get the original adapter-specific message - */ - public function getMessage() - { - return $this->_clientMessage; - } -} diff --git a/lib/Zend/Cloud/QueueService/MessageSet.php b/lib/Zend/Cloud/QueueService/MessageSet.php deleted file mode 100644 index d80e935ed2e..00000000000 --- a/lib/Zend/Cloud/QueueService/MessageSet.php +++ /dev/null @@ -1,68 +0,0 @@ -_messageCount = count($messages); - $this->_messages = new ArrayIterator($messages); - } - - /** - * Countable: number of messages in collection - * - * @return int - */ - public function count() - { - return $this->_messageCount; - } - - /** - * IteratorAggregate: return iterable object - * - * @return Traversable - */ - public function getIterator() - { - return $this->_messages; - } -} diff --git a/lib/Zend/Cloud/StorageService/Adapter.php b/lib/Zend/Cloud/StorageService/Adapter.php deleted file mode 100644 index d494ca05243..00000000000 --- a/lib/Zend/Cloud/StorageService/Adapter.php +++ /dev/null @@ -1,145 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_StorageService_Exception('Invalid options provided'); - } - - if (isset($options[self::LOCAL_DIRECTORY])) { - $this->_directory = $options[self::LOCAL_DIRECTORY]; - } else { - $this->_directory = realpath(sys_get_temp_dir()); - } - } - - /** - * Get an item from the storage service. - * - * TODO: Support streaming - * - * @param string $path - * @param array $options - * @return false|string - */ - public function fetchItem($path, $options = array()) - { - $filepath = $this->_getFullPath($path); - $path = realpath($filepath); - - if (!$path || !file_exists($path)) { - return false; - } - - return file_get_contents($path); - } - - /** - * Store an item in the storage service. - * - * WARNING: This operation overwrites any item that is located at - * $destinationPath. - * - * @TODO Support streams - * - * @param string $destinationPath - * @param mixed $data - * @param array $options - * @return void - */ - public function storeItem($destinationPath, $data, $options = array()) - { - $path = $this->_getFullPath($destinationPath); - file_put_contents($path, $data); - chmod($path, 0775); - } - - /** - * Delete an item in the storage service. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteItem($path, $options = array()) - { - if (!isset($path)) { - return; - } - - $filepath = $this->_getFullPath($path); - if (file_exists($filepath)) { - unlink($filepath); - } - } - - /** - * Copy an item in the storage service to a given path. - * - * WARNING: This operation is *very* expensive for services that do not - * support copying an item natively. - * - * @TODO Support streams for those services that don't support natively - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function copyItem($sourcePath, $destinationPath, $options = array()) - { - copy($this->_getFullPath($sourcePath), $this->_getFullPath($destinationPath)); - } - - /** - * Move an item in the storage service to a given path. - * - * WARNING: This operation is *very* expensive for services that do not - * support moving an item natively. - * - * @TODO Support streams for those services that don't support natively - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function moveItem($sourcePath, $destinationPath, $options = array()) - { - rename($this->_getFullPath($sourcePath), $this->_getFullPath($destinationPath)); - } - - /** - * Rename an item in the storage service to a given name. - * - * - * @param string $path - * @param string $name - * @param array $options - * @return void - */ - public function renameItem($path, $name, $options = null) - { - rename( - $this->_getFullPath($path), - dirname($this->_getFullPath($path)) . DIRECTORY_SEPARATOR . $name - ); - } - - /** - * List items in the given directory in the storage service - * - * The $path must be a directory - * - * - * @param string $path Must be a directory - * @param array $options - * @return array A list of item names - */ - public function listItems($path, $options = null) - { - $listing = scandir($this->_getFullPath($path)); - - // Remove the hidden navigation directories - $listing = array_diff($listing, array('.', '..')); - - return $listing; - } - - /** - * Get a key/value array of metadata for the given path. - * - * @param string $path - * @param array $options - * @return array - */ - public function fetchMetadata($path, $options = array()) - { - $fullPath = $this->_getFullPath($path); - $metadata = null; - if (file_exists($fullPath)) { - $metadata = stat(realpath($fullPath)); - } - - return isset($metadata) ? $metadata : false; - } - - /** - * Store a key/value array of metadata at the given path. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. - * - * @param string $destinationPath - * @param array $options - * @return void - */ - public function storeMetadata($destinationPath, $metadata, $options = array()) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Storing metadata not implemented'); - } - - /** - * Delete a key/value array of metadata at the given path. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteMetadata($path) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Deleting metadata not implemented'); - } - - /** - * Return the full path for the file. - * - * @param string $path - * @return string - */ - private function _getFullPath($path) - { - return $this->_directory . DIRECTORY_SEPARATOR . $path; - } - - /** - * Get the concrete client. - * @return strings - */ - public function getClient() - { - return $this->_directory; - } -} diff --git a/lib/Zend/Cloud/StorageService/Adapter/Rackspace.php b/lib/Zend/Cloud/StorageService/Adapter/Rackspace.php deleted file mode 100644 index bdc69c2557f..00000000000 --- a/lib/Zend/Cloud/StorageService/Adapter/Rackspace.php +++ /dev/null @@ -1,332 +0,0 @@ -toArray(); - } - - if (!is_array($options) || empty($options)) { - throw new Zend_Cloud_StorageService_Exception('Invalid options provided'); - } - - try { - $this->_rackspace = new Zend_Service_Rackspace_Files($options[self::USER], $options[self::API_KEY]); - } catch (Zend_Service_Rackspace_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e); - } - - if (isset($options[self::HTTP_ADAPTER])) { - $this->_rackspace->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - if (!empty($options[self::REMOTE_CONTAINER])) { - $this->_container = $options[self::REMOTE_CONTAINER]; - } - } - - /** - * Get an item from the storage service. - * - * @param string $path - * @param array $options - * @return mixed - */ - public function fetchItem($path, $options = null) - { - $item = $this->_rackspace->getObject($this->_container,$path, $options); - if (!$this->_rackspace->isSuccessful() && ($this->_rackspace->getErrorCode()!='404')) { - throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$this->_rackspace->getErrorMsg()); - } - if (!empty($item)) { - return $item->getContent(); - } else { - return false; - } - } - - /** - * Store an item in the storage service. - * - * @param string $destinationPath - * @param mixed $data - * @param array $options - * @return void - */ - public function storeItem($destinationPath, $data, $options = null) - { - $this->_rackspace->storeObject($this->_container,$destinationPath,$data,$options); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on store: '.$this->_rackspace->getErrorMsg()); - } - } - - /** - * Delete an item in the storage service. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteItem($path, $options = null) - { - $this->_rackspace->deleteObject($this->_container,$path); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$this->_rackspace->getErrorMsg()); - } - } - - /** - * Copy an item in the storage service to a given path. - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function copyItem($sourcePath, $destinationPath, $options = null) - { - $this->_rackspace->copyObject($this->_container,$sourcePath,$this->_container,$destinationPath,$options); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$this->_rackspace->getErrorMsg()); - } - } - - /** - * Move an item in the storage service to a given path. - * WARNING: This operation is *very* expensive for services that do not - * support moving an item natively. - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function moveItem($sourcePath, $destinationPath, $options = null) - { - try { - $this->copyItem($sourcePath, $destinationPath, $options); - } catch (Zend_Service_Rackspace_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage()); - } - try { - $this->deleteItem($sourcePath); - } catch (Zend_Service_Rackspace_Exception $e) { - $this->deleteItem($destinationPath); - throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage()); - } - } - - /** - * Rename an item in the storage service to a given name. - * - * @param string $path - * @param string $name - * @param array $options - * @return void - */ - public function renameItem($path, $name, $options = null) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Renaming not implemented'); - } - - /** - * Get a key/value array of metadata for the given path. - * - * @param string $path - * @param array $options - * @return array An associative array of key/value pairs specifying the metadata for this object. - * If no metadata exists, an empty array is returned. - */ - public function fetchMetadata($path, $options = null) - { - $result = $this->_rackspace->getMetadataObject($this->_container,$path); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on fetch metadata: '.$this->_rackspace->getErrorMsg()); - } - $metadata = array(); - if (isset($result['metadata'])) { - $metadata = $result['metadata']; - } - // delete the self::DELETE_METADATA_KEY - this is a trick to remove all - // the metadata information of an object (see deleteMetadata). - // Rackspace doesn't have an API to remove the metadata of an object - unset($metadata[self::DELETE_METADATA_KEY]); - return $metadata; - } - - /** - * Store a key/value array of metadata at the given path. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. - * - * @param string $destinationPath - * @param array $metadata associative array specifying the key/value pairs for the metadata. - * @param array $options - * @return void - */ - public function storeMetadata($destinationPath, $metadata, $options = null) - { - $this->_rackspace->setMetadataObject($this->_container, $destinationPath, $metadata); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$this->_rackspace->getErrorMsg()); - } - } - - /** - * Delete a key/value array of metadata at the given path. - * - * @param string $path - * @param array $metadata - An associative array specifying the key/value pairs for the metadata - * to be deleted. If null, all metadata associated with the object will - * be deleted. - * @param array $options - * @return void - */ - public function deleteMetadata($path, $metadata = null, $options = null) - { - if (empty($metadata)) { - $newMetadata = array(self::DELETE_METADATA_KEY => true); - try { - $this->storeMetadata($path, $newMetadata); - } catch (Zend_Service_Rackspace_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage()); - } - } else { - try { - $oldMetadata = $this->fetchMetadata($path); - } catch (Zend_Service_Rackspace_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage()); - } - $newMetadata = array_diff_assoc($oldMetadata, $metadata); - try { - $this->storeMetadata($path, $newMetadata); - } catch (Zend_Service_Rackspace_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage()); - } - } - } - - /* - * Recursively traverse all the folders and build an array that contains - * the path names for each folder. - * - * @param string $path folder path to get the list of folders from. - * @param array& $resultArray reference to the array that contains the path names - * for each folder. - * @return void - */ - private function getAllFolders($path, &$resultArray) - { - if (!empty($path)) { - $options = array ( - 'prefix' => $path - ); - } - $files = $this->_rackspace->getObjects($this->_container,$options); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on get all folders: '.$this->_rackspace->getErrorMsg()); - } - $resultArray = array(); - foreach ($files as $file) { - $resultArray[dirname($file->getName())] = true; - } - $resultArray = array_keys($resultArray); - } - - /** - * Return an array of the items contained in the given path. The items - * returned are the files or objects that in the specified path. - * - * @param string $path - * @param array $options - * @return array - */ - public function listItems($path, $options = null) - { - if (!empty($path)) { - $options = array ( - 'prefix' => $path - ); - } - - $files = $this->_rackspace->getObjects($this->_container,$options); - if (!$this->_rackspace->isSuccessful()) { - throw new Zend_Cloud_StorageService_Exception('Error on list items: '.$this->_rackspace->getErrorMsg()); - } - $resultArray = array(); - if (!empty($files)) { - foreach ($files as $file) { - $resultArray[] = $file->getName(); - } - } - return $resultArray; - } - - /** - * Get the concrete client. - * - * @return Zend_Service_Rackspace_File - */ - public function getClient() - { - return $this->_rackspace; - } -} diff --git a/lib/Zend/Cloud/StorageService/Adapter/S3.php b/lib/Zend/Cloud/StorageService/Adapter/S3.php deleted file mode 100644 index 32f474d55aa..00000000000 --- a/lib/Zend/Cloud/StorageService/Adapter/S3.php +++ /dev/null @@ -1,332 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_StorageService_Exception('Invalid options provided'); - } - - if (!isset($options[self::AWS_ACCESS_KEY]) || !isset($options[self::AWS_SECRET_KEY])) { - throw new Zend_Cloud_StorageService_Exception('AWS keys not specified!'); - } - - try { - $this->_s3 = new Zend_Service_Amazon_S3($options[self::AWS_ACCESS_KEY], - $options[self::AWS_SECRET_KEY]); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e); - } - - if (isset($options[self::HTTP_ADAPTER])) { - $this->_s3->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); - } - - if (isset($options[self::BUCKET_NAME])) { - $this->_defaultBucketName = $options[self::BUCKET_NAME]; - } - - if (isset($options[self::BUCKET_AS_DOMAIN])) { - $this->_defaultBucketAsDomain = $options[self::BUCKET_AS_DOMAIN]; - } - } - - /** - * Get an item from the storage service. - * - * @TODO Support streams - * - * @param string $path - * @param array $options - * @return string - */ - public function fetchItem($path, $options = array()) - { - $fullPath = $this->_getFullPath($path, $options); - try { - if (!empty($options[self::FETCH_STREAM])) { - return $this->_s3->getObjectStream($fullPath, $options[self::FETCH_STREAM]); - } else { - return $this->_s3->getObject($fullPath); - } - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store an item in the storage service. - * - * WARNING: This operation overwrites any item that is located at - * $destinationPath. - * - * @TODO Support streams - * - * @param string $destinationPath - * @param string|resource $data - * @param array $options - * @return void - */ - public function storeItem($destinationPath, $data, $options = array()) - { - try { - $fullPath = $this->_getFullPath($destinationPath, $options); - return $this->_s3->putObject( - $fullPath, - $data, - empty($options[self::METADATA]) ? null : $options[self::METADATA] - ); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Delete an item in the storage service. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteItem($path, $options = array()) - { - try { - $this->_s3->removeObject($this->_getFullPath($path, $options)); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Copy an item in the storage service to a given path. - * - * WARNING: This operation is *very* expensive for services that do not - * support copying an item natively. - * - * @TODO Support streams for those services that don't support natively - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function copyItem($sourcePath, $destinationPath, $options = array()) - { - try { - $fullSourcePath = $this->_getFullPath($sourcePath, $options); - $fullDestPath = $this->_getFullPath($destinationPath, $options); - return $this->_s3->copyObject( - $fullSourcePath, - $fullDestPath, - empty($options[self::METADATA]) ? null : $options[self::METADATA] - ); - - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Move an item in the storage service to a given path. - * - * @TODO Support streams for those services that don't support natively - * - * @param string $sourcePath - * @param string $destination path - * @param array $options - * @return void - */ - public function moveItem($sourcePath, $destinationPath, $options = array()) - { - try { - $fullSourcePath = $this->_getFullPath($sourcePath, $options); - $fullDestPath = $this->_getFullPath($destinationPath, $options); - return $this->_s3->moveObject( - $fullSourcePath, - $fullDestPath, - empty($options[self::METADATA]) ? null : $options[self::METADATA] - ); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Rename an item in the storage service to a given name. - * - * - * @param string $path - * @param string $name - * @param array $options - * @return void - */ - public function renameItem($path, $name, $options = null) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Rename not implemented'); - } - - /** - * List items in the given directory in the storage service - * - * The $path must be a directory - * - * - * @param string $path Must be a directory - * @param array $options - * @return array A list of item names - */ - public function listItems($path, $options = null) - { - try { - // TODO Support 'prefix' parameter for Zend_Service_Amazon_S3::getObjectsByBucket() - return $this->_s3->getObjectsByBucket($this->_defaultBucketName); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get a key/value array of metadata for the given path. - * - * @param string $path - * @param array $options - * @return array - */ - public function fetchMetadata($path, $options = array()) - { - try { - return $this->_s3->getInfo($this->_getFullPath($path, $options)); - } catch (Zend_Service_Amazon_S3_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store a key/value array of metadata at the given path. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. - * - * @param string $destinationPath - * @param array $options - * @return void - */ - public function storeMetadata($destinationPath, $metadata, $options = array()) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Storing separate metadata is not supported, use storeItem() with \'metadata\' option key'); - } - - /** - * Delete a key/value array of metadata at the given path. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteMetadata($path) - { - #require_once 'Zend/Cloud/OperationNotAvailableException.php'; - throw new Zend_Cloud_OperationNotAvailableException('Deleting metadata not supported'); - } - - /** - * Get full path, including bucket, for an object - * - * @param string $path - * @param array $options - * @return void - */ - protected function _getFullPath($path, $options) - { - if (isset($options[self::BUCKET_NAME])) { - $bucket = $options[self::BUCKET_NAME]; - } else if (isset($this->_defaultBucketName)) { - $bucket = $this->_defaultBucketName; - } else { - #require_once 'Zend/Cloud/StorageService/Exception.php'; - throw new Zend_Cloud_StorageService_Exception('Bucket name must be specified for S3 adapter.'); - } - - if (isset($options[self::BUCKET_AS_DOMAIN])) { - // TODO: support bucket domain names - #require_once 'Zend/Cloud/StorageService/Exception.php'; - throw new Zend_Cloud_StorageService_Exception('The S3 adapter does not currently support buckets in domain names.'); - } - - return trim($bucket) . '/' . trim($path); - } - - /** - * Get the concrete client. - * @return Zend_Service_Amazon_S3 - */ - public function getClient() - { - return $this->_s3; - } -} diff --git a/lib/Zend/Cloud/StorageService/Adapter/WindowsAzure.php b/lib/Zend/Cloud/StorageService/Adapter/WindowsAzure.php deleted file mode 100644 index 6df6603c26f..00000000000 --- a/lib/Zend/Cloud/StorageService/Adapter/WindowsAzure.php +++ /dev/null @@ -1,443 +0,0 @@ -toArray(); - } - - if (!is_array($options)) { - throw new Zend_Cloud_StorageService_Exception('Invalid options provided'); - } - - // Build Zend_Service_WindowsAzure_Storage_Blob instance - if (!isset($options[self::HOST])) { - $host = self::DEFAULT_HOST; - } else { - $host = $options[self::HOST]; - } - - if (!isset($options[self::ACCOUNT_NAME])) { - throw new Zend_Cloud_StorageService_Exception('No Windows Azure account name provided.'); - } - if (!isset($options[self::ACCOUNT_KEY])) { - throw new Zend_Cloud_StorageService_Exception('No Windows Azure account key provided.'); - } - - $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Blob($host, - $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]); - - // Parse other options - if (!empty($options[self::PROXY_HOST])) { - $proxyHost = $options[self::PROXY_HOST]; - $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080; - $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : ''; - - $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials); - } - - if (isset($options[self::HTTP_ADAPTER])) { - $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]); - } - - // Set container - $this->_container = $options[self::CONTAINER]; - - // Make sure the container exists - if (!$this->_storageClient->containerExists($this->_container)) { - $this->_storageClient->createContainer($this->_container); - } - } - - /** - * Get an item from the storage service. - * - * @param string $path - * @param array $options - * @return mixed - */ - public function fetchItem($path, $options = null) - { - // Options - $returnType = self::RETURN_STRING; - $returnPath = tempnam('', 'azr'); - $openMode = 'r'; - - // Parse options - if (is_array($options)) { - if (isset($options[self::RETURN_TYPE])) { - $returnType = $options[self::RETURN_TYPE]; - } - - if (isset($options[self::RETURN_PATHNAME])) { - $returnPath = $options[self::RETURN_PATHNAME]; - } - - if (isset($options[self::RETURN_OPENMODE])) { - $openMode = $options[self::RETURN_OPENMODE]; - } - } - - // Fetch the blob - try { - $this->_storageClient->getBlob( - $this->_container, - $path, - $returnPath - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "does not exist") !== false) { - return false; - } - throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); - } - - // Return value - if ($returnType == self::RETURN_PATH) { - return $returnPath; - } - if ($returnType == self::RETURN_STRING) { - return file_get_contents($returnPath); - } - if ($returnType == self::RETURN_STREAM) { - return fopen($returnPath, $openMode); - } - } - - /** - * Store an item in the storage service. - * WARNING: This operation overwrites any item that is located at - * $destinationPath. - * @param string $destinationPath - * @param mixed $data - * @param array $options - * @return boolean - */ - public function storeItem($destinationPath, $data, $options = null) - { - // Create a temporary file that will be uploaded - $temporaryFilePath = ''; - $removeTemporaryFilePath = false; - - if (is_resource($data)) { - $temporaryFilePath = tempnam('', 'azr'); - $fpDestination = fopen($temporaryFilePath, 'w'); - - $fpSource = $data; - rewind($fpSource); - while (!feof($fpSource)) { - fwrite($fpDestination, fread($fpSource, 8192)); - } - - fclose($fpDestination); - - $removeTemporaryFilePath = true; - } elseif (file_exists($data)) { - $temporaryFilePath = $data; - $removeTemporaryFilePath = false; - } else { - $temporaryFilePath = tempnam('', 'azr'); - file_put_contents($temporaryFilePath, $data); - $removeTemporaryFilePath = true; - } - - try { - // Upload data - $this->_storageClient->putBlob( - $this->_container, - $destinationPath, - $temporaryFilePath - ); - } catch(Zend_Service_WindowsAzure_Exception $e) { - @unlink($temporaryFilePath); - throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e); - } - if ($removeTemporaryFilePath) { - @unlink($temporaryFilePath); - } - } - - /** - * Delete an item in the storage service. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteItem($path, $options = null) - { - try { - $this->_storageClient->deleteBlob( - $this->_container, - $path - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Copy an item in the storage service to a given path. - * - * @param string $sourcePath - * @param string $destinationPath - * @param array $options - * @return void - */ - public function copyItem($sourcePath, $destinationPath, $options = null) - { - try { - $this->_storageClient->copyBlob( - $this->_container, - $sourcePath, - $this->_container, - $destinationPath - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Move an item in the storage service to a given path. - * - * @param string $sourcePath - * @param string $destinationPath - * @param array $options - * @return void - */ - public function moveItem($sourcePath, $destinationPath, $options = null) - { - try { - $this->_storageClient->copyBlob( - $this->_container, - $sourcePath, - $this->_container, - $destinationPath - ); - - $this->_storageClient->deleteBlob( - $this->_container, - $sourcePath - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e); - } - - } - - /** - * Rename an item in the storage service to a given name. - * - * - * @param string $path - * @param string $name - * @param array $options - * @return void - */ - public function renameItem($path, $name, $options = null) - { - return $this->moveItem($path, $name, $options); - } - - /** - * List items in the given directory in the storage service - * - * The $path must be a directory - * - * - * @param string $path Must be a directory - * @param array $options - * @return array A list of item names - */ - public function listItems($path, $options = null) - { - // Options - $returnType = self::RETURN_NAMES; // 1: return list of paths, 2: return raw output from underlying provider - - // Parse options - if (is_array($options)&& isset($options[self::RETURN_TYPE])) { - $returnType = $options[self::RETURN_TYPE]; - } - - try { - // Fetch list - $blobList = $this->_storageClient->listBlobs( - $this->_container, - $path - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e); - } - - // Return - if ($returnType == self::RETURN_LIST) { - return $blobList; - } - - $returnValue = array(); - foreach ($blobList as $blob) { - $returnValue[] = $blob->Name; - } - - return $returnValue; - } - - /** - * Get a key/value array of metadata for the given path. - * - * @param string $path - * @param array $options - * @return array - */ - public function fetchMetadata($path, $options = null) - { - try { - return $this->_storageClient->getBlobMetaData( - $this->_container, - $path - ); - } catch (Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "could not be accessed") !== false) { - return false; - } - throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Store a key/value array of metadata at the given path. - * WARNING: This operation overwrites any metadata that is located at - * $destinationPath. - * - * @param string $destinationPath - * @param array $options - * @return void - */ - public function storeMetadata($destinationPath, $metadata, $options = null) - { - try { - $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, $metadata); - } catch (Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "could not be accessed") === false) { - throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - } - - /** - * Delete a key/value array of metadata at the given path. - * - * @param string $path - * @param array $options - * @return void - */ - public function deleteMetadata($path, $options = null) - { - try { - $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, array()); - } catch (Zend_Service_WindowsAzure_Exception $e) { - if (strpos($e->getMessage(), "could not be accessed") === false) { - throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage(), $e->getCode(), $e); - } - } - } - - /** - * Delete container - * - * @return void - */ - public function deleteContainer() - { - try { - $this->_storageClient->deleteContainer($this->_container); - } catch (Zend_Service_WindowsAzure_Exception $e) { - throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Get the concrete adapter. - * @return Zend_Service_Azure_Storage_Blob - */ - public function getClient() - { - return $this->_storageClient; - } -} diff --git a/lib/Zend/Cloud/StorageService/Exception.php b/lib/Zend/Cloud/StorageService/Exception.php deleted file mode 100644 index 1364c1d663b..00000000000 --- a/lib/Zend/Cloud/StorageService/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_init(); - if ($options != null) { - // use Zend_Config objects if provided - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - // pass arrays to setOptions - if (is_array($options)) { - $this->setOptions($options); - } - } - $this->_prepare(); - } - - /** - * setConfig() - * - * @param Zend_Config $config - * @return Zend_CodeGenerator_Abstract - */ - public function setConfig(Zend_Config $config) - { - $this->setOptions($config->toArray()); - return $this; - } - - /** - * setOptions() - * - * @param array $options - * @return Zend_CodeGenerator_Abstract - */ - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $methodName = 'set' . $optionName; - if (method_exists($this, $methodName)) { - $this->{$methodName}($optionValue); - } - } - return $this; - } - - /** - * setSourceContent() - * - * @param string $sourceContent - */ - public function setSourceContent($sourceContent) - { - $this->_sourceContent = $sourceContent; - return; - } - - /** - * getSourceContent() - * - * @return string - */ - public function getSourceContent() - { - return $this->_sourceContent; - } - - /** - * _init() - this is called before the constuctor - * - */ - protected function _init() - { - - } - - /** - * _prepare() - this is called at construction completion - * - */ - protected function _prepare() - { - - } - - /** - * generate() - must be implemented by the child - * - */ - abstract public function generate(); - - /** - * __toString() - casting to a string will in turn call generate() - * - * @return string - */ - final public function __toString() - { - return $this->generate(); - } - -} diff --git a/lib/Zend/CodeGenerator/Exception.php b/lib/Zend/CodeGenerator/Exception.php deleted file mode 100644 index f4126bf0355..00000000000 --- a/lib/Zend/CodeGenerator/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_isSourceDirty = ($isSourceDirty) ? true : false; - return $this; - } - - /** - * isSourceDirty() - * - * @return bool - */ - public function isSourceDirty() - { - return $this->_isSourceDirty; - } - - /** - * setIndentation() - * - * @param string|int $indentation - * @return Zend_CodeGenerator_Php_Abstract - */ - public function setIndentation($indentation) - { - $this->_indentation = $indentation; - return $this; - } - - /** - * getIndentation() - * - * @return string|int - */ - public function getIndentation() - { - return $this->_indentation; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Body.php b/lib/Zend/CodeGenerator/Php/Body.php deleted file mode 100644 index a3ce0683a47..00000000000 --- a/lib/Zend/CodeGenerator/Php/Body.php +++ /dev/null @@ -1,73 +0,0 @@ -_content = $content; - return $this; - } - - /** - * getContent() - * - * @return string - */ - public function getContent() - { - return (string) $this->_content; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - return $this->getContent(); - } -} diff --git a/lib/Zend/CodeGenerator/Php/Class.php b/lib/Zend/CodeGenerator/Php/Class.php deleted file mode 100644 index d4f24cb3f39..00000000000 --- a/lib/Zend/CodeGenerator/Php/Class.php +++ /dev/null @@ -1,618 +0,0 @@ -setSourceContent($class->getSourceContent()); - $class->setSourceDirty(false); - - if ($reflectionClass->getDocComment() != '') { - $class->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($reflectionClass->getDocblock())); - } - - $class->setAbstract($reflectionClass->isAbstract()); - $class->setName($reflectionClass->getName()); - - if ($parentClass = $reflectionClass->getParentClass()) { - $class->setExtendedClass($parentClass->getName()); - $interfaces = array_diff($reflectionClass->getInterfaces(), $parentClass->getInterfaces()); - } else { - $interfaces = $reflectionClass->getInterfaces(); - } - - $interfaceNames = array(); - foreach($interfaces AS $interface) { - $interfaceNames[] = $interface->getName(); - } - - $class->setImplementedInterfaces($interfaceNames); - - $properties = array(); - foreach ($reflectionClass->getProperties() as $reflectionProperty) { - if ($reflectionProperty->getDeclaringClass()->getName() == $class->getName()) { - $properties[] = Zend_CodeGenerator_Php_Property::fromReflection($reflectionProperty); - } - } - $class->setProperties($properties); - - $methods = array(); - foreach ($reflectionClass->getMethods() as $reflectionMethod) { - if ($reflectionMethod->getDeclaringClass()->getName() == $class->getName()) { - $methods[] = Zend_CodeGenerator_Php_Method::fromReflection($reflectionMethod); - } - } - $class->setMethods($methods); - - return $class; - } - - /** - * setDocblock() Set the docblock - * - * @param Zend_CodeGenerator_Php_Docblock|array|string $docblock - * @return Zend_CodeGenerator_Php_File - */ - public function setDocblock($docblock) - { - if (is_string($docblock)) { - $docblock = array('shortDescription' => $docblock); - } - - if (is_array($docblock)) { - $docblock = new Zend_CodeGenerator_Php_Docblock($docblock); - } elseif ((!is_null($docblock)) && (!$docblock instanceof Zend_CodeGenerator_Php_Docblock)) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock'); - } - - $this->_docblock = $docblock; - return $this; - } - - /** - * getDocblock() - * - * @return Zend_CodeGenerator_Php_Docblock - */ - public function getDocblock() - { - return $this->_docblock; - } - - /** - * setName() - * - * @param string $name - * @return Zend_CodeGenerator_Php_Class - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * setAbstract() - * - * @param bool $isAbstract - * @return Zend_CodeGenerator_Php_Class - */ - public function setAbstract($isAbstract) - { - $this->_isAbstract = ($isAbstract) ? true : false; - return $this; - } - - /** - * isAbstract() - * - * @return bool - */ - public function isAbstract() - { - return $this->_isAbstract; - } - - /** - * setExtendedClass() - * - * @param string $extendedClass - * @return Zend_CodeGenerator_Php_Class - */ - public function setExtendedClass($extendedClass) - { - $this->_extendedClass = $extendedClass; - return $this; - } - - /** - * getExtendedClass() - * - * @return string - */ - public function getExtendedClass() - { - return $this->_extendedClass; - } - - /** - * setImplementedInterfaces() - * - * @param array $implementedInterfaces - * @return Zend_CodeGenerator_Php_Class - */ - public function setImplementedInterfaces(Array $implementedInterfaces) - { - $this->_implementedInterfaces = $implementedInterfaces; - return $this; - } - - /** - * getImplementedInterfaces - * - * @return array - */ - public function getImplementedInterfaces() - { - return $this->_implementedInterfaces; - } - - /** - * setProperties() - * - * @param array $properties - * @return Zend_CodeGenerator_Php_Class - */ - public function setProperties(Array $properties) - { - foreach ($properties as $property) { - $this->setProperty($property); - } - - return $this; - } - - /** - * setConstants() - * - * @param array $constants - * @return Zend_CodeGenerator_Php_Class - */ - public function setConstants(Array $constants) - { - foreach ($constants as $const) { - $this->setConstant($const); - } - - return $this; - } - - /** - * setProperty() - * - * @param array|Zend_CodeGenerator_Php_Property $property - * @return Zend_CodeGenerator_Php_Class - */ - public function setProperty($property) - { - if (is_array($property)) { - $property = new Zend_CodeGenerator_Php_Property($property); - $propertyName = $property->getName(); - } elseif ($property instanceof Zend_CodeGenerator_Php_Property) { - $propertyName = $property->getName(); - } else { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setProperty() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property'); - } - - if ($property->isConst()) { - return $this->setConstant($property); - } - if (isset($this->_properties[$propertyName])) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('A property by name ' . $propertyName . ' already exists in this class.'); - } - - $this->_properties[$propertyName] = $property; - return $this; - } - - /** - * setConstant() - * - * @param array|Zend_CodeGenerator_Php_Property $const - * @return Zend_CodeGenerator_Php_Class - */ - public function setConstant($const) - { - if (is_array($const)) { - $const = new Zend_CodeGenerator_Php_Property($const); - $constName = $const->getName(); - } elseif ($const instanceof Zend_CodeGenerator_Php_Property) { - $constName = $const->getName(); - } else { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setConstant() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property'); - } - - if (!$const->isConst()) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setProperty() expects argument to define a constant'); - } - if (isset($this->_constants[$constName])) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('A constant by name ' . $constName . ' already exists in this class.'); - } - - $this->_constants[$constName] = $const; - return $this; - } - - /** - * getProperties() - * - * @return array - */ - public function getProperties() - { - return $this->_properties; - } - - /** - * getConstants() - * - * @return array - */ - public function getConstants() - { - return $this->_constants; - } - - /** - * getProperty() - * - * @param string $propertyName - * @return Zend_CodeGenerator_Php_Property - */ - public function getProperty($propertyName) - { - foreach ($this->_properties as $property) { - if ($property->getName() == $propertyName) { - return $property; - } - } - return false; - } - - /** - * getConstant() - * - * @param string $constName - * @return Zend_CodeGenerator_Php_Property - */ - public function getConstant($constName) - { - foreach ($this->_constants as $const) { - if ($const->getName() == $constName) { - return $const; - } - } - return false; - } - - /** - * hasProperty() - * - * @param string $propertyName - * @return bool - */ - public function hasProperty($propertyName) - { - return isset($this->_properties[$propertyName]); - } - - /** - * hasConstant() - * - * @param string $constName - * @return bool - */ - public function hasConstant($constName) - { - return isset($this->_constants[$constName]); - } - - /** - * setMethods() - * - * @param array $methods - * @return Zend_CodeGenerator_Php_Class - */ - public function setMethods(Array $methods) - { - foreach ($methods as $method) { - $this->setMethod($method); - } - return $this; - } - - /** - * setMethod() - * - * @param array|Zend_CodeGenerator_Php_Method $method - * @return Zend_CodeGenerator_Php_Class - */ - public function setMethod($method) - { - if (is_array($method)) { - $method = new Zend_CodeGenerator_Php_Method($method); - $methodName = $method->getName(); - } elseif ($method instanceof Zend_CodeGenerator_Php_Method) { - $methodName = $method->getName(); - } else { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setMethod() expects either an array of method options or an instance of Zend_CodeGenerator_Php_Method'); - } - - if (isset($this->_methods[$methodName])) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('A method by name ' . $methodName . ' already exists in this class.'); - } - - $this->_methods[$methodName] = $method; - return $this; - } - - /** - * getMethods() - * - * @return array - */ - public function getMethods() - { - return $this->_methods; - } - - /** - * getMethod() - * - * @param string $methodName - * @return Zend_CodeGenerator_Php_Method - */ - public function getMethod($methodName) - { - foreach ($this->_methods as $method) { - if ($method->getName() == $methodName) { - return $method; - } - } - return false; - } - - /** - * hasMethod() - * - * @param string $methodName - * @return bool - */ - public function hasMethod($methodName) - { - return isset($this->_methods[$methodName]); - } - - /** - * isSourceDirty() - * - * @return bool - */ - public function isSourceDirty() - { - if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) { - return true; - } - - foreach ($this->_properties as $property) { - if ($property->isSourceDirty()) { - return true; - } - } - - foreach ($this->_constants as $constant) { - if ($constant->isSourceDirty()) { - return true; - } - } - - foreach ($this->_methods as $method) { - if ($method->isSourceDirty()) { - return true; - } - } - - return parent::isSourceDirty(); - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - if (!$this->isSourceDirty()) { - return $this->getSourceContent(); - } - - $output = ''; - - if (null !== ($docblock = $this->getDocblock())) { - $docblock->setIndentation(''); - $output .= $docblock->generate(); - } - - if ($this->isAbstract()) { - $output .= 'abstract '; - } - - $output .= 'class ' . $this->getName(); - - if ( !empty( $this->_extendedClass) ) { - $output .= ' extends ' . $this->_extendedClass; - } - - $implemented = $this->getImplementedInterfaces(); - if (!empty($implemented)) { - $output .= ' implements ' . implode(', ', $implemented); - } - - $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED; - - $constants = $this->getConstants(); - if (!empty($constants)) { - foreach ($constants as $const) { - $output .= $const->generate() . self::LINE_FEED . self::LINE_FEED; - } - } - - $properties = $this->getProperties(); - if (!empty($properties)) { - foreach ($properties as $property) { - $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED; - } - } - - $methods = $this->getMethods(); - if (!empty($methods)) { - foreach ($methods as $method) { - $output .= $method->generate() . self::LINE_FEED; - } - } - - $output .= self::LINE_FEED . '}' . self::LINE_FEED; - - return $output; - } - - /** - * _init() - is called at construction time - * - */ - protected function _init() - { - $this->_properties = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_PROPERTY); - $this->_constants = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_PROPERTY); - $this->_methods = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_METHOD); - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Docblock.php b/lib/Zend/CodeGenerator/Php/Docblock.php deleted file mode 100644 index efefa219f6d..00000000000 --- a/lib/Zend/CodeGenerator/Php/Docblock.php +++ /dev/null @@ -1,227 +0,0 @@ -setSourceContent($reflectionDocblock->getContents()); - $docblock->setSourceDirty(false); - - $docblock->setShortDescription($reflectionDocblock->getShortDescription()); - $docblock->setLongDescription($reflectionDocblock->getLongDescription()); - - foreach ($reflectionDocblock->getTags() as $tag) { - $docblock->setTag(Zend_CodeGenerator_Php_Docblock_Tag::fromReflection($tag)); - } - - return $docblock; - } - - /** - * setShortDescription() - * - * @param string $shortDescription - * @return Zend_CodeGenerator_Php_Docblock - */ - public function setShortDescription($shortDescription) - { - $this->_shortDescription = $shortDescription; - return $this; - } - - /** - * getShortDescription() - * - * @return string - */ - public function getShortDescription() - { - return $this->_shortDescription; - } - - /** - * setLongDescription() - * - * @param string $longDescription - * @return Zend_CodeGenerator_Php_Docblock - */ - public function setLongDescription($longDescription) - { - $this->_longDescription = $longDescription; - return $this; - } - - /** - * getLongDescription() - * - * @return string - */ - public function getLongDescription() - { - return $this->_longDescription; - } - - /** - * setTags() - * - * @param array $tags - * @return Zend_CodeGenerator_Php_Docblock - */ - public function setTags(Array $tags) - { - foreach ($tags as $tag) { - $this->setTag($tag); - } - - return $this; - } - - /** - * setTag() - * - * @param array|Zend_CodeGenerator_Php_Docblock_Tag $tag - * @return Zend_CodeGenerator_Php_Docblock - */ - public function setTag($tag) - { - if (is_array($tag)) { - $tag = new Zend_CodeGenerator_Php_Docblock_Tag($tag); - } elseif (!$tag instanceof Zend_CodeGenerator_Php_Docblock_Tag) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception( - 'setTag() expects either an array of method options or an ' - . 'instance of Zend_CodeGenerator_Php_Docblock_Tag' - ); - } - - $this->_tags[] = $tag; - return $this; - } - - /** - * getTags - * - * @return array Array of Zend_CodeGenerator_Php_Docblock_Tag - */ - public function getTags() - { - return $this->_tags; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - if (!$this->isSourceDirty()) { - return $this->_docCommentize($this->getSourceContent()); - } - - $output = ''; - if (null !== ($sd = $this->getShortDescription())) { - $output .= $sd . self::LINE_FEED . self::LINE_FEED; - } - if (null !== ($ld = $this->getLongDescription())) { - $output .= $ld . self::LINE_FEED . self::LINE_FEED; - } - - foreach ($this->getTags() as $tag) { - $output .= $tag->generate() . self::LINE_FEED; - } - - return $this->_docCommentize(trim($output)); - } - - /** - * _docCommentize() - * - * @param string $content - * @return string - */ - protected function _docCommentize($content) - { - $indent = $this->getIndentation(); - $output = $indent . '/**' . self::LINE_FEED; - $content = wordwrap($content, 80, self::LINE_FEED); - $lines = explode(self::LINE_FEED, $content); - - foreach ($lines as $line) { - $output .= $indent . ' *'; - if ($line) { - $output .= " $line"; - } - $output .= self::LINE_FEED; - } - - $output = rtrim($output, ' *' . self::LINE_FEED) . self::LINE_FEED; - - $output .= $indent . ' */' . self::LINE_FEED; - return $output; - } -} diff --git a/lib/Zend/CodeGenerator/Php/Docblock/Tag.php b/lib/Zend/CodeGenerator/Php/Docblock/Tag.php deleted file mode 100644 index 2eede59624a..00000000000 --- a/lib/Zend/CodeGenerator/Php/Docblock/Tag.php +++ /dev/null @@ -1,178 +0,0 @@ -getName(); - - $codeGenDocblockTag = self::factory($tagName); - - // transport any properties via accessors and mutators from reflection to codegen object - $reflectionClass = new ReflectionClass($reflectionTag); - foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if (substr($method->getName(), 0, 3) == 'get') { - $propertyName = substr($method->getName(), 3); - if (method_exists($codeGenDocblockTag, 'set' . $propertyName)) { - $codeGenDocblockTag->{'set' . $propertyName}($reflectionTag->{'get' . $propertyName}()); - } - } - } - - return $codeGenDocblockTag; - } - - /** - * setPluginLoader() - * - * @param Zend_Loader_PluginLoader $pluginLoader - */ - public static function setPluginLoader(Zend_Loader_PluginLoader $pluginLoader) - { - self::$_pluginLoader = $pluginLoader; - return; - } - - /** - * getPluginLoader() - * - * @return Zend_Loader_PluginLoader - */ - public static function getPluginLoader() - { - if (self::$_pluginLoader == null) { - #require_once 'Zend/Loader/PluginLoader.php'; - self::setPluginLoader(new Zend_Loader_PluginLoader(array( - 'Zend_CodeGenerator_Php_Docblock_Tag' => dirname(__FILE__) . '/Tag/')) - ); - } - - return self::$_pluginLoader; - } - - public static function factory($tagName) - { - $pluginLoader = self::getPluginLoader(); - - try { - $tagClass = $pluginLoader->load($tagName); - } catch (Zend_Loader_Exception $exception) { - $tagClass = 'Zend_CodeGenerator_Php_Docblock_Tag'; - } - - $tag = new $tagClass(array('name' => $tagName)); - return $tag; - } - - /** - * setName() - * - * @param string $name - * @return Zend_CodeGenerator_Php_Docblock_Tag - */ - public function setName($name) - { - $this->_name = ltrim($name, '@'); - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * setDescription() - * - * @param string $description - * @return Zend_CodeGenerator_Php_Docblock_Tag - */ - public function setDescription($description) - { - $this->_description = $description; - return $this; - } - - /** - * getDescription() - * - * @return string - */ - public function getDescription() - { - return $this->_description; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $tag = '@' . $this->_name; - if ($this->_description) { - $tag .= ' ' . $this->_description; - } - return $tag; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Docblock/Tag/License.php b/lib/Zend/CodeGenerator/Php/Docblock/Tag/License.php deleted file mode 100644 index a588ad16113..00000000000 --- a/lib/Zend/CodeGenerator/Php/Docblock/Tag/License.php +++ /dev/null @@ -1,98 +0,0 @@ -setName('license'); - $returnTag->setUrl($reflectionTagLicense->getUrl()); - $returnTag->setDescription($reflectionTagLicense->getDescription()); - - return $returnTag; - } - - /** - * setUrl() - * - * @param string $url - * @return Zend_CodeGenerator_Php_Docblock_Tag_License - */ - public function setUrl($url) - { - $this->_url = $url; - return $this; - } - - /** - * getUrl() - * - * @return string - */ - public function getUrl() - { - return $this->_url; - } - - - /** - * generate() - * - * @return string - */ - public function generate() - { - $output = '@license ' . $this->_url . ' ' . $this->_description . self::LINE_FEED; - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Docblock/Tag/Param.php b/lib/Zend/CodeGenerator/Php/Docblock/Tag/Param.php deleted file mode 100644 index 19d3326e486..00000000000 --- a/lib/Zend/CodeGenerator/Php/Docblock/Tag/Param.php +++ /dev/null @@ -1,128 +0,0 @@ -setName('param'); - $paramTag->setDatatype($reflectionTagParam->getType()); // @todo rename - $paramTag->setParamName($reflectionTagParam->getVariableName()); - $paramTag->setDescription($reflectionTagParam->getDescription()); - - return $paramTag; - } - - /** - * setDatatype() - * - * @param string $datatype - * @return Zend_CodeGenerator_Php_Docblock_Tag_Param - */ - public function setDatatype($datatype) - { - $this->_datatype = $datatype; - return $this; - } - - /** - * getDatatype - * - * @return string - */ - public function getDatatype() - { - return $this->_datatype; - } - - /** - * setParamName() - * - * @param string $paramName - * @return Zend_CodeGenerator_Php_Docblock_Tag_Param - */ - public function setParamName($paramName) - { - $this->_paramName = $paramName; - return $this; - } - - /** - * getParamName() - * - * @return string - */ - public function getParamName() - { - return $this->_paramName; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $output = '@param ' - . (($this->_datatype != null) ? $this->_datatype : 'unknown') - . (($this->_paramName != null) ? ' $' . $this->_paramName : '') - . (($this->_description != null) ? ' ' . $this->_description : ''); - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Docblock/Tag/Return.php b/lib/Zend/CodeGenerator/Php/Docblock/Tag/Return.php deleted file mode 100644 index f4a0b1a4745..00000000000 --- a/lib/Zend/CodeGenerator/Php/Docblock/Tag/Return.php +++ /dev/null @@ -1,98 +0,0 @@ -setName('return'); - $returnTag->setDatatype($reflectionTagReturn->getType()); // @todo rename - $returnTag->setDescription($reflectionTagReturn->getDescription()); - - return $returnTag; - } - - /** - * setDatatype() - * - * @param string $datatype - * @return Zend_CodeGenerator_Php_Docblock_Tag_Return - */ - public function setDatatype($datatype) - { - $this->_datatype = $datatype; - return $this; - } - - /** - * getDatatype() - * - * @return string - */ - public function getDatatype() - { - return $this->_datatype; - } - - - /** - * generate() - * - * @return string - */ - public function generate() - { - $output = '@return ' . $this->_datatype . ' ' . $this->_description; - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Exception.php b/lib/Zend/CodeGenerator/Php/Exception.php deleted file mode 100644 index bb4ccd9af40..00000000000 --- a/lib/Zend/CodeGenerator/Php/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -getFilename(); - } - - if ($fileName == '') { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('FileName does not exist.'); - } - - // cannot use realpath since the file might not exist, but we do need to have the index - // in the same DIRECTORY_SEPARATOR that realpath would use: - $fileName = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $fileName); - - self::$_fileCodeGenerators[$fileName] = $fileCodeGenerator; - - } - - /** - * fromReflectedFileName() - use this if you intend on generating code generation objects based on the same file. - * This will keep previous changes to the file in tact during the same PHP process - * - * @param string $filePath - * @param bool $usePreviousCodeGeneratorIfItExists - * @param bool $includeIfNotAlreadyIncluded - * @return Zend_CodeGenerator_Php_File - */ - public static function fromReflectedFileName($filePath, $usePreviousCodeGeneratorIfItExists = true, $includeIfNotAlreadyIncluded = true) - { - $realpath = realpath($filePath); - - if ($realpath === false) { - if ( ($realpath = Zend_Reflection_File::findRealpathInIncludePath($filePath)) === false) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('No file for ' . $realpath . ' was found.'); - } - } - - if ($usePreviousCodeGeneratorIfItExists && isset(self::$_fileCodeGenerators[$realpath])) { - return self::$_fileCodeGenerators[$realpath]; - } - - if ($includeIfNotAlreadyIncluded && !in_array($realpath, get_included_files())) { - include $realpath; - } - - $codeGenerator = self::fromReflection(($fileReflector = new Zend_Reflection_File($realpath))); - - if (!isset(self::$_fileCodeGenerators[$fileReflector->getFileName()])) { - self::$_fileCodeGenerators[$fileReflector->getFileName()] = $codeGenerator; - } - - return $codeGenerator; - } - - /** - * fromReflection() - * - * @param Zend_Reflection_File $reflectionFile - * @return Zend_CodeGenerator_Php_File - */ - public static function fromReflection(Zend_Reflection_File $reflectionFile) - { - $file = new self(); - - $file->setSourceContent($reflectionFile->getContents()); - $file->setSourceDirty(false); - - $body = $reflectionFile->getContents(); - - // @todo this whole area needs to be reworked with respect to how body lines are processed - foreach ($reflectionFile->getClasses() as $class) { - $file->setClass(Zend_CodeGenerator_Php_Class::fromReflection($class)); - $classStartLine = $class->getStartLine(true); - $classEndLine = $class->getEndLine(); - - $bodyLines = explode("\n", $body); - $bodyReturn = array(); - for ($lineNum = 1; $lineNum <= count($bodyLines); $lineNum++) { - if ($lineNum == $classStartLine) { - $bodyReturn[] = str_replace('?', $class->getName(), self::$_markerClass); //'/* Zend_CodeGenerator_Php_File-ClassMarker: {' . $class->getName() . '} */'; - $lineNum = $classEndLine; - } else { - $bodyReturn[] = $bodyLines[$lineNum - 1]; // adjust for index -> line conversion - } - } - $body = implode("\n", $bodyReturn); - unset($bodyLines, $bodyReturn, $classStartLine, $classEndLine); - } - - if (($reflectionFile->getDocComment() != '')) { - $docblock = $reflectionFile->getDocblock(); - $file->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($docblock)); - - $bodyLines = explode("\n", $body); - $bodyReturn = array(); - for ($lineNum = 1; $lineNum <= count($bodyLines); $lineNum++) { - if ($lineNum == $docblock->getStartLine()) { - $bodyReturn[] = str_replace('?', $class->getName(), self::$_markerDocblock); //'/* Zend_CodeGenerator_Php_File-ClassMarker: {' . $class->getName() . '} */'; - $lineNum = $docblock->getEndLine(); - } else { - $bodyReturn[] = $bodyLines[$lineNum - 1]; // adjust for index -> line conversion - } - } - $body = implode("\n", $bodyReturn); - unset($bodyLines, $bodyReturn, $classStartLine, $classEndLine); - } - - $file->setBody($body); - - return $file; - } - - /** - * setDocblock() Set the docblock - * - * @param Zend_CodeGenerator_Php_Docblock|array|string $docblock - * @return Zend_CodeGenerator_Php_File - */ - public function setDocblock($docblock) - { - if (is_string($docblock)) { - $docblock = array('shortDescription' => $docblock); - } - - if (is_array($docblock)) { - $docblock = new Zend_CodeGenerator_Php_Docblock($docblock); - } elseif (!$docblock instanceof Zend_CodeGenerator_Php_Docblock) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock'); - } - - $this->_docblock = $docblock; - return $this; - } - - /** - * Get docblock - * - * @return Zend_CodeGenerator_Php_Docblock - */ - public function getDocblock() - { - return $this->_docblock; - } - - /** - * setRequiredFiles - * - * @param array $requiredFiles - * @return Zend_CodeGenerator_Php_File - */ - public function setRequiredFiles($requiredFiles) - { - $this->_requiredFiles = $requiredFiles; - return $this; - } - - /** - * getRequiredFiles() - * - * @return array - */ - public function getRequiredFiles() - { - return $this->_requiredFiles; - } - - /** - * setClasses() - * - * @param array $classes - * @return Zend_CodeGenerator_Php_File - */ - public function setClasses(Array $classes) - { - foreach ($classes as $class) { - $this->setClass($class); - } - return $this; - } - - /** - * getClass() - * - * @param string $name - * @return Zend_CodeGenerator_Php_Class - */ - public function getClass($name = null) - { - if ($name == null) { - reset($this->_classes); - return current($this->_classes); - } - - return $this->_classes[$name]; - } - - /** - * setClass() - * - * @param Zend_CodeGenerator_Php_Class|array $class - * @return Zend_CodeGenerator_Php_File - */ - public function setClass($class) - { - if (is_array($class)) { - $class = new Zend_CodeGenerator_Php_Class($class); - $className = $class->getName(); - } elseif ($class instanceof Zend_CodeGenerator_Php_Class) { - $className = $class->getName(); - } else { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('Expecting either an array or an instance of Zend_CodeGenerator_Php_Class'); - } - - // @todo check for dup here - - $this->_classes[$className] = $class; - return $this; - } - - /** - * setFilename() - * - * @param string $filename - * @return Zend_CodeGenerator_Php_File - */ - public function setFilename($filename) - { - $this->_filename = $filename; - return $this; - } - - /** - * getFilename() - * - * @return string - */ - public function getFilename() - { - return $this->_filename; - } - - /** - * getClasses() - * - * @return array Array of Zend_CodeGenerator_Php_Class - */ - public function getClasses() - { - return $this->_classes; - } - - /** - * setBody() - * - * @param string $body - * @return Zend_CodeGenerator_Php_File - */ - public function setBody($body) - { - $this->_body = $body; - return $this; - } - - /** - * getBody() - * - * @return string - */ - public function getBody() - { - return $this->_body; - } - - /** - * isSourceDirty() - * - * @return bool - */ - public function isSourceDirty() - { - if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) { - return true; - } - - foreach ($this->_classes as $class) { - if ($class->isSourceDirty()) { - return true; - } - } - - return parent::isSourceDirty(); - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - if ($this->isSourceDirty() === false) { - return $this->_sourceContent; - } - - $output = ''; - - // start with the body (if there), or open tag - if (preg_match('#(?:\s*)<\?php#', $this->getBody()) == false) { - $output = 'getBody(); - if (preg_match('#/\* Zend_CodeGenerator_Php_File-(.*?)Marker#', $body)) { - $output .= $body; - $body = ''; - } - - // Add file docblock, if any - if (null !== ($docblock = $this->getDocblock())) { - $docblock->setIndentation(''); - $regex = preg_quote(self::$_markerDocblock, '#'); - if (preg_match('#'.$regex.'#', $output)) { - $output = preg_replace('#'.$regex.'#', $docblock->generate(), $output, 1); - } else { - $output .= $docblock->generate() . self::LINE_FEED; - } - } - - // newline - $output .= self::LINE_FEED; - - // process required files - // @todo marker replacement for required files - $requiredFiles = $this->getRequiredFiles(); - if (!empty($requiredFiles)) { - foreach ($requiredFiles as $requiredFile) { - $output .= '#require_once \'' . $requiredFile . '\';' . self::LINE_FEED; - } - - $output .= self::LINE_FEED; - } - - // process classes - $classes = $this->getClasses(); - if (!empty($classes)) { - foreach ($classes as $class) { - if($this->getDocblock() == $class->getDocblock()) { - $class->setDocblock(null); - } - $regex = str_replace('?', $class->getName(), self::$_markerClass); - $regex = preg_quote($regex, '#'); - if (preg_match('#'.$regex.'#', $output)) { - $output = preg_replace('#'.$regex.'#', $class->generate(), $output, 1); - } else { - $output .= $class->generate() . self::LINE_FEED; - } - } - - } - - if (!empty($body)) { - - // add an extra space betwee clsses and - if (!empty($classes)) { - $output .= self::LINE_FEED; - } - - $output .= $body; - } - - return $output; - } - - public function write() - { - if ($this->_filename == '' || !is_writable(dirname($this->_filename))) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('This code generator object is not writable.'); - } - file_put_contents($this->_filename, $this->generate()); - return $this; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Member/Abstract.php b/lib/Zend/CodeGenerator/Php/Member/Abstract.php deleted file mode 100644 index 9896d420fac..00000000000 --- a/lib/Zend/CodeGenerator/Php/Member/Abstract.php +++ /dev/null @@ -1,222 +0,0 @@ - $docblock); - } - - if (is_array($docblock)) { - $docblock = new Zend_CodeGenerator_Php_Docblock($docblock); - } elseif (!$docblock instanceof Zend_CodeGenerator_Php_Docblock) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock'); - } - - $this->_docblock = $docblock; - return $this; - } - - /** - * getDocblock() - * - * @return Zend_CodeGenerator_Php_Docblock - */ - public function getDocblock() - { - return $this->_docblock; - } - - /** - * setAbstract() - * - * @param bool $isAbstract - * @return Zend_CodeGenerator_Php_Member_Abstract - */ - public function setAbstract($isAbstract) - { - $this->_isAbstract = ($isAbstract) ? true : false; - return $this; - } - - /** - * isAbstract() - * - * @return bool - */ - public function isAbstract() - { - return $this->_isAbstract; - } - - /** - * setFinal() - * - * @param bool $isFinal - * @return Zend_CodeGenerator_Php_Member_Abstract - */ - public function setFinal($isFinal) - { - $this->_isFinal = ($isFinal) ? true : false; - return $this; - } - - /** - * isFinal() - * - * @return bool - */ - public function isFinal() - { - return $this->_isFinal; - } - - /** - * setStatic() - * - * @param bool $isStatic - * @return Zend_CodeGenerator_Php_Member_Abstract - */ - public function setStatic($isStatic) - { - $this->_isStatic = ($isStatic) ? true : false; - return $this; - } - - /** - * isStatic() - * - * @return bool - */ - public function isStatic() - { - return $this->_isStatic; - } - - /** - * setVisitibility() - * - * @param const $visibility - * @return Zend_CodeGenerator_Php_Member_Abstract - */ - public function setVisibility($visibility) - { - $this->_visibility = $visibility; - return $this; - } - - /** - * getVisibility() - * - * @return const - */ - public function getVisibility() - { - return $this->_visibility; - } - - /** - * setName() - * - * @param string $name - * @return Zend_CodeGenerator_Php_Member_Abstract - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return $this->_name; - } -} diff --git a/lib/Zend/CodeGenerator/Php/Member/Container.php b/lib/Zend/CodeGenerator/Php/Member/Container.php deleted file mode 100644 index d792f130708..00000000000 --- a/lib/Zend/CodeGenerator/Php/Member/Container.php +++ /dev/null @@ -1,55 +0,0 @@ -_type = $type; - parent::__construct(array(), self::ARRAY_AS_PROPS); - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Method.php b/lib/Zend/CodeGenerator/Php/Method.php deleted file mode 100644 index abf2de7677f..00000000000 --- a/lib/Zend/CodeGenerator/Php/Method.php +++ /dev/null @@ -1,236 +0,0 @@ -setSourceContent($reflectionMethod->getContents(false)); - $method->setSourceDirty(false); - - if ($reflectionMethod->getDocComment() != '') { - $method->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($reflectionMethod->getDocblock())); - } - - $method->setFinal($reflectionMethod->isFinal()); - - if ($reflectionMethod->isPrivate()) { - $method->setVisibility(self::VISIBILITY_PRIVATE); - } elseif ($reflectionMethod->isProtected()) { - $method->setVisibility(self::VISIBILITY_PROTECTED); - } else { - $method->setVisibility(self::VISIBILITY_PUBLIC); - } - - $method->setStatic($reflectionMethod->isStatic()); - - $method->setName($reflectionMethod->getName()); - - foreach ($reflectionMethod->getParameters() as $reflectionParameter) { - $method->setParameter(Zend_CodeGenerator_Php_Parameter::fromReflection($reflectionParameter)); - } - - $method->setBody($reflectionMethod->getBody()); - - return $method; - } - - /** - * setFinal() - * - * @param bool $isFinal - */ - public function setFinal($isFinal) - { - $this->_isFinal = ($isFinal) ? true : false; - } - - /** - * setParameters() - * - * @param array $parameters - * @return Zend_CodeGenerator_Php_Method - */ - public function setParameters(Array $parameters) - { - foreach ($parameters as $parameter) { - $this->setParameter($parameter); - } - return $this; - } - - /** - * setParameter() - * - * @param Zend_CodeGenerator_Php_Parameter|array $parameter - * @return Zend_CodeGenerator_Php_Method - */ - public function setParameter($parameter) - { - if (is_array($parameter)) { - $parameter = new Zend_CodeGenerator_Php_Parameter($parameter); - $parameterName = $parameter->getName(); - } elseif ($parameter instanceof Zend_CodeGenerator_Php_Parameter) { - $parameterName = $parameter->getName(); - } else { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('setParameter() expects either an array of method options or an instance of Zend_CodeGenerator_Php_Parameter'); - } - - $this->_parameters[$parameterName] = $parameter; - return $this; - } - - /** - * getParameters() - * - * @return array Array of Zend_CodeGenerator_Php_Parameter - */ - public function getParameters() - { - return $this->_parameters; - } - - /** - * setBody() - * - * @param string $body - * @return Zend_CodeGenerator_Php_Method - */ - public function setBody($body) - { - $this->_body = $body; - return $this; - } - - /** - * getBody() - * - * @return string - */ - public function getBody() - { - return $this->_body; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $output = ''; - - $indent = $this->getIndentation(); - - if (($docblock = $this->getDocblock()) !== null) { - $docblock->setIndentation($indent); - $output .= $docblock->generate(); - } - - $output .= $indent; - - if ($this->isAbstract()) { - $output .= 'abstract '; - } else { - $output .= (($this->isFinal()) ? 'final ' : ''); - } - - $output .= $this->getVisibility() - . (($this->isStatic()) ? ' static' : '') - . ' function ' . $this->getName() . '('; - - $parameters = $this->getParameters(); - if (!empty($parameters)) { - foreach ($parameters as $parameter) { - $parameterOuput[] = $parameter->generate(); - } - - $output .= implode(', ', $parameterOuput); - } - - $output .= ')' . self::LINE_FEED . $indent . '{' . self::LINE_FEED; - - if ($this->_body && $this->isSourceDirty()) { - $output .= ' ' - . str_replace(self::LINE_FEED, self::LINE_FEED . $indent . $indent, trim($this->_body)) - . self::LINE_FEED; - } elseif ($this->_body) { - $output .= $this->_body . self::LINE_FEED; - } - - $output .= $indent . '}' . self::LINE_FEED; - - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Parameter.php b/lib/Zend/CodeGenerator/Php/Parameter.php deleted file mode 100644 index 1fa398efb51..00000000000 --- a/lib/Zend/CodeGenerator/Php/Parameter.php +++ /dev/null @@ -1,250 +0,0 @@ -setName($reflectionParameter->getName()); - - if($reflectionParameter->isArray()) { - $param->setType('array'); - } else { - $typeClass = $reflectionParameter->getClass(); - if($typeClass !== null) { - $param->setType($typeClass->getName()); - } - } - - $param->setPosition($reflectionParameter->getPosition()); - - if($reflectionParameter->isOptional()) { - $param->setDefaultValue($reflectionParameter->getDefaultValue()); - } - $param->setPassedByReference($reflectionParameter->isPassedByReference()); - - return $param; - } - - /** - * setType() - * - * @param string $type - * @return Zend_CodeGenerator_Php_Parameter - */ - public function setType($type) - { - $this->_type = $type; - return $this; - } - - /** - * getType() - * - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * setName() - * - * @param string $name - * @return Zend_CodeGenerator_Php_Parameter - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Set the default value of the parameter. - * - * Certain variables are difficult to expres - * - * @param null|bool|string|int|float|Zend_CodeGenerator_Php_Parameter_DefaultValue $defaultValue - * @return Zend_CodeGenerator_Php_Parameter - */ - public function setDefaultValue($defaultValue) - { - if($defaultValue === null) { - $this->_defaultValue = new Zend_CodeGenerator_Php_Parameter_DefaultValue("null"); - } else if(is_array($defaultValue)) { - $defaultValue = str_replace(array("\r", "\n"), "", var_export($defaultValue, true)); - $this->_defaultValue = new Zend_CodeGenerator_Php_Parameter_DefaultValue($defaultValue); - } else if(is_bool($defaultValue)) { - if($defaultValue == true) { - $this->_defaultValue = new Zend_CodeGenerator_Php_Parameter_DefaultValue("true"); - } else { - $this->_defaultValue = new Zend_CodeGenerator_Php_Parameter_DefaultValue("false"); - } - } else { - $this->_defaultValue = $defaultValue; - } - return $this; - } - - /** - * getDefaultValue() - * - * @return string - */ - public function getDefaultValue() - { - return $this->_defaultValue; - } - - /** - * setPosition() - * - * @param int $position - * @return Zend_CodeGenerator_Php_Parameter - */ - public function setPosition($position) - { - $this->_position = $position; - return $this; - } - - /** - * getPosition() - * - * @return int - */ - public function getPosition() - { - return $this->_position; - } - - /** - * @return bool - */ - public function getPassedByReference() - { - return $this->_passedByReference; - } - - /** - * @param bool $passedByReference - * @return Zend_CodeGenerator_Php_Parameter - */ - public function setPassedByReference($passedByReference) - { - $this->_passedByReference = $passedByReference; - return $this; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $output = ''; - - if ($this->_type) { - $output .= $this->_type . ' '; - } - - if($this->_passedByReference === true) { - $output .= '&'; - } - - $output .= '$' . $this->_name; - - if ($this->_defaultValue !== null) { - $output .= ' = '; - if (is_string($this->_defaultValue)) { - $output .= '\'' . $this->_defaultValue . '\''; - } else if($this->_defaultValue instanceof Zend_CodeGenerator_Php_Parameter_DefaultValue) { - $output .= (string)$this->_defaultValue; - } else { - $output .= $this->_defaultValue; - } - } - - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Parameter/DefaultValue.php b/lib/Zend/CodeGenerator/Php/Parameter/DefaultValue.php deleted file mode 100644 index 8518ece1820..00000000000 --- a/lib/Zend/CodeGenerator/Php/Parameter/DefaultValue.php +++ /dev/null @@ -1,60 +0,0 @@ -_defaultValue = $defaultValue; - } - - public function __toString() - { - return $this->_defaultValue; - } -} diff --git a/lib/Zend/CodeGenerator/Php/Property.php b/lib/Zend/CodeGenerator/Php/Property.php deleted file mode 100644 index 39bcc128cd6..00000000000 --- a/lib/Zend/CodeGenerator/Php/Property.php +++ /dev/null @@ -1,179 +0,0 @@ -setName($reflectionProperty->getName()); - - $allDefaultProperties = $reflectionProperty->getDeclaringClass()->getDefaultProperties(); - - $property->setDefaultValue($allDefaultProperties[$reflectionProperty->getName()]); - - if ($reflectionProperty->getDocComment() != '') { - $property->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($reflectionProperty->getDocComment())); - } - - if ($reflectionProperty->isStatic()) { - $property->setStatic(true); - } - - if ($reflectionProperty->isPrivate()) { - $property->setVisibility(self::VISIBILITY_PRIVATE); - } elseif ($reflectionProperty->isProtected()) { - $property->setVisibility(self::VISIBILITY_PROTECTED); - } else { - $property->setVisibility(self::VISIBILITY_PUBLIC); - } - - $property->setSourceDirty(false); - - return $property; - } - - /** - * setConst() - * - * @param bool $const - * @return Zend_CodeGenerator_Php_Property - */ - public function setConst($const) - { - $this->_isConst = $const; - return $this; - } - - /** - * isConst() - * - * @return bool - */ - public function isConst() - { - return ($this->_isConst) ? true : false; - } - - /** - * setDefaultValue() - * - * @param Zend_CodeGenerator_Php_Property_DefaultValue|string|array $defaultValue - * @return Zend_CodeGenerator_Php_Property - */ - public function setDefaultValue($defaultValue) - { - // if it looks like - if (is_array($defaultValue) - && array_key_exists('value', $defaultValue) - && array_key_exists('type', $defaultValue)) { - $defaultValue = new Zend_CodeGenerator_Php_Property_DefaultValue($defaultValue); - } - - if (!($defaultValue instanceof Zend_CodeGenerator_Php_Property_DefaultValue)) { - $defaultValue = new Zend_CodeGenerator_Php_Property_DefaultValue(array('value' => $defaultValue)); - } - - $this->_defaultValue = $defaultValue; - return $this; - } - - /** - * getDefaultValue() - * - * @return Zend_CodeGenerator_Php_Property_DefaultValue - */ - public function getDefaultValue() - { - return $this->_defaultValue; - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $name = $this->getName(); - $defaultValue = $this->getDefaultValue(); - - $output = ''; - - if (($docblock = $this->getDocblock()) !== null) { - $docblock->setIndentation(' '); - $output .= $docblock->generate(); - } - - if ($this->isConst()) { - if ($defaultValue != null && !$defaultValue->isValidConstantType()) { - #require_once 'Zend/CodeGenerator/Php/Exception.php'; - throw new Zend_CodeGenerator_Php_Exception('The property ' . $this->_name . ' is said to be ' - . 'constant but does not have a valid constant value.'); - } - $output .= $this->_indentation . 'const ' . $name . ' = ' - . (($defaultValue !== null) ? $defaultValue->generate() : 'null;'); - } else { - $output .= $this->_indentation - . $this->getVisibility() - . (($this->isStatic()) ? ' static' : '') - . ' $' . $name . ' = ' - . (($defaultValue !== null) ? $defaultValue->generate() : 'null;'); - } - return $output; - } - -} diff --git a/lib/Zend/CodeGenerator/Php/Property/DefaultValue.php b/lib/Zend/CodeGenerator/Php/Property/DefaultValue.php deleted file mode 100644 index 4679d0a45f1..00000000000 --- a/lib/Zend/CodeGenerator/Php/Property/DefaultValue.php +++ /dev/null @@ -1,325 +0,0 @@ -getConstants(); - unset($reflect); - } - } - - /** - * isValidConstantType() - * - * @return bool - */ - public function isValidConstantType() - { - if ($this->_type == self::TYPE_AUTO) { - $type = $this->_getAutoDeterminedType($this->_value); - } else { - $type = $this->_type; - } - - // valid types for constants - $scalarTypes = array( - self::TYPE_BOOLEAN, - self::TYPE_BOOL, - self::TYPE_NUMBER, - self::TYPE_INTEGER, - self::TYPE_INT, - self::TYPE_FLOAT, - self::TYPE_DOUBLE, - self::TYPE_STRING, - self::TYPE_CONSTANT, - self::TYPE_NULL - ); - - return in_array($type, $scalarTypes); - } - - /** - * setValue() - * - * @param mixed $value - * @return Zend_CodeGenerator_Php_Property_DefaultValue - */ - public function setValue($value) - { - $this->_value = $value; - return $this; - } - - /** - * getValue() - * - * @return mixed - */ - public function getValue() - { - return $this->_value; - } - - /** - * setType() - * - * @param string $type - * @return Zend_CodeGenerator_Php_Property_DefaultValue - */ - public function setType($type) - { - $this->_type = $type; - return $this; - } - - /** - * getType() - * - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * setArrayDepth() - * - * @param int $arrayDepth - * @return Zend_CodeGenerator_Php_Property_DefaultValue - */ - public function setArrayDepth($arrayDepth) - { - $this->_arrayDepth = $arrayDepth; - return $this; - } - - /** - * getArrayDepth() - * - * @return int - */ - public function getArrayDepth() - { - return $this->_arrayDepth; - } - - /** - * _getValidatedType() - * - * @param string $type - * @return string - */ - protected function _getValidatedType($type) - { - if (($constName = array_search($type, self::$_constants)) !== false) { - return $type; - } - - return self::TYPE_AUTO; - } - - /** - * _getAutoDeterminedType() - * - * @param mixed $value - * @return string - */ - public function _getAutoDeterminedType($value) - { - switch (gettype($value)) { - case 'boolean': - return self::TYPE_BOOLEAN; - case 'integer': - return self::TYPE_INT; - case 'string': - return self::TYPE_STRING; - case 'double': - case 'float': - case 'integer': - return self::TYPE_NUMBER; - case 'array': - return self::TYPE_ARRAY; - case 'NULL': - return self::TYPE_NULL; - case 'object': - case 'resource': - case 'unknown type': - default: - return self::TYPE_OTHER; - } - } - - /** - * generate() - * - * @return string - */ - public function generate() - { - $type = $this->_type; - - if ($type != self::TYPE_AUTO) { - $type = $this->_getValidatedType($type); - } - - $value = $this->_value; - - if ($type == self::TYPE_AUTO) { - $type = $this->_getAutoDeterminedType($value); - - if ($type == self::TYPE_ARRAY) { - $rii = new RecursiveIteratorIterator( - $it = new RecursiveArrayIterator($value), - RecursiveIteratorIterator::SELF_FIRST - ); - foreach ($rii as $curKey => $curValue) { - if (!$curValue instanceof Zend_CodeGenerator_Php_Property_DefaultValue) { - $curValue = new self(array('value' => $curValue)); - $rii->getSubIterator()->offsetSet($curKey, $curValue); - } - $curValue->setArrayDepth($rii->getDepth()); - } - $value = $rii->getSubIterator()->getArrayCopy(); - } - - } - - $output = ''; - - switch ($type) { - case self::TYPE_BOOLEAN: - case self::TYPE_BOOL: - $output .= ( $value ? 'true' : 'false' ); - break; - case self::TYPE_STRING: - $output .= "'" . addcslashes($value, "'") . "'"; - break; - case self::TYPE_NULL: - $output .= 'null'; - break; - case self::TYPE_NUMBER: - case self::TYPE_INTEGER: - case self::TYPE_INT: - case self::TYPE_FLOAT: - case self::TYPE_DOUBLE: - case self::TYPE_CONSTANT: - $output .= $value; - break; - case self::TYPE_ARRAY: - $output .= 'array('; - $curArrayMultiblock = false; - if (count($value) > 1) { - $curArrayMultiblock = true; - $output .= PHP_EOL . str_repeat($this->_indentation, $this->_arrayDepth+1); - } - $outputParts = array(); - $noKeyIndex = 0; - foreach ($value as $n => $v) { - $v->setArrayDepth($this->_arrayDepth + 1); - $partV = $v->generate(); - $partV = substr($partV, 0, strlen($partV)-1); - if ($n === $noKeyIndex) { - $outputParts[] = $partV; - $noKeyIndex++; - } else { - $outputParts[] = (is_int($n) ? $n : "'" . addcslashes($n, "'") . "'") . ' => ' . $partV; - } - - } - $output .= implode(',' . PHP_EOL . str_repeat($this->_indentation, $this->_arrayDepth+1), $outputParts); - if ($curArrayMultiblock == true) { - $output .= PHP_EOL . str_repeat($this->_indentation, $this->_arrayDepth+1); - } - $output .= ')'; - break; - case self::TYPE_OTHER: - default: - #require_once "Zend/CodeGenerator/Php/Exception.php"; - throw new Zend_CodeGenerator_Php_Exception( - "Type '".get_class($value)."' is unknown or cannot be used as property default value." - ); - } - - $output .= ';'; - - return $output; - } -} diff --git a/lib/Zend/Config.php b/lib/Zend/Config.php deleted file mode 100644 index b4dda458b32..00000000000 --- a/lib/Zend/Config.php +++ /dev/null @@ -1,484 +0,0 @@ -_allowModifications = (boolean) $allowModifications; - $this->_loadedSection = null; - $this->_index = 0; - $this->_data = array(); - foreach ($array as $key => $value) { - if (is_array($value)) { - $this->_data[$key] = new self($value, $this->_allowModifications); - } else { - $this->_data[$key] = $value; - } - } - $this->_count = count($this->_data); - } - - /** - * Retrieve a value and return $default if there is no element set. - * - * @param string $name - * @param mixed $default - * @return mixed - */ - public function get($name, $default = null) - { - $result = $default; - if (array_key_exists($name, $this->_data)) { - $result = $this->_data[$name]; - } - return $result; - } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - return $this->get($name); - } - - /** - * Only allow setting of a property if $allowModifications - * was set to true on construction. Otherwise, throw an exception. - * - * @param string $name - * @param mixed $value - * @throws Zend_Config_Exception - * @return void - */ - public function __set($name, $value) - { - if ($this->_allowModifications) { - if (is_array($value)) { - $this->_data[$name] = new self($value, true); - } else { - $this->_data[$name] = $value; - } - $this->_count = count($this->_data); - } else { - /** @see Zend_Config_Exception */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Zend_Config is read only'); - } - } - - /** - * Deep clone of this instance to ensure that nested Zend_Configs - * are also cloned. - * - * @return void - */ - public function __clone() - { - $array = array(); - foreach ($this->_data as $key => $value) { - if ($value instanceof Zend_Config) { - $array[$key] = clone $value; - } else { - $array[$key] = $value; - } - } - $this->_data = $array; - } - - /** - * Return an associative array of the stored data. - * - * @return array - */ - public function toArray() - { - $array = array(); - $data = $this->_data; - foreach ($data as $key => $value) { - if ($value instanceof Zend_Config) { - $array[$key] = $value->toArray(); - } else { - $array[$key] = $value; - } - } - return $array; - } - - /** - * Support isset() overloading on PHP 5.1 - * - * @param string $name - * @return boolean - */ - public function __isset($name) - { - return isset($this->_data[$name]); - } - - /** - * Support unset() overloading on PHP 5.1 - * - * @param string $name - * @throws Zend_Config_Exception - * @return void - */ - public function __unset($name) - { - if ($this->_allowModifications) { - unset($this->_data[$name]); - $this->_count = count($this->_data); - $this->_skipNextIteration = true; - } else { - /** @see Zend_Config_Exception */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Zend_Config is read only'); - } - - } - - /** - * Defined by Countable interface - * - * @return int - */ - public function count() - { - return $this->_count; - } - - /** - * Defined by Iterator interface - * - * @return mixed - */ - public function current() - { - $this->_skipNextIteration = false; - return current($this->_data); - } - - /** - * Defined by Iterator interface - * - * @return mixed - */ - public function key() - { - return key($this->_data); - } - - /** - * Defined by Iterator interface - * - */ - public function next() - { - if ($this->_skipNextIteration) { - $this->_skipNextIteration = false; - return; - } - next($this->_data); - $this->_index++; - } - - /** - * Defined by Iterator interface - * - */ - public function rewind() - { - $this->_skipNextIteration = false; - reset($this->_data); - $this->_index = 0; - } - - /** - * Defined by Iterator interface - * - * @return boolean - */ - public function valid() - { - return $this->_index < $this->_count; - } - - /** - * Returns the section name(s) loaded. - * - * @return mixed - */ - public function getSectionName() - { - if(is_array($this->_loadedSection) && count($this->_loadedSection) == 1) { - $this->_loadedSection = $this->_loadedSection[0]; - } - return $this->_loadedSection; - } - - /** - * Returns true if all sections were loaded - * - * @return boolean - */ - public function areAllSectionsLoaded() - { - return $this->_loadedSection === null; - } - - - /** - * Merge another Zend_Config with this one. The items - * in $merge will override the same named items in - * the current config. - * - * @param Zend_Config $merge - * @return Zend_Config - */ - public function merge(Zend_Config $merge) - { - foreach($merge as $key => $item) { - if(array_key_exists($key, $this->_data)) { - if($item instanceof Zend_Config && $this->$key instanceof Zend_Config) { - $this->$key = $this->$key->merge(new Zend_Config($item->toArray(), !$this->readOnly())); - } else { - $this->$key = $item; - } - } else { - if($item instanceof Zend_Config) { - $this->$key = new Zend_Config($item->toArray(), !$this->readOnly()); - } else { - $this->$key = $item; - } - } - } - - return $this; - } - - /** - * Prevent any more modifications being made to this instance. Useful - * after merge() has been used to merge multiple Zend_Config objects - * into one object which should then not be modified again. - * - */ - public function setReadOnly() - { - $this->_allowModifications = false; - foreach ($this->_data as $key => $value) { - if ($value instanceof Zend_Config) { - $value->setReadOnly(); - } - } - } - - /** - * Returns if this Zend_Config object is read only or not. - * - * @return boolean - */ - public function readOnly() - { - return !$this->_allowModifications; - } - - /** - * Get the current extends - * - * @return array - */ - public function getExtends() - { - return $this->_extends; - } - - /** - * Set an extend for Zend_Config_Writer - * - * @param string $extendingSection - * @param string $extendedSection - * @return void - */ - public function setExtend($extendingSection, $extendedSection = null) - { - if ($extendedSection === null && isset($this->_extends[$extendingSection])) { - unset($this->_extends[$extendingSection]); - } else if ($extendedSection !== null) { - $this->_extends[$extendingSection] = $extendedSection; - } - } - - /** - * Throws an exception if $extendingSection may not extend $extendedSection, - * and tracks the section extension if it is valid. - * - * @param string $extendingSection - * @param string $extendedSection - * @throws Zend_Config_Exception - * @return void - */ - protected function _assertValidExtend($extendingSection, $extendedSection) - { - // detect circular section inheritance - $extendedSectionCurrent = $extendedSection; - while (array_key_exists($extendedSectionCurrent, $this->_extends)) { - if ($this->_extends[$extendedSectionCurrent] == $extendingSection) { - /** @see Zend_Config_Exception */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Illegal circular inheritance detected'); - } - $extendedSectionCurrent = $this->_extends[$extendedSectionCurrent]; - } - // remember that this section extends another section - $this->_extends[$extendingSection] = $extendedSection; - } - - /** - * Handle any errors from simplexml_load_file or parse_ini_file - * - * @param integer $errno - * @param string $errstr - * @param string $errfile - * @param integer $errline - */ - public function _loadFileErrorHandler($errno, $errstr, $errfile, $errline) - { - if ($this->_loadFileErrorStr === null) { - $this->_loadFileErrorStr = $errstr; - } else { - $this->_loadFileErrorStr .= (PHP_EOL . $errstr); - } - } - - /** - * Merge two arrays recursively, overwriting keys of the same name - * in $firstArray with the value in $secondArray. - * - * @param mixed $firstArray First array - * @param mixed $secondArray Second array to merge into first array - * @return array - */ - protected function _arrayMergeRecursive($firstArray, $secondArray) - { - if (is_array($firstArray) && is_array($secondArray)) { - foreach ($secondArray as $key => $value) { - if (isset($firstArray[$key])) { - $firstArray[$key] = $this->_arrayMergeRecursive($firstArray[$key], $value); - } else { - if($key === 0) { - $firstArray= array(0=>$this->_arrayMergeRecursive($firstArray, $value)); - } else { - $firstArray[$key] = $value; - } - } - } - } else { - $firstArray = $secondArray; - } - - return $firstArray; - } -} diff --git a/lib/Zend/Config/Exception.php b/lib/Zend/Config/Exception.php deleted file mode 100644 index ce72cab3adc..00000000000 --- a/lib/Zend/Config/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ -hostname === "staging" - * $data->db->connection === "database" - * - * The $options parameter may be provided as either a boolean or an array. - * If provided as a boolean, this sets the $allowModifications option of - * Zend_Config. If provided as an array, there are three configuration - * directives that may be set. For example: - * - * $options = array( - * 'allowModifications' => false, - * 'nestSeparator' => ':', - * 'skipExtends' => false, - * ); - * - * @param string $filename - * @param mixed $section - * @param boolean|array $options - * @throws Zend_Config_Exception - * @return void - */ - public function __construct($filename, $section = null, $options = false) - { - if (empty($filename)) { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Filename is not set'); - } - - $allowModifications = false; - if (is_bool($options)) { - $allowModifications = $options; - } elseif (is_array($options)) { - if (isset($options['allowModifications'])) { - $allowModifications = (bool) $options['allowModifications']; - } - if (isset($options['nestSeparator'])) { - $this->_nestSeparator = (string) $options['nestSeparator']; - } - if (isset($options['skipExtends'])) { - $this->_skipExtends = (bool) $options['skipExtends']; - } - } - - $iniArray = $this->_loadIniFile($filename); - - if (null === $section) { - // Load entire file - $dataArray = array(); - foreach ($iniArray as $sectionName => $sectionData) { - if(!is_array($sectionData)) { - $dataArray = $this->_arrayMergeRecursive($dataArray, $this->_processKey(array(), $sectionName, $sectionData)); - } else { - $dataArray[$sectionName] = $this->_processSection($iniArray, $sectionName); - } - } - parent::__construct($dataArray, $allowModifications); - } else { - // Load one or more sections - if (!is_array($section)) { - $section = array($section); - } - $dataArray = array(); - foreach ($section as $sectionName) { - if (!isset($iniArray[$sectionName])) { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Section '$sectionName' cannot be found in $filename"); - } - $dataArray = $this->_arrayMergeRecursive($this->_processSection($iniArray, $sectionName), $dataArray); - - } - parent::__construct($dataArray, $allowModifications); - } - - $this->_loadedSection = $section; - } - - /** - * Load the INI file from disk using parse_ini_file(). Use a private error - * handler to convert any loading errors into a Zend_Config_Exception - * - * @param string $filename - * @throws Zend_Config_Exception - * @return array - */ - protected function _parseIniFile($filename) - { - set_error_handler(array($this, '_loadFileErrorHandler')); - $iniArray = parse_ini_file($filename, true); // Warnings and errors are suppressed - restore_error_handler(); - - // Check if there was a error while loading file - if ($this->_loadFileErrorStr !== null) { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception($this->_loadFileErrorStr); - } - - return $iniArray; - } - - /** - * Load the ini file and preprocess the section separator (':' in the - * section name (that is used for section extension) so that the resultant - * array has the correct section names and the extension information is - * stored in a sub-key called ';extends'. We use ';extends' as this can - * never be a valid key name in an INI file that has been loaded using - * parse_ini_file(). - * - * @param string $filename - * @throws Zend_Config_Exception - * @return array - */ - protected function _loadIniFile($filename) - { - $loaded = $this->_parseIniFile($filename); - $iniArray = array(); - foreach ($loaded as $key => $data) - { - $pieces = explode($this->_sectionSeparator, $key); - $thisSection = trim($pieces[0]); - switch (count($pieces)) { - case 1: - $iniArray[$thisSection] = $data; - break; - - case 2: - $extendedSection = trim($pieces[1]); - $iniArray[$thisSection] = array_merge(array(';extends'=>$extendedSection), $data); - break; - - default: - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Section '$thisSection' may not extend multiple sections in $filename"); - } - } - - return $iniArray; - } - - /** - * Process each element in the section and handle the ";extends" inheritance - * key. Passes control to _processKey() to handle the nest separator - * sub-property syntax that may be used within the key name. - * - * @param array $iniArray - * @param string $section - * @param array $config - * @throws Zend_Config_Exception - * @return array - */ - protected function _processSection($iniArray, $section, $config = array()) - { - $thisSection = $iniArray[$section]; - - foreach ($thisSection as $key => $value) { - if (strtolower($key) == ';extends') { - if (isset($iniArray[$value])) { - $this->_assertValidExtend($section, $value); - - if (!$this->_skipExtends) { - $config = $this->_processSection($iniArray, $value, $config); - } - } else { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Parent section '$section' cannot be found"); - } - } else { - $config = $this->_processKey($config, $key, $value); - } - } - return $config; - } - - /** - * Assign the key's value to the property list. Handles the - * nest separator for sub-properties. - * - * @param array $config - * @param string $key - * @param string $value - * @throws Zend_Config_Exception - * @return array - */ - protected function _processKey($config, $key, $value) - { - if (strpos($key, $this->_nestSeparator) !== false) { - $pieces = explode($this->_nestSeparator, $key, 2); - if (strlen($pieces[0]) && strlen($pieces[1])) { - if (!isset($config[$pieces[0]])) { - if ($pieces[0] === '0' && !empty($config)) { - // convert the current values in $config into an array - $config = array($pieces[0] => $config); - } else { - $config[$pieces[0]] = array(); - } - } elseif (!is_array($config[$pieces[0]])) { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Cannot create sub-key for '{$pieces[0]}' as key already exists"); - } - $config[$pieces[0]] = $this->_processKey($config[$pieces[0]], $pieces[1], $value); - } else { - /** - * @see Zend_Config_Exception - */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Invalid key '$key'"); - } - } else { - $config[$key] = $value; - } - return $config; - } -} diff --git a/lib/Zend/Config/Json.php b/lib/Zend/Config/Json.php deleted file mode 100644 index 0032685bad3..00000000000 --- a/lib/Zend/Config/Json.php +++ /dev/null @@ -1,242 +0,0 @@ - $value) { - switch (strtolower($key)) { - case 'allow_modifications': - case 'allowmodifications': - $allowModifications = (bool) $value; - break; - case 'skip_extends': - case 'skipextends': - $this->_skipExtends = (bool) $value; - break; - case 'ignore_constants': - case 'ignoreconstants': - $this->_ignoreConstants = (bool) $value; - break; - default: - break; - } - } - } - - set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed - if ($json[0] != '{') { - $json = file_get_contents($json); - } - restore_error_handler(); - - // Check if there was a error while loading file - if ($this->_loadFileErrorStr !== null) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception($this->_loadFileErrorStr); - } - - // Replace constants - if (!$this->_ignoreConstants) { - $json = $this->_replaceConstants($json); - } - - // Parse/decode - try { - $config = Zend_Json::decode($json); - } catch (Zend_Json_Exception $e) { - // decode failed - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Error parsing JSON data"); - } - - if ($section === null) { - $dataArray = array(); - foreach ($config as $sectionName => $sectionData) { - $dataArray[$sectionName] = $this->_processExtends($config, $sectionName); - } - - parent::__construct($dataArray, $allowModifications); - } elseif (is_array($section)) { - $dataArray = array(); - foreach ($section as $sectionName) { - if (!isset($config[$sectionName])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $sectionName)); - } - - $dataArray = array_merge($this->_processExtends($config, $sectionName), $dataArray); - } - - parent::__construct($dataArray, $allowModifications); - } else { - if (!isset($config[$section])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $section)); - } - - $dataArray = $this->_processExtends($config, $section); - if (!is_array($dataArray)) { - // Section in the JSON data contains just one top level string - $dataArray = array($section => $dataArray); - } - - parent::__construct($dataArray, $allowModifications); - } - - $this->_loadedSection = $section; - } - - /** - * Helper function to process each element in the section and handle - * the "_extends" inheritance attribute. - * - * @param array $data Data array to process - * @param string $section Section to process - * @param array $config Configuration which was parsed yet - * @throws Zend_Config_Exception When $section cannot be found - * @return array - */ - protected function _processExtends(array $data, $section, array $config = array()) - { - if (!isset($data[$section])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $section)); - } - - $thisSection = $data[$section]; - - if (is_array($thisSection) && isset($thisSection[self::EXTENDS_NAME])) { - if (is_array($thisSection[self::EXTENDS_NAME])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Invalid extends clause: must be a string; array received'); - } - $this->_assertValidExtend($section, $thisSection[self::EXTENDS_NAME]); - - if (!$this->_skipExtends) { - $config = $this->_processExtends($data, $thisSection[self::EXTENDS_NAME], $config); - } - unset($thisSection[self::EXTENDS_NAME]); - } - - $config = $this->_arrayMergeRecursive($config, $thisSection); - - return $config; - } - - /** - * Replace any constants referenced in a string with their values - * - * @param string $value - * @return string - */ - protected function _replaceConstants($value) - { - foreach ($this->_getConstants() as $constant) { - if (strstr($value, $constant)) { - // handle backslashes that may represent windows path names for instance - $replacement = str_replace('\\', '\\\\', constant($constant)); - $value = str_replace($constant, $replacement, $value); - } - } - return $value; - } - - /** - * Get (reverse) sorted list of defined constant names - * - * @return array - */ - protected function _getConstants() - { - $constants = array_keys(get_defined_constants()); - rsort($constants, SORT_STRING); - return $constants; - } -} diff --git a/lib/Zend/Config/Writer.php b/lib/Zend/Config/Writer.php deleted file mode 100644 index 8c255b3c847..00000000000 --- a/lib/Zend/Config/Writer.php +++ /dev/null @@ -1,101 +0,0 @@ -setOptions($options); - } - } - - /** - * Set options via a Zend_Config instance - * - * @param Zend_Config $config - * @return Zend_Config_Writer - */ - public function setConfig(Zend_Config $config) - { - $this->_config = $config; - - return $this; - } - - /** - * Set options via an array - * - * @param array $options - * @return Zend_Config_Writer - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . ucfirst($key); - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Write a Zend_Config object to it's target - * - * @return void - */ - abstract public function write(); -} diff --git a/lib/Zend/Config/Writer/Array.php b/lib/Zend/Config/Writer/Array.php deleted file mode 100644 index 72026d70aae..00000000000 --- a/lib/Zend/Config/Writer/Array.php +++ /dev/null @@ -1,55 +0,0 @@ -_config->toArray(); - $sectionName = $this->_config->getSectionName(); - - if (is_string($sectionName)) { - $data = array($sectionName => $data); - } - - $arrayString = "_filename = $filename; - - return $this; - } - - /** - * Set wether to exclusively lock the file or not - * - * @param boolean $exclusiveLock - * @return Zend_Config_Writer_Array - */ - public function setExclusiveLock($exclusiveLock) - { - $this->_exclusiveLock = $exclusiveLock; - - return $this; - } - - /** - * Write configuration to file. - * - * @param string $filename - * @param Zend_Config $config - * @param bool $exclusiveLock - * @return void - */ - public function write($filename = null, Zend_Config $config = null, $exclusiveLock = null) - { - if ($filename !== null) { - $this->setFilename($filename); - } - - if ($config !== null) { - $this->setConfig($config); - } - - if ($exclusiveLock !== null) { - $this->setExclusiveLock($exclusiveLock); - } - - if ($this->_filename === null) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('No filename was set'); - } - - if ($this->_config === null) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('No config was set'); - } - - $configString = $this->render(); - - $flags = 0; - - if ($this->_exclusiveLock) { - $flags |= LOCK_EX; - } - - $result = @file_put_contents($this->_filename, $configString, $flags); - - if ($result === false) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Could not write to file "' . $this->_filename . '"'); - } - } - - /** - * Render a Zend_Config into a config file string. - * - * @since 1.10 - * @todo For 2.0 this should be redone into an abstract method. - * @return string - */ - public function render() - { - return ""; - } -} diff --git a/lib/Zend/Config/Writer/Ini.php b/lib/Zend/Config/Writer/Ini.php deleted file mode 100644 index b119d060fbf..00000000000 --- a/lib/Zend/Config/Writer/Ini.php +++ /dev/null @@ -1,193 +0,0 @@ -_nestSeparator = $separator; - - return $this; - } - - /** - * Set if rendering should occour without sections or not. - * - * If set to true, the INI file is rendered without sections completely - * into the global namespace of the INI file. - * - * @param bool $withoutSections - * @return Zend_Config_Writer_Ini - */ - public function setRenderWithoutSections($withoutSections=true) - { - $this->_renderWithoutSections = (bool)$withoutSections; - return $this; - } - - /** - * Render a Zend_Config into a INI config string. - * - * @since 1.10 - * @return string - */ - public function render() - { - $iniString = ''; - $extends = $this->_config->getExtends(); - $sectionName = $this->_config->getSectionName(); - - if($this->_renderWithoutSections == true) { - $iniString .= $this->_addBranch($this->_config); - } else if (is_string($sectionName)) { - $iniString .= '[' . $sectionName . ']' . "\n" - . $this->_addBranch($this->_config) - . "\n"; - } else { - $config = $this->_sortRootElements($this->_config); - foreach ($config as $sectionName => $data) { - if (!($data instanceof Zend_Config)) { - $iniString .= $sectionName - . ' = ' - . $this->_prepareValue($data) - . "\n"; - } else { - if (isset($extends[$sectionName])) { - $sectionName .= ' : ' . $extends[$sectionName]; - } - - $iniString .= '[' . $sectionName . ']' . "\n" - . $this->_addBranch($data) - . "\n"; - } - } - } - - return $iniString; - } - - /** - * Add a branch to an INI string recursively - * - * @param Zend_Config $config - * @return void - */ - protected function _addBranch(Zend_Config $config, $parents = array()) - { - $iniString = ''; - - foreach ($config as $key => $value) { - $group = array_merge($parents, array($key)); - - if ($value instanceof Zend_Config) { - $iniString .= $this->_addBranch($value, $group); - } else { - $iniString .= implode($this->_nestSeparator, $group) - . ' = ' - . $this->_prepareValue($value) - . "\n"; - } - } - - return $iniString; - } - - /** - * Prepare a value for INI - * - * @param mixed $value - * @return string - */ - protected function _prepareValue($value) - { - if (is_integer($value) || is_float($value)) { - return $value; - } elseif (is_bool($value)) { - return ($value ? 'true' : 'false'); - } elseif (strpos($value, '"') === false) { - return '"' . $value . '"'; - } else { - /** @see Zend_Config_Exception */ - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Value can not contain double quotes "'); - } - } - - /** - * Root elements that are not assigned to any section needs to be - * on the top of config. - * - * @see http://framework.zend.com/issues/browse/ZF-6289 - * @param Zend_Config - * @return Zend_Config - */ - protected function _sortRootElements(Zend_Config $config) - { - $configArray = $config->toArray(); - $sections = array(); - - // remove sections from config array - foreach ($configArray as $key => $value) { - if (is_array($value)) { - $sections[$key] = $value; - unset($configArray[$key]); - } - } - - // readd sections to the end - foreach ($sections as $key => $value) { - $configArray[$key] = $value; - } - - return new Zend_Config($configArray); - } -} diff --git a/lib/Zend/Config/Writer/Json.php b/lib/Zend/Config/Writer/Json.php deleted file mode 100644 index 99a4a982936..00000000000 --- a/lib/Zend/Config/Writer/Json.php +++ /dev/null @@ -1,106 +0,0 @@ -_prettyPrint; - } - - /** - * Set prettyPrint flag - * - * @param bool $prettyPrint PrettyPrint flag - * @return Zend_Config_Writer_Json - */ - public function setPrettyPrint($flag) - { - $this->_prettyPrint = (bool) $flag; - return $this; - } - - /** - * Render a Zend_Config into a JSON config string. - * - * @since 1.10 - * @return string - */ - public function render() - { - $data = $this->_config->toArray(); - $sectionName = $this->_config->getSectionName(); - $extends = $this->_config->getExtends(); - - if (is_string($sectionName)) { - $data = array($sectionName => $data); - } - - foreach ($extends as $section => $parentSection) { - $data[$section][Zend_Config_Json::EXTENDS_NAME] = $parentSection; - } - - // Ensure that each "extends" section actually exists - foreach ($data as $section => $sectionData) { - if (is_array($sectionData) && isset($sectionData[Zend_Config_Json::EXTENDS_NAME])) { - $sectionExtends = $sectionData[Zend_Config_Json::EXTENDS_NAME]; - if (!isset($data[$sectionExtends])) { - // Remove "extends" declaration if section does not exist - unset($data[$section][Zend_Config_Json::EXTENDS_NAME]); - } - } - } - - $out = Zend_Json::encode($data); - if ($this->prettyPrint()) { - $out = Zend_Json::prettyPrint($out); - } - return $out; - } -} diff --git a/lib/Zend/Config/Writer/Xml.php b/lib/Zend/Config/Writer/Xml.php deleted file mode 100644 index 18fc3b82fcb..00000000000 --- a/lib/Zend/Config/Writer/Xml.php +++ /dev/null @@ -1,127 +0,0 @@ -'); - $extends = $this->_config->getExtends(); - $sectionName = $this->_config->getSectionName(); - - if (is_string($sectionName)) { - $child = $xml->addChild($sectionName); - - $this->_addBranch($this->_config, $child, $xml); - } else { - foreach ($this->_config as $sectionName => $data) { - if (!($data instanceof Zend_Config)) { - $xml->addChild($sectionName, (string) $data); - } else { - $child = $xml->addChild($sectionName); - - if (isset($extends[$sectionName])) { - $child->addAttribute('zf:extends', $extends[$sectionName], Zend_Config_Xml::XML_NAMESPACE); - } - - $this->_addBranch($data, $child, $xml); - } - } - } - - $dom = dom_import_simplexml($xml)->ownerDocument; - $dom->formatOutput = true; - - $xmlString = $dom->saveXML(); - - return $xmlString; - } - - /** - * Add a branch to an XML object recursively - * - * @param Zend_Config $config - * @param SimpleXMLElement $xml - * @param SimpleXMLElement $parent - * @return void - */ - protected function _addBranch(Zend_Config $config, SimpleXMLElement $xml, SimpleXMLElement $parent) - { - $branchType = null; - - foreach ($config as $key => $value) { - if ($branchType === null) { - if (is_numeric($key)) { - $branchType = 'numeric'; - $branchName = $xml->getName(); - $xml = $parent; - - unset($parent->{$branchName}); - } else { - $branchType = 'string'; - } - } else if ($branchType !== (is_numeric($key) ? 'numeric' : 'string')) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Mixing of string and numeric keys is not allowed'); - } - - if ($branchType === 'numeric') { - if ($value instanceof Zend_Config) { - $child = $parent->addChild($branchName); - - $this->_addBranch($value, $child, $parent); - } else { - $parent->addChild($branchName, (string) $value); - } - } else { - if ($value instanceof Zend_Config) { - $child = $xml->addChild($key); - - $this->_addBranch($value, $child, $xml); - } else { - $xml->addChild($key, (string) $value); - } - } - } - } -} diff --git a/lib/Zend/Config/Writer/Yaml.php b/lib/Zend/Config/Writer/Yaml.php deleted file mode 100644 index 2b1aeba4c98..00000000000 --- a/lib/Zend/Config/Writer/Yaml.php +++ /dev/null @@ -1,144 +0,0 @@ -_yamlEncoder; - } - - /** - * Set callback for decoding YAML - * - * @param callable $yamlEncoder the decoder to set - * @return Zend_Config_Yaml - */ - public function setYamlEncoder($yamlEncoder) - { - if (!is_callable($yamlEncoder)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Invalid parameter to setYamlEncoder - must be callable'); - } - - $this->_yamlEncoder = $yamlEncoder; - return $this; - } - - /** - * Render a Zend_Config into a YAML config string. - * - * @since 1.10 - * @return string - */ - public function render() - { - $data = $this->_config->toArray(); - $sectionName = $this->_config->getSectionName(); - $extends = $this->_config->getExtends(); - - if (is_string($sectionName)) { - $data = array($sectionName => $data); - } - - foreach ($extends as $section => $parentSection) { - $data[$section][Zend_Config_Yaml::EXTENDS_NAME] = $parentSection; - } - - // Ensure that each "extends" section actually exists - foreach ($data as $section => $sectionData) { - if (is_array($sectionData) && isset($sectionData[Zend_Config_Yaml::EXTENDS_NAME])) { - $sectionExtends = $sectionData[Zend_Config_Yaml::EXTENDS_NAME]; - if (!isset($data[$sectionExtends])) { - // Remove "extends" declaration if section does not exist - unset($data[$section][Zend_Config_Yaml::EXTENDS_NAME]); - } - } - } - - return call_user_func($this->getYamlEncoder(), $data); - } - - /** - * Very dumb YAML encoder - * - * Until we have Zend_Yaml... - * - * @param array $data YAML data - * @return string - */ - public static function encode($data) - { - return self::_encodeYaml(0, $data); - } - - /** - * Service function for encoding YAML - * - * @param int $indent Current indent level - * @param array $data Data to encode - * @return string - */ - protected static function _encodeYaml($indent, $data) - { - reset($data); - $result = ""; - $numeric = is_numeric(key($data)); - - foreach($data as $key => $value) { - if(is_array($value)) { - $encoded = "\n".self::_encodeYaml($indent+1, $value); - } else { - $encoded = (string)$value."\n"; - } - $result .= str_repeat(" ", $indent).($numeric?"- ":"$key: ").$encoded; - } - return $result; - } -} diff --git a/lib/Zend/Config/Xml.php b/lib/Zend/Config/Xml.php deleted file mode 100644 index ceef39eb0a6..00000000000 --- a/lib/Zend/Config/Xml.php +++ /dev/null @@ -1,314 +0,0 @@ - false, - * 'skipExtends' => false - * ); - * - * @param string $xml XML file or string to process - * @param mixed $section Section to process - * @param array|boolean $options - * @throws Zend_Config_Exception When xml is not set or cannot be loaded - * @throws Zend_Config_Exception When section $sectionName cannot be found in $xml - */ - public function __construct($xml, $section = null, $options = false) - { - if (empty($xml)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Filename is not set'); - } - - $allowModifications = false; - if (is_bool($options)) { - $allowModifications = $options; - } elseif (is_array($options)) { - if (isset($options['allowModifications'])) { - $allowModifications = (bool) $options['allowModifications']; - } - if (isset($options['skipExtends'])) { - $this->_skipExtends = (bool) $options['skipExtends']; - } - } - - set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed - if (strstr($xml, 'getMessage() - ); - } - } - - restore_error_handler(); - // Check if there was a error while loading file - if ($this->_loadFileErrorStr !== null) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception($this->_loadFileErrorStr); - } - - if ($section === null) { - $dataArray = array(); - foreach ($config as $sectionName => $sectionData) { - $dataArray[$sectionName] = $this->_processExtends($config, $sectionName); - } - - parent::__construct($dataArray, $allowModifications); - } else if (is_array($section)) { - $dataArray = array(); - foreach ($section as $sectionName) { - if (!isset($config->$sectionName)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Section '$sectionName' cannot be found in $xml"); - } - - $dataArray = array_merge($this->_processExtends($config, $sectionName), $dataArray); - } - - parent::__construct($dataArray, $allowModifications); - } else { - if (!isset($config->$section)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Section '$section' cannot be found in $xml"); - } - - $dataArray = $this->_processExtends($config, $section); - if (!is_array($dataArray)) { - // Section in the XML file contains just one top level string - $dataArray = array($section => $dataArray); - } - - parent::__construct($dataArray, $allowModifications); - } - - $this->_loadedSection = $section; - } - - /** - * Helper function to process each element in the section and handle - * the "extends" inheritance attribute. - * - * @param SimpleXMLElement $element XML Element to process - * @param string $section Section to process - * @param array $config Configuration which was parsed yet - * @throws Zend_Config_Exception When $section cannot be found - * @return array - */ - protected function _processExtends(SimpleXMLElement $element, $section, array $config = array()) - { - if (!isset($element->$section)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Section '$section' cannot be found"); - } - - $thisSection = $element->$section; - $nsAttributes = $thisSection->attributes(self::XML_NAMESPACE); - - if (isset($thisSection['extends']) || isset($nsAttributes['extends'])) { - $extendedSection = (string) (isset($nsAttributes['extends']) ? $nsAttributes['extends'] : $thisSection['extends']); - $this->_assertValidExtend($section, $extendedSection); - - if (!$this->_skipExtends) { - $config = $this->_processExtends($element, $extendedSection, $config); - } - } - - $config = $this->_arrayMergeRecursive($config, $this->_toArray($thisSection)); - - return $config; - } - - /** - * Returns a string or an associative and possibly multidimensional array from - * a SimpleXMLElement. - * - * @param SimpleXMLElement $xmlObject Convert a SimpleXMLElement into an array - * @return array|string - */ - protected function _toArray(SimpleXMLElement $xmlObject) - { - $config = array(); - $nsAttributes = $xmlObject->attributes(self::XML_NAMESPACE); - - // Search for parent node values - if (count($xmlObject->attributes()) > 0) { - foreach ($xmlObject->attributes() as $key => $value) { - if ($key === 'extends') { - continue; - } - - $value = (string) $value; - - if (array_key_exists($key, $config)) { - if (!is_array($config[$key])) { - $config[$key] = array($config[$key]); - } - - $config[$key][] = $value; - } else { - $config[$key] = $value; - } - } - } - - // Search for local 'const' nodes and replace them - if (count($xmlObject->children(self::XML_NAMESPACE)) > 0) { - if (count($xmlObject->children()) > 0) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("A node with a 'const' childnode may not have any other children"); - } - - $dom = dom_import_simplexml($xmlObject); - $namespaceChildNodes = array(); - - // We have to store them in an array, as replacing nodes will - // confuse the DOMNodeList later - foreach ($dom->childNodes as $node) { - if ($node instanceof DOMElement && $node->namespaceURI === self::XML_NAMESPACE) { - $namespaceChildNodes[] = $node; - } - } - - foreach ($namespaceChildNodes as $node) { - switch ($node->localName) { - case 'const': - if (!$node->hasAttributeNS(self::XML_NAMESPACE, 'name')) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Misssing 'name' attribute in 'const' node"); - } - - $constantName = $node->getAttributeNS(self::XML_NAMESPACE, 'name'); - - if (!defined($constantName)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Constant with name '$constantName' was not defined"); - } - - $constantValue = constant($constantName); - - $dom->replaceChild($dom->ownerDocument->createTextNode($constantValue), $node); - break; - - default: - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Unknown node with name '$node->localName' found"); - } - } - - return (string) simplexml_import_dom($dom); - } - - // Search for children - if (count($xmlObject->children()) > 0) { - foreach ($xmlObject->children() as $key => $value) { - if (count($value->children()) > 0 || count($value->children(self::XML_NAMESPACE)) > 0) { - $value = $this->_toArray($value); - } else if (count($value->attributes()) > 0) { - $attributes = $value->attributes(); - if (isset($attributes['value'])) { - $value = (string) $attributes['value']; - } else { - $value = $this->_toArray($value); - } - } else { - $value = (string) $value; - } - - if (array_key_exists($key, $config)) { - if (!is_array($config[$key]) || !array_key_exists(0, $config[$key])) { - $config[$key] = array($config[$key]); - } - - $config[$key][] = $value; - } else { - $config[$key] = $value; - } - } - } else if (!isset($xmlObject['extends']) && !isset($nsAttributes['extends']) && (count($config) === 0)) { - // Object has no children nor attributes and doesn't use the extends - // attribute: it's a string - $config = (string) $xmlObject; - } - - return $config; - } -} diff --git a/lib/Zend/Config/Yaml.php b/lib/Zend/Config/Yaml.php deleted file mode 100644 index b11a407330a..00000000000 --- a/lib/Zend/Config/Yaml.php +++ /dev/null @@ -1,415 +0,0 @@ -_yamlDecoder; - } - - /** - * Set callback for decoding YAML - * - * @param callable $yamlDecoder the decoder to set - * @return Zend_Config_Yaml - */ - public function setYamlDecoder($yamlDecoder) - { - if (!is_callable($yamlDecoder)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Invalid parameter to setYamlDecoder() - must be callable'); - } - - $this->_yamlDecoder = $yamlDecoder; - return $this; - } - - /** - * Loads the section $section from the config file encoded as YAML - * - * Sections are defined as properties of the main object - * - * In order to extend another section, a section defines the "_extends" - * property having a value of the section name from which the extending - * section inherits values. - * - * Note that the keys in $section will override any keys of the same - * name in the sections that have been included via "_extends". - * - * Options may include: - * - allow_modifications: whether or not the config object is mutable - * - skip_extends: whether or not to skip processing of parent configuration - * - yaml_decoder: a callback to use to decode the Yaml source - * - * @param string $yaml YAML file to process - * @param mixed $section Section to process - * @param array|boolean $options - */ - public function __construct($yaml, $section = null, $options = false) - { - if (empty($yaml)) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception('Filename is not set'); - } - - $ignoreConstants = $staticIgnoreConstants = self::ignoreConstants(); - $allowModifications = false; - if (is_bool($options)) { - $allowModifications = $options; - } elseif (is_array($options)) { - foreach ($options as $key => $value) { - switch (strtolower($key)) { - case 'allow_modifications': - case 'allowmodifications': - $allowModifications = (bool) $value; - break; - case 'skip_extends': - case 'skipextends': - $this->_skipExtends = (bool) $value; - break; - case 'ignore_constants': - case 'ignoreconstants': - $ignoreConstants = (bool) $value; - break; - case 'yaml_decoder': - case 'yamldecoder': - $this->setYamlDecoder($value); - break; - default: - break; - } - } - } - - // Suppress warnings and errors while loading file - set_error_handler(array($this, '_loadFileErrorHandler')); - $yaml = file_get_contents($yaml); - restore_error_handler(); - - // Check if there was a error while loading file - if ($this->_loadFileErrorStr !== null) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception($this->_loadFileErrorStr); - } - - // Override static value for ignore_constants if provided in $options - self::setIgnoreConstants($ignoreConstants); - - // Parse YAML - $config = call_user_func($this->getYamlDecoder(), $yaml); - - // Reset original static state of ignore_constants - self::setIgnoreConstants($staticIgnoreConstants); - - if (null === $config) { - // decode failed - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception("Error parsing YAML data"); - } - - if (null === $section) { - $dataArray = array(); - foreach ($config as $sectionName => $sectionData) { - $dataArray[$sectionName] = $this->_processExtends($config, $sectionName); - } - parent::__construct($dataArray, $allowModifications); - } elseif (is_array($section)) { - $dataArray = array(); - foreach ($section as $sectionName) { - if (!isset($config[$sectionName])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf( - 'Section "%s" cannot be found', - implode(' ', (array)$section) - )); - } - - $dataArray = array_merge($this->_processExtends($config, $sectionName), $dataArray); - } - parent::__construct($dataArray, $allowModifications); - } else { - if (!isset($config[$section])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf( - 'Section "%s" cannot be found', - implode(' ', (array)$section) - )); - } - - $dataArray = $this->_processExtends($config, $section); - if (!is_array($dataArray)) { - // Section in the yaml data contains just one top level string - $dataArray = array($section => $dataArray); - } - parent::__construct($dataArray, $allowModifications); - } - - $this->_loadedSection = $section; - } - - /** - * Helper function to process each element in the section and handle - * the "_extends" inheritance attribute. - * - * @param array $data Data array to process - * @param string $section Section to process - * @param array $config Configuration which was parsed yet - * @return array - * @throws Zend_Config_Exception When $section cannot be found - */ - protected function _processExtends(array $data, $section, array $config = array()) - { - if (!isset($data[$section])) { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $section)); - } - - $thisSection = $data[$section]; - - if (is_array($thisSection) && isset($thisSection[self::EXTENDS_NAME])) { - $this->_assertValidExtend($section, $thisSection[self::EXTENDS_NAME]); - - if (!$this->_skipExtends) { - $config = $this->_processExtends($data, $thisSection[self::EXTENDS_NAME], $config); - } - unset($thisSection[self::EXTENDS_NAME]); - } - - $config = $this->_arrayMergeRecursive($config, $thisSection); - - return $config; - } - - /** - * Very dumb YAML parser - * - * Until we have Zend_Yaml... - * - * @param string $yaml YAML source - * @return array Decoded data - */ - public static function decode($yaml) - { - $lines = explode("\n", $yaml); - reset($lines); - return self::_decodeYaml(0, $lines); - } - - /** - * Service function to decode YAML - * - * @param int $currentIndent Current indent level - * @param array $lines YAML lines - * @return array|string - */ - protected static function _decodeYaml($currentIndent, &$lines) - { - $config = array(); - $inIndent = false; - foreach($lines as $n => $line) { - $lineno = $n + 1; - - $line = rtrim(preg_replace("/#.*$/", "", $line)); - if (strlen($line) == 0) { - continue; - } - - $indent = strspn($line, " "); - - // line without the spaces - $line = trim($line); - if (strlen($line) == 0) { - continue; - } - - if ($indent < $currentIndent) { - // this level is done - prev($lines); - return $config; - } - - if (!$inIndent) { - $currentIndent = $indent; - $inIndent = true; - } - - if (preg_match("/(?!-)([\w\-]+):\s*(.*)/", $line, $m)) { - // key: value - if (strlen($m[2])) { - // simple key: value - $value = preg_replace("/#.*$/", "", $m[2]); - $value = self::_parseValue($value); - } else { - // key: and then values on new lines - $value = self::_decodeYaml($currentIndent + 1, $lines); - if (is_array($value) && !count($value)) { - $value = ""; - } - } - $config[$m[1]] = $value; - } elseif ($line[0] == "-") { - // item in the list: - // - FOO - if (strlen($line) > 2) { - $value = substr($line, 2); - - $config[] = self::_parseValue($value); - } else { - $config[] = self::_decodeYaml($currentIndent + 1, $lines); - } - } else { - #require_once 'Zend/Config/Exception.php'; - throw new Zend_Config_Exception(sprintf( - 'Error parsing YAML at line %d - unsupported syntax: "%s"', - $lineno, $line - )); - } - } - return $config; - } - - /** - * Parse values - * - * @param string $value - * @return string - */ - protected static function _parseValue($value) - { - $value = trim($value); - - // remove quotes from string. - if ('"' == $value['0']) { - if ('"' == $value[count($value) -1]) { - $value = substr($value, 1, -1); - } - } elseif ('\'' == $value['0'] && '\'' == $value[count($value) -1]) { - $value = strtr($value, array("''" => "'", "'" => '')); - } - - // Check for booleans and constants - if (preg_match('/^(t(rue)?|on|y(es)?)$/i', $value)) { - $value = true; - } elseif (preg_match('/^(f(alse)?|off|n(o)?)$/i', $value)) { - $value = false; - } elseif (strcasecmp($value, 'null') === 0) { - $value = null; - } elseif (!self::$_ignoreConstants) { - // test for constants - $value = self::_replaceConstants($value); - } - - return $value; - } - - /** - * Replace any constants referenced in a string with their values - * - * @param string $value - * @return string - */ - protected static function _replaceConstants($value) - { - foreach (self::_getConstants() as $constant) { - if (strstr($value, $constant)) { - $value = str_replace($constant, constant($constant), $value); - } - } - return $value; - } - - /** - * Get (reverse) sorted list of defined constant names - * - * @return array - */ - protected static function _getConstants() - { - $constants = array_keys(get_defined_constants()); - rsort($constants, SORT_STRING); - return $constants; - } -} diff --git a/lib/Zend/Console/Getopt.php b/lib/Zend/Console/Getopt.php deleted file mode 100644 index 332b986bd40..00000000000 --- a/lib/Zend/Console/Getopt.php +++ /dev/null @@ -1,992 +0,0 @@ - self::MODE_ZEND, - self::CONFIG_DASHDASH => true, - self::CONFIG_IGNORECASE => false, - self::CONFIG_PARSEALL => true, - ); - - /** - * Stores the command-line arguments for the calling application. - * - * @var array - */ - protected $_argv = array(); - - /** - * Stores the name of the calling application. - * - * @var string - */ - protected $_progname = ''; - - /** - * Stores the list of legal options for this application. - * - * @var array - */ - protected $_rules = array(); - - /** - * Stores alternate spellings of legal options. - * - * @var array - */ - protected $_ruleMap = array(); - - /** - * Stores options given by the user in the current invocation - * of the application, as well as parameters given in options. - * - * @var array - */ - protected $_options = array(); - - /** - * Stores the command-line arguments other than options. - * - * @var array - */ - protected $_remainingArgs = array(); - - /** - * State of the options: parsed or not yet parsed? - * - * @var boolean - */ - protected $_parsed = false; - - /** - * The constructor takes one to three parameters. - * - * The first parameter is $rules, which may be a string for - * gnu-style format, or a structured array for Zend-style format. - * - * The second parameter is $argv, and it is optional. If not - * specified, $argv is inferred from the global argv. - * - * The third parameter is an array of configuration parameters - * to control the behavior of this instance of Getopt; it is optional. - * - * @param array $rules - * @param array $argv - * @param array $getoptConfig - * @return void - */ - public function __construct($rules, $argv = null, $getoptConfig = array()) - { - if (!isset($_SERVER['argv'])) { - #require_once 'Zend/Console/Getopt/Exception.php'; - if (ini_get('register_argc_argv') == false) { - throw new Zend_Console_Getopt_Exception( - "argv is not available, because ini option 'register_argc_argv' is set Off" - ); - } else { - throw new Zend_Console_Getopt_Exception( - '$_SERVER["argv"] is not set, but Zend_Console_Getopt cannot work without this information.' - ); - } - } - - $this->_progname = $_SERVER['argv'][0]; - $this->setOptions($getoptConfig); - $this->addRules($rules); - if (!is_array($argv)) { - $argv = array_slice($_SERVER['argv'], 1); - } - if (isset($argv)) { - $this->addArguments((array)$argv); - } - } - - /** - * Return the state of the option seen on the command line of the - * current application invocation. This function returns true, or the - * parameter to the option, if any. If the option was not given, - * this function returns null. - * - * The magic __get method works in the context of naming the option - * as a virtual member of this class. - * - * @param string $key - * @return string - */ - public function __get($key) - { - return $this->getOption($key); - } - - /** - * Test whether a given option has been seen. - * - * @param string $key - * @return boolean - */ - public function __isset($key) - { - $this->parse(); - if (isset($this->_ruleMap[$key])) { - $key = $this->_ruleMap[$key]; - return isset($this->_options[$key]); - } - return false; - } - - /** - * Set the value for a given option. - * - * @param string $key - * @param string $value - * @return void - */ - public function __set($key, $value) - { - $this->parse(); - if (isset($this->_ruleMap[$key])) { - $key = $this->_ruleMap[$key]; - $this->_options[$key] = $value; - } - } - - /** - * Return the current set of options and parameters seen as a string. - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Unset an option. - * - * @param string $key - * @return void - */ - public function __unset($key) - { - $this->parse(); - if (isset($this->_ruleMap[$key])) { - $key = $this->_ruleMap[$key]; - unset($this->_options[$key]); - } - } - - /** - * Define additional command-line arguments. - * These are appended to those defined when the constructor was called. - * - * @param array $argv - * @throws Zend_Console_Getopt_Exception When not given an array as parameter - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function addArguments($argv) - { - if(!is_array($argv)) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Parameter #1 to addArguments should be an array"); - } - $this->_argv = array_merge($this->_argv, $argv); - $this->_parsed = false; - return $this; - } - - /** - * Define full set of command-line arguments. - * These replace any currently defined. - * - * @param array $argv - * @throws Zend_Console_Getopt_Exception When not given an array as parameter - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function setArguments($argv) - { - if(!is_array($argv)) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Parameter #1 to setArguments should be an array"); - } - $this->_argv = $argv; - $this->_parsed = false; - return $this; - } - - /** - * Define multiple configuration options from an associative array. - * These are not program options, but properties to configure - * the behavior of Zend_Console_Getopt. - * - * @param array $getoptConfig - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function setOptions($getoptConfig) - { - if (isset($getoptConfig)) { - foreach ($getoptConfig as $key => $value) { - $this->setOption($key, $value); - } - } - return $this; - } - - /** - * Define one configuration option as a key/value pair. - * These are not program options, but properties to configure - * the behavior of Zend_Console_Getopt. - * - * @param string $configKey - * @param string $configValue - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function setOption($configKey, $configValue) - { - if ($configKey !== null) { - $this->_getoptConfig[$configKey] = $configValue; - } - return $this; - } - - /** - * Define additional option rules. - * These are appended to the rules defined when the constructor was called. - * - * @param array $rules - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function addRules($rules) - { - $ruleMode = $this->_getoptConfig['ruleMode']; - switch ($this->_getoptConfig['ruleMode']) { - case self::MODE_ZEND: - if (is_array($rules)) { - $this->_addRulesModeZend($rules); - break; - } - // intentional fallthrough - case self::MODE_GNU: - $this->_addRulesModeGnu($rules); - break; - default: - /** - * Call addRulesModeFoo() for ruleMode 'foo'. - * The developer should subclass Getopt and - * provide this method. - */ - $method = '_addRulesMode' . ucfirst($ruleMode); - $this->$method($rules); - } - $this->_parsed = false; - return $this; - } - - /** - * Return the current set of options and parameters seen as a string. - * - * @return string - */ - public function toString() - { - $this->parse(); - $s = array(); - foreach ($this->_options as $flag => $value) { - $s[] = $flag . '=' . ($value === true ? 'true' : $value); - } - return implode(' ', $s); - } - - /** - * Return the current set of options and parameters seen - * as an array of canonical options and parameters. - * - * Clusters have been expanded, and option aliases - * have been mapped to their primary option names. - * - * @return array - */ - public function toArray() - { - $this->parse(); - $s = array(); - foreach ($this->_options as $flag => $value) { - $s[] = $flag; - if ($value !== true) { - $s[] = $value; - } - } - return $s; - } - - /** - * Return the current set of options and parameters seen in Json format. - * - * @return string - */ - public function toJson() - { - $this->parse(); - $j = array(); - foreach ($this->_options as $flag => $value) { - $j['options'][] = array( - 'option' => array( - 'flag' => $flag, - 'parameter' => $value - ) - ); - } - - /** - * @see Zend_Json - */ - #require_once 'Zend/Json.php'; - $json = Zend_Json::encode($j); - - return $json; - } - - /** - * Return the current set of options and parameters seen in XML format. - * - * @return string - */ - public function toXml() - { - $this->parse(); - $doc = new DomDocument('1.0', 'utf-8'); - $optionsNode = $doc->createElement('options'); - $doc->appendChild($optionsNode); - foreach ($this->_options as $flag => $value) { - $optionNode = $doc->createElement('option'); - $optionNode->setAttribute('flag', utf8_encode($flag)); - if ($value !== true) { - $optionNode->setAttribute('parameter', utf8_encode($value)); - } - $optionsNode->appendChild($optionNode); - } - $xml = $doc->saveXML(); - return $xml; - } - - /** - * Return a list of options that have been seen in the current argv. - * - * @return array - */ - public function getOptions() - { - $this->parse(); - return array_keys($this->_options); - } - - /** - * Return the state of the option seen on the command line of the - * current application invocation. - * - * This function returns true, or the parameter value to the option, if any. - * If the option was not given, this function returns null. - * - * @param string $flag - * @return mixed - */ - public function getOption($flag) - { - $this->parse(); - if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { - $flag = strtolower($flag); - } - if (isset($this->_ruleMap[$flag])) { - $flag = $this->_ruleMap[$flag]; - if (isset($this->_options[$flag])) { - return $this->_options[$flag]; - } - } - return null; - } - - /** - * Return the arguments from the command-line following all options found. - * - * @return array - */ - public function getRemainingArgs() - { - $this->parse(); - return $this->_remainingArgs; - } - - /** - * Return a useful option reference, formatted for display in an - * error message. - * - * Note that this usage information is provided in most Exceptions - * generated by this class. - * - * @return string - */ - public function getUsageMessage() - { - $usage = "Usage: {$this->_progname} [ options ]\n"; - $maxLen = 20; - $lines = array(); - foreach ($this->_rules as $rule) { - $flags = array(); - if (is_array($rule['alias'])) { - foreach ($rule['alias'] as $flag) { - $flags[] = (strlen($flag) == 1 ? '-' : '--') . $flag; - } - } - $linepart['name'] = implode('|', $flags); - if (isset($rule['param']) && $rule['param'] != 'none') { - $linepart['name'] .= ' '; - switch ($rule['param']) { - case 'optional': - $linepart['name'] .= "[ <{$rule['paramType']}> ]"; - break; - case 'required': - $linepart['name'] .= "<{$rule['paramType']}>"; - break; - } - } - if (strlen($linepart['name']) > $maxLen) { - $maxLen = strlen($linepart['name']); - } - $linepart['help'] = ''; - if (isset($rule['help'])) { - $linepart['help'] .= $rule['help']; - } - $lines[] = $linepart; - } - foreach ($lines as $linepart) { - $usage .= sprintf("%s %s\n", - str_pad($linepart['name'], $maxLen), - $linepart['help']); - } - return $usage; - } - - /** - * Define aliases for options. - * - * The parameter $aliasMap is an associative array - * mapping option name (short or long) to an alias. - * - * @param array $aliasMap - * @throws Zend_Console_Getopt_Exception - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function setAliases($aliasMap) - { - foreach ($aliasMap as $flag => $alias) - { - if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { - $flag = strtolower($flag); - $alias = strtolower($alias); - } - if (!isset($this->_ruleMap[$flag])) { - continue; - } - $flag = $this->_ruleMap[$flag]; - if (isset($this->_rules[$alias]) || isset($this->_ruleMap[$alias])) { - $o = (strlen($alias) == 1 ? '-' : '--') . $alias; - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"$o\" is being defined more than once."); - } - $this->_rules[$flag]['alias'][] = $alias; - $this->_ruleMap[$alias] = $flag; - } - return $this; - } - - /** - * Define help messages for options. - * - * The parameter $help_map is an associative array - * mapping option name (short or long) to the help string. - * - * @param array $helpMap - * @return Zend_Console_Getopt Provides a fluent interface - */ - public function setHelp($helpMap) - { - foreach ($helpMap as $flag => $help) - { - if (!isset($this->_ruleMap[$flag])) { - continue; - } - $flag = $this->_ruleMap[$flag]; - $this->_rules[$flag]['help'] = $help; - } - return $this; - } - - /** - * Parse command-line arguments and find both long and short - * options. - * - * Also find option parameters, and remaining arguments after - * all options have been parsed. - * - * @return Zend_Console_Getopt|null Provides a fluent interface - */ - public function parse() - { - if ($this->_parsed === true) { - return; - } - $argv = $this->_argv; - $this->_options = array(); - $this->_remainingArgs = array(); - while (count($argv) > 0) { - if ($argv[0] == '--') { - array_shift($argv); - if ($this->_getoptConfig[self::CONFIG_DASHDASH]) { - $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); - break; - } - } - if (substr($argv[0], 0, 2) == '--') { - $this->_parseLongOption($argv); - } else if (substr($argv[0], 0, 1) == '-' && ('-' != $argv[0] || count($argv) >1)) { - $this->_parseShortOptionCluster($argv); - } else if($this->_getoptConfig[self::CONFIG_PARSEALL]) { - $this->_remainingArgs[] = array_shift($argv); - } else { - /* - * We should put all other arguments in _remainingArgs and stop parsing - * since CONFIG_PARSEALL is false. - */ - $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); - break; - } - } - $this->_parsed = true; - return $this; - } - - /** - * @throws Zend_Console_Getopt_Exception - */ - public function checkRequiredArguments() - { - foreach ($this->_rules as $name => $rule) { - if ($rule['param'] === 'required') { - $defined = false; - foreach ($rule['alias'] as $alias) { - $defined = $defined === true ? true : array_key_exists($alias, $this->_options); - } - if ($defined === false) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - 'Option "$alias" requires a parameter.', - $this->getUsageMessage() - ); - } - } - } - } - - /** - * Parse command-line arguments for a single long option. - * A long option is preceded by a double '--' character. - * Long options may not be clustered. - * - * @param mixed &$argv - * @return void - */ - protected function _parseLongOption(&$argv) - { - $optionWithParam = ltrim(array_shift($argv), '-'); - $l = explode('=', $optionWithParam, 2); - $flag = array_shift($l); - $param = array_shift($l); - if (isset($param)) { - array_unshift($argv, $param); - } - $this->_parseSingleOption($flag, $argv); - } - - /** - * Parse command-line arguments for short options. - * Short options are those preceded by a single '-' character. - * Short options may be clustered. - * - * @param mixed &$argv - * @return void - */ - protected function _parseShortOptionCluster(&$argv) - { - $flagCluster = ltrim(array_shift($argv), '-'); - foreach (str_split($flagCluster) as $flag) { - $this->_parseSingleOption($flag, $argv); - } - } - - /** - * Parse command-line arguments for a single option. - * - * @param string $flag - * @param mixed $argv - * @throws Zend_Console_Getopt_Exception - * @return void - */ - protected function _parseSingleOption($flag, &$argv) - { - if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { - $flag = strtolower($flag); - } - if (!isset($this->_ruleMap[$flag])) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"$flag\" is not recognized.", - $this->getUsageMessage()); - } - $realFlag = $this->_ruleMap[$flag]; - switch ($this->_rules[$realFlag]['param']) { - case 'required': - if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') { - $param = array_shift($argv); - $this->_checkParameterType($realFlag, $param); - } else { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"$flag\" requires a parameter.", - $this->getUsageMessage()); - } - break; - case 'optional': - if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') { - $param = array_shift($argv); - $this->_checkParameterType($realFlag, $param); - } else { - $param = true; - } - break; - default: - $param = true; - } - $this->_options[$realFlag] = $param; - } - - /** - * Return true if the parameter is in a valid format for - * the option $flag. - * Throw an exception in most other cases. - * - * @param string $flag - * @param string $param - * @throws Zend_Console_Getopt_Exception - * @return bool - */ - protected function _checkParameterType($flag, $param) - { - $type = 'string'; - if (isset($this->_rules[$flag]['paramType'])) { - $type = $this->_rules[$flag]['paramType']; - } - switch ($type) { - case 'word': - if (preg_match('/\W/', $param)) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"$flag\" requires a single-word parameter, but was given \"$param\".", - $this->getUsageMessage()); - } - break; - case 'integer': - if (preg_match('/\D/', $param)) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"$flag\" requires an integer parameter, but was given \"$param\".", - $this->getUsageMessage()); - } - break; - case 'string': - default: - break; - } - return true; - } - - /** - * Define legal options using the gnu-style format. - * - * @param string $rules - * @return void - */ - protected function _addRulesModeGnu($rules) - { - $ruleArray = array(); - - /** - * Options may be single alphanumeric characters. - * Options may have a ':' which indicates a required string parameter. - * No long options or option aliases are supported in GNU style. - */ - preg_match_all('/([a-zA-Z0-9]:?)/', $rules, $ruleArray); - foreach ($ruleArray[1] as $rule) { - $r = array(); - $flag = substr($rule, 0, 1); - if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { - $flag = strtolower($flag); - } - $r['alias'][] = $flag; - if (substr($rule, 1, 1) == ':') { - $r['param'] = 'required'; - $r['paramType'] = 'string'; - } else { - $r['param'] = 'none'; - } - $this->_rules[$flag] = $r; - $this->_ruleMap[$flag] = $flag; - } - } - - /** - * Define legal options using the Zend-style format. - * - * @param array $rules - * @throws Zend_Console_Getopt_Exception - * @return void - */ - protected function _addRulesModeZend($rules) - { - foreach ($rules as $ruleCode => $helpMessage) - { - // this may have to translate the long parm type if there - // are any complaints that =string will not work (even though that use - // case is not documented) - if (in_array(substr($ruleCode, -2, 1), array('-', '='))) { - $flagList = substr($ruleCode, 0, -2); - $delimiter = substr($ruleCode, -2, 1); - $paramType = substr($ruleCode, -1); - } else { - $flagList = $ruleCode; - $delimiter = $paramType = null; - } - if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { - $flagList = strtolower($flagList); - } - $flags = explode('|', $flagList); - $rule = array(); - $mainFlag = $flags[0]; - foreach ($flags as $flag) { - if (empty($flag)) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Blank flag not allowed in rule \"$ruleCode\"."); - } - if (strlen($flag) == 1) { - if (isset($this->_ruleMap[$flag])) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"-$flag\" is being defined more than once."); - } - $this->_ruleMap[$flag] = $mainFlag; - $rule['alias'][] = $flag; - } else { - if (isset($this->_rules[$flag]) || isset($this->_ruleMap[$flag])) { - #require_once 'Zend/Console/Getopt/Exception.php'; - throw new Zend_Console_Getopt_Exception( - "Option \"--$flag\" is being defined more than once."); - } - $this->_ruleMap[$flag] = $mainFlag; - $rule['alias'][] = $flag; - } - } - if (isset($delimiter)) { - switch ($delimiter) { - case self::PARAM_REQUIRED: - $rule['param'] = 'required'; - break; - case self::PARAM_OPTIONAL: - default: - $rule['param'] = 'optional'; - } - switch (substr($paramType, 0, 1)) { - case self::TYPE_WORD: - $rule['paramType'] = 'word'; - break; - case self::TYPE_INTEGER: - $rule['paramType'] = 'integer'; - break; - case self::TYPE_STRING: - default: - $rule['paramType'] = 'string'; - } - } else { - $rule['param'] = 'none'; - } - $rule['help'] = $helpMessage; - $this->_rules[$mainFlag] = $rule; - } - } - -} diff --git a/lib/Zend/Console/Getopt/Exception.php b/lib/Zend/Console/Getopt/Exception.php deleted file mode 100644 index c1ff445b704..00000000000 --- a/lib/Zend/Console/Getopt/Exception.php +++ /dev/null @@ -1,66 +0,0 @@ -usage = $usage; - parent::__construct($message); - } - - /** - * Returns the usage - * - * @return string - */ - public function getUsageMessage() - { - return $this->usage; - } -} diff --git a/lib/Zend/Controller/Action.php b/lib/Zend/Controller/Action.php deleted file mode 100644 index 3821a779d27..00000000000 --- a/lib/Zend/Controller/Action.php +++ /dev/null @@ -1,798 +0,0 @@ -setRequest($request) - ->setResponse($response) - ->_setInvokeArgs($invokeArgs); - $this->_helper = new Zend_Controller_Action_HelperBroker($this); - $this->init(); - } - - /** - * Initialize object - * - * Called from {@link __construct()} as final step of object instantiation. - * - * @return void - */ - public function init() - { - } - - /** - * Initialize View object - * - * Initializes {@link $view} if not otherwise a Zend_View_Interface. - * - * If {@link $view} is not otherwise set, instantiates a new Zend_View - * object, using the 'views' subdirectory at the same level as the - * controller directory for the current module as the base directory. - * It uses this to set the following: - * - script path = views/scripts/ - * - helper path = views/helpers/ - * - filter path = views/filters/ - * - * @return Zend_View_Interface - * @throws Zend_Controller_Exception if base view directory does not exist - */ - public function initView() - { - if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) { - return $this->view; - } - - #require_once 'Zend/View/Interface.php'; - if (isset($this->view) && ($this->view instanceof Zend_View_Interface)) { - return $this->view; - } - - $request = $this->getRequest(); - $module = $request->getModuleName(); - $dirs = $this->getFrontController()->getControllerDirectory(); - if (empty($module) || !isset($dirs[$module])) { - $module = $this->getFrontController()->getDispatcher()->getDefaultModule(); - } - $baseDir = dirname($dirs[$module]) . DIRECTORY_SEPARATOR . 'views'; - if (!file_exists($baseDir) || !is_dir($baseDir)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Missing base view directory ("' . $baseDir . '")'); - } - - #require_once 'Zend/View.php'; - $this->view = new Zend_View(array('basePath' => $baseDir)); - - return $this->view; - } - - /** - * Render a view - * - * Renders a view. By default, views are found in the view script path as - * /.phtml. You may change the script suffix by - * resetting {@link $viewSuffix}. You may omit the controller directory - * prefix by specifying boolean true for $noController. - * - * By default, the rendered contents are appended to the response. You may - * specify the named body content segment to set by specifying a $name. - * - * @see Zend_Controller_Response_Abstract::appendBody() - * @param string|null $action Defaults to action registered in request object - * @param string|null $name Response object named path segment to use; defaults to null - * @param bool $noController Defaults to false; i.e. use controller name as subdir in which to search for view script - * @return void - */ - public function render($action = null, $name = null, $noController = false) - { - if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) { - return $this->_helper->viewRenderer->render($action, $name, $noController); - } - - $view = $this->initView(); - $script = $this->getViewScript($action, $noController); - - $this->getResponse()->appendBody( - $view->render($script), - $name - ); - } - - /** - * Render a given view script - * - * Similar to {@link render()}, this method renders a view script. Unlike render(), - * however, it does not autodetermine the view script via {@link getViewScript()}, - * but instead renders the script passed to it. Use this if you know the - * exact view script name and path you wish to use, or if using paths that do not - * conform to the spec defined with getViewScript(). - * - * By default, the rendered contents are appended to the response. You may - * specify the named body content segment to set by specifying a $name. - * - * @param string $script - * @param string $name - * @return void - */ - public function renderScript($script, $name = null) - { - if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) { - return $this->_helper->viewRenderer->renderScript($script, $name); - } - - $view = $this->initView(); - $this->getResponse()->appendBody( - $view->render($script), - $name - ); - } - - /** - * Construct view script path - * - * Used by render() to determine the path to the view script. - * - * @param string $action Defaults to action registered in request object - * @param bool $noController Defaults to false; i.e. use controller name as subdir in which to search for view script - * @return string - * @throws Zend_Controller_Exception with bad $action - */ - public function getViewScript($action = null, $noController = null) - { - if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) { - $viewRenderer = $this->_helper->getHelper('viewRenderer'); - if (null !== $noController) { - $viewRenderer->setNoController($noController); - } - return $viewRenderer->getViewScript($action); - } - - $request = $this->getRequest(); - if (null === $action) { - $action = $request->getActionName(); - } elseif (!is_string($action)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid action specifier for view render'); - } - - if (null === $this->_delimiters) { - $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher(); - $wordDelimiters = $dispatcher->getWordDelimiter(); - $pathDelimiters = $dispatcher->getPathDelimiter(); - $this->_delimiters = array_unique(array_merge($wordDelimiters, (array) $pathDelimiters)); - } - - $action = str_replace($this->_delimiters, '-', $action); - $script = $action . '.' . $this->viewSuffix; - - if (!$noController) { - $controller = $request->getControllerName(); - $controller = str_replace($this->_delimiters, '-', $controller); - $script = $controller . DIRECTORY_SEPARATOR . $script; - } - - return $script; - } - - /** - * Return the Request object - * - * @return Zend_Controller_Request_Abstract - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Set the Request object - * - * @param Zend_Controller_Request_Abstract $request - * @return Zend_Controller_Action - */ - public function setRequest(Zend_Controller_Request_Abstract $request) - { - $this->_request = $request; - return $this; - } - - /** - * Return the Response object - * - * @return Zend_Controller_Response_Abstract - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Set the Response object - * - * @param Zend_Controller_Response_Abstract $response - * @return Zend_Controller_Action - */ - public function setResponse(Zend_Controller_Response_Abstract $response) - { - $this->_response = $response; - return $this; - } - - /** - * Set invocation arguments - * - * @param array $args - * @return Zend_Controller_Action - */ - protected function _setInvokeArgs(array $args = array()) - { - $this->_invokeArgs = $args; - return $this; - } - - /** - * Return the array of constructor arguments (minus the Request object) - * - * @return array - */ - public function getInvokeArgs() - { - return $this->_invokeArgs; - } - - /** - * Return a single invocation argument - * - * @param string $key - * @return mixed - */ - public function getInvokeArg($key) - { - if (isset($this->_invokeArgs[$key])) { - return $this->_invokeArgs[$key]; - } - - return null; - } - - /** - * Get a helper by name - * - * @param string $helperName - * @return Zend_Controller_Action_Helper_Abstract - */ - public function getHelper($helperName) - { - return $this->_helper->{$helperName}; - } - - /** - * Get a clone of a helper by name - * - * @param string $helperName - * @return Zend_Controller_Action_Helper_Abstract - */ - public function getHelperCopy($helperName) - { - return clone $this->_helper->{$helperName}; - } - - /** - * Set the front controller instance - * - * @param Zend_Controller_Front $front - * @return Zend_Controller_Action - */ - public function setFrontController(Zend_Controller_Front $front) - { - $this->_frontController = $front; - return $this; - } - - /** - * Retrieve Front Controller - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - // Used cache version if found - if (null !== $this->_frontController) { - return $this->_frontController; - } - - // Grab singleton instance, if class has been loaded - if (class_exists('Zend_Controller_Front')) { - $this->_frontController = Zend_Controller_Front::getInstance(); - return $this->_frontController; - } - - // Throw exception in all other cases - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Front controller class has not been loaded'); - } - - /** - * Pre-dispatch routines - * - * Called before action method. If using class with - * {@link Zend_Controller_Front}, it may modify the - * {@link $_request Request object} and reset its dispatched flag in order - * to skip processing the current action. - * - * @return void - */ - public function preDispatch() - { - } - - /** - * Post-dispatch routines - * - * Called after action method execution. If using class with - * {@link Zend_Controller_Front}, it may modify the - * {@link $_request Request object} and reset its dispatched flag in order - * to process an additional action. - * - * Common usages for postDispatch() include rendering content in a sitewide - * template, link url correction, setting headers, etc. - * - * @return void - */ - public function postDispatch() - { - } - - /** - * Proxy for undefined methods. Default behavior is to throw an - * exception on undefined methods, however this function can be - * overridden to implement magic (dynamic) actions, or provide run-time - * dispatching. - * - * @param string $methodName - * @param array $args - * @return void - * @throws Zend_Controller_Action_Exception - */ - public function __call($methodName, $args) - { - #require_once 'Zend/Controller/Action/Exception.php'; - if ('Action' == substr($methodName, -6)) { - $action = substr($methodName, 0, strlen($methodName) - 6); - throw new Zend_Controller_Action_Exception(sprintf('Action "%s" does not exist and was not trapped in __call()', $action), 404); - } - - throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500); - } - - /** - * Dispatch the requested action - * - * @param string $action Method name of action - * @return void - */ - public function dispatch($action) - { - // Notify helpers of action preDispatch state - $this->_helper->notifyPreDispatch(); - - $this->preDispatch(); - if ($this->getRequest()->isDispatched()) { - if (null === $this->_classMethods) { - $this->_classMethods = get_class_methods($this); - } - - // If pre-dispatch hooks introduced a redirect then stop dispatch - // @see ZF-7496 - if (!($this->getResponse()->isRedirect())) { - // preDispatch() didn't change the action, so we can continue - if ($this->getInvokeArg('useCaseSensitiveActions') || in_array($action, $this->_classMethods)) { - if ($this->getInvokeArg('useCaseSensitiveActions')) { - trigger_error('Using case sensitive actions without word separators is deprecated; please do not rely on this "feature"'); - } - $this->$action(); - } else { - $this->__call($action, array()); - } - } - $this->postDispatch(); - } - - // whats actually important here is that this action controller is - // shutting down, regardless of dispatching; notify the helpers of this - // state - $this->_helper->notifyPostDispatch(); - } - - /** - * Call the action specified in the request object, and return a response - * - * Not used in the Action Controller implementation, but left for usage in - * Page Controller implementations. Dispatches a method based on the - * request. - * - * Returns a Zend_Controller_Response_Abstract object, instantiating one - * prior to execution if none exists in the controller. - * - * {@link preDispatch()} is called prior to the action, - * {@link postDispatch()} is called following it. - * - * @param null|Zend_Controller_Request_Abstract $request Optional request - * object to use - * @param null|Zend_Controller_Response_Abstract $response Optional response - * object to use - * @return Zend_Controller_Response_Abstract - */ - public function run(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null) - { - if (null !== $request) { - $this->setRequest($request); - } else { - $request = $this->getRequest(); - } - - if (null !== $response) { - $this->setResponse($response); - } - - $action = $request->getActionName(); - if (empty($action)) { - $action = 'index'; - } - $action = $action . 'Action'; - - $request->setDispatched(true); - $this->dispatch($action); - - return $this->getResponse(); - } - - /** - * Gets a parameter from the {@link $_request Request object}. If the - * parameter does not exist, NULL will be returned. - * - * If the parameter does not exist and $default is set, then - * $default will be returned instead of NULL. - * - * @param string $paramName - * @param mixed $default - * @return mixed - */ - protected function _getParam($paramName, $default = null) - { - return $this->getParam($paramName, $default); - } - - /** - * Gets a parameter from the {@link $_request Request object}. If the - * parameter does not exist, NULL will be returned. - * - * If the parameter does not exist and $default is set, then - * $default will be returned instead of NULL. - * - * @param string $paramName - * @param mixed $default - * @return mixed - */ - public function getParam($paramName, $default = null) - { - $value = $this->getRequest()->getParam($paramName); - if ((null === $value || '' === $value) && (null !== $default)) { - $value = $default; - } - - return $value; - } - - /** - * Set a parameter in the {@link $_request Request object}. - * - * @param string $paramName - * @param mixed $value - * @return Zend_Controller_Action - * @deprecated Deprecated as of Zend Framework 1.7. Use - * setParam() instead. - */ - protected function _setParam($paramName, $value) - { - return $this->setParam($paramName, $value); - } - - /** - * Set a parameter in the {@link $_request Request object}. - * - * @param string $paramName - * @param mixed $value - * @return Zend_Controller_Action - */ - public function setParam($paramName, $value) - { - $this->getRequest()->setParam($paramName, $value); - - return $this; - } - - /** - * Determine whether a given parameter exists in the - * {@link $_request Request object}. - * - * @param string $paramName - * @return boolean - * @deprecated Deprecated as of Zend Framework 1.7. Use - * hasParam() instead. - */ - protected function _hasParam($paramName) - { - return $this->hasParam($paramName); - } - - /** - * Determine whether a given parameter exists in the - * {@link $_request Request object}. - * - * @param string $paramName - * @return boolean - */ - public function hasParam($paramName) - { - return null !== $this->getRequest()->getParam($paramName); - } - - /** - * Return all parameters in the {@link $_request Request object} - * as an associative array. - * - * @return array - * @deprecated Deprecated as of Zend Framework 1.7. Use - * getAllParams() instead. - */ - protected function _getAllParams() - { - return $this->getAllParams(); - } - - /** - * Return all parameters in the {@link $_request Request object} - * as an associative array. - * - * @return array - */ - public function getAllParams() - { - return $this->getRequest()->getParams(); - } - - - /** - * Forward to another controller/action. - * - * It is important to supply the unformatted names, i.e. "article" - * rather than "ArticleController". The dispatcher will do the - * appropriate formatting when the request is received. - * - * If only an action name is provided, forwards to that action in this - * controller. - * - * If an action and controller are specified, forwards to that action and - * controller in this module. - * - * Specifying an action, controller, and module is the most specific way to - * forward. - * - * A fourth argument, $params, will be used to set the request parameters. - * If either the controller or module are unnecessary for forwarding, - * simply pass null values for them before specifying the parameters. - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return void - * @deprecated Deprecated as of Zend Framework 1.7. Use - * forward() instead. - */ - final protected function _forward($action, $controller = null, $module = null, array $params = null) - { - $this->forward($action, $controller, $module, $params); - } - - /** - * Forward to another controller/action. - * - * It is important to supply the unformatted names, i.e. "article" - * rather than "ArticleController". The dispatcher will do the - * appropriate formatting when the request is received. - * - * If only an action name is provided, forwards to that action in this - * controller. - * - * If an action and controller are specified, forwards to that action and - * controller in this module. - * - * Specifying an action, controller, and module is the most specific way to - * forward. - * - * A fourth argument, $params, will be used to set the request parameters. - * If either the controller or module are unnecessary for forwarding, - * simply pass null values for them before specifying the parameters. - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return void - */ - final public function forward($action, $controller = null, $module = null, array $params = null) - { - $request = $this->getRequest(); - - if (null !== $params) { - $request->setParams($params); - } - - if (null !== $controller) { - $request->setControllerName($controller); - - // Module should only be reset if controller has been specified - if (null !== $module) { - $request->setModuleName($module); - } - } - - $request->setActionName($action) - ->setDispatched(false); - } - - /** - * Redirect to another URL - * - * Proxies to {@link Zend_Controller_Action_Helper_Redirector::gotoUrl()}. - * - * @param string $url - * @param array $options Options to be used when redirecting - * @return void - * @deprecated Deprecated as of Zend Framework 1.7. Use - * redirect() instead. - */ - protected function _redirect($url, array $options = array()) - { - $this->redirect($url, $options); - } - - /** - * Redirect to another URL - * - * Proxies to {@link Zend_Controller_Action_Helper_Redirector::gotoUrl()}. - * - * @param string $url - * @param array $options Options to be used when redirecting - * @return void - */ - public function redirect($url, array $options = array()) - { - $this->_helper->redirector->gotoUrl($url, $options); - } -} diff --git a/lib/Zend/Controller/Action/Exception.php b/lib/Zend/Controller/Action/Exception.php deleted file mode 100644 index 5c3a23afcef..00000000000 --- a/lib/Zend/Controller/Action/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_actionController = $actionController; - return $this; - } - - /** - * Retrieve current action controller - * - * @return Zend_Controller_Action - */ - public function getActionController() - { - return $this->_actionController; - } - - /** - * Retrieve front controller instance - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - return Zend_Controller_Front::getInstance(); - } - - /** - * Hook into action controller initialization - * - * @return void - */ - public function init() - { - } - - /** - * Hook into action controller preDispatch() workflow - * - * @return void - */ - public function preDispatch() - { - } - - /** - * Hook into action controller postDispatch() workflow - * - * @return void - */ - public function postDispatch() - { - } - - /** - * getRequest() - - * - * @return Zend_Controller_Request_Abstract $request - */ - public function getRequest() - { - $controller = $this->getActionController(); - if (null === $controller) { - $controller = $this->getFrontController(); - } - - return $controller->getRequest(); - } - - /** - * getResponse() - - * - * @return Zend_Controller_Response_Abstract $response - */ - public function getResponse() - { - $controller = $this->getActionController(); - if (null === $controller) { - $controller = $this->getFrontController(); - } - - return $controller->getResponse(); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - $fullClassName = get_class($this); - if (strpos($fullClassName, '_') !== false) { - $helperName = strrchr($fullClassName, '_'); - return ltrim($helperName, '_'); - } elseif (strpos($fullClassName, '\\') !== false) { - $helperName = strrchr($fullClassName, '\\'); - return ltrim($helperName, '\\'); - } else { - return $fullClassName; - } - } -} diff --git a/lib/Zend/Controller/Action/Helper/ActionStack.php b/lib/Zend/Controller/Action/Helper/ActionStack.php deleted file mode 100644 index 75dd0ae2bb5..00000000000 --- a/lib/Zend/Controller/Action/Helper/ActionStack.php +++ /dev/null @@ -1,138 +0,0 @@ -hasPlugin('Zend_Controller_Plugin_ActionStack')) { - /** - * @see Zend_Controller_Plugin_ActionStack - */ - #require_once 'Zend/Controller/Plugin/ActionStack.php'; - $this->_actionStack = new Zend_Controller_Plugin_ActionStack(); - $front->registerPlugin($this->_actionStack, 97); - } else { - $this->_actionStack = $front->getPlugin('Zend_Controller_Plugin_ActionStack'); - } - } - - /** - * Push onto the stack - * - * @param Zend_Controller_Request_Abstract $next - * @return Zend_Controller_Action_Helper_ActionStack Provides a fluent interface - */ - public function pushStack(Zend_Controller_Request_Abstract $next) - { - $this->_actionStack->pushStack($next); - return $this; - } - - /** - * Push a new action onto the stack - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ActionStack - */ - public function actionToStack($action, $controller = null, $module = null, array $params = array()) - { - if ($action instanceof Zend_Controller_Request_Abstract) { - return $this->pushStack($action); - } elseif (!is_string($action)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('ActionStack requires either a request object or minimally a string action'); - } - - $request = $this->getRequest(); - - if ($request instanceof Zend_Controller_Request_Abstract === false){ - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Request object not set yet'); - } - - $controller = (null === $controller) ? $request->getControllerName() : $controller; - $module = (null === $module) ? $request->getModuleName() : $module; - - /** - * @see Zend_Controller_Request_Simple - */ - #require_once 'Zend/Controller/Request/Simple.php'; - $newRequest = new Zend_Controller_Request_Simple($action, $controller, $module, $params); - - return $this->pushStack($newRequest); - } - - /** - * Perform helper when called as $this->_helper->actionStack() from an action controller - * - * Proxies to {@link simple()} - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return boolean - */ - public function direct($action, $controller = null, $module = null, array $params = array()) - { - return $this->actionToStack($action, $controller, $module, $params); - } -} diff --git a/lib/Zend/Controller/Action/Helper/AjaxContext.php b/lib/Zend/Controller/Action/Helper/AjaxContext.php deleted file mode 100644 index 3b6e4bbaa40..00000000000 --- a/lib/Zend/Controller/Action/Helper/AjaxContext.php +++ /dev/null @@ -1,80 +0,0 @@ -addContext('html', array('suffix' => 'ajax')); - } - - /** - * Initialize AJAX context switching - * - * Checks for XHR requests; if detected, attempts to perform context switch. - * - * @param string $format - * @return void - */ - public function initContext($format = null) - { - $this->_currentContext = null; - - $request = $this->getRequest(); - if (!method_exists($request, 'isXmlHttpRequest') || - !$this->getRequest()->isXmlHttpRequest()) - { - return; - } - - return parent::initContext($format); - } -} diff --git a/lib/Zend/Controller/Action/Helper/AutoComplete/Abstract.php b/lib/Zend/Controller/Action/Helper/AutoComplete/Abstract.php deleted file mode 100644 index 6b550a3b324..00000000000 --- a/lib/Zend/Controller/Action/Helper/AutoComplete/Abstract.php +++ /dev/null @@ -1,149 +0,0 @@ -disableLayout(); - } - - Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true); - - return $this; - } - - /** - * Encode data to JSON - * - * @param mixed $data - * @param bool $keepLayouts - * @throws Zend_Controller_Action_Exception - * @return string - */ - public function encodeJson($data, $keepLayouts = false) - { - if ($this->validateData($data)) { - return Zend_Controller_Action_HelperBroker::getStaticHelper('Json')->encodeJson($data, $keepLayouts); - } - - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Invalid data passed for autocompletion'); - } - - /** - * Send autocompletion data - * - * Calls prepareAutoCompletion, populates response body with this - * information, and sends response. - * - * @param mixed $data - * @param bool $keepLayouts - * @return string|void - */ - public function sendAutoCompletion($data, $keepLayouts = false) - { - $data = $this->prepareAutoCompletion($data, $keepLayouts); - - $response = $this->getResponse(); - $response->setBody($data); - - if (!$this->suppressExit) { - $response->sendResponse(); - exit; - } - - return $data; - } - - /** - * Strategy pattern: allow calling helper as broker method - * - * Prepares autocompletion data and, if $sendNow is true, immediately sends - * response. - * - * @param mixed $data - * @param bool $sendNow - * @param bool $keepLayouts - * @return string|void - */ - public function direct($data, $sendNow = true, $keepLayouts = false) - { - if ($sendNow) { - return $this->sendAutoCompletion($data, $keepLayouts); - } - - return $this->prepareAutoCompletion($data, $keepLayouts); - } -} diff --git a/lib/Zend/Controller/Action/Helper/AutoCompleteDojo.php b/lib/Zend/Controller/Action/Helper/AutoCompleteDojo.php deleted file mode 100644 index 8c8a764c7a5..00000000000 --- a/lib/Zend/Controller/Action/Helper/AutoCompleteDojo.php +++ /dev/null @@ -1,87 +0,0 @@ - $value) { - $items[] = array('label' => $value, 'name' => $value); - } - $data = new Zend_Dojo_Data('name', $items); - } - - if (!$keepLayouts) { - #require_once 'Zend/Controller/Action/HelperBroker.php'; - Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true); - - #require_once 'Zend/Layout.php'; - $layout = Zend_Layout::getMvcInstance(); - if ($layout instanceof Zend_Layout) { - $layout->disableLayout(); - } - } - - $response = Zend_Controller_Front::getInstance()->getResponse(); - $response->setHeader('Content-Type', 'application/json'); - - return $data->toJson(); - } -} diff --git a/lib/Zend/Controller/Action/Helper/AutoCompleteScriptaculous.php b/lib/Zend/Controller/Action/Helper/AutoCompleteScriptaculous.php deleted file mode 100644 index d7d5e1e17aa..00000000000 --- a/lib/Zend/Controller/Action/Helper/AutoCompleteScriptaculous.php +++ /dev/null @@ -1,82 +0,0 @@ -validateData($data)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Invalid data passed for autocompletion'); - } - - $data = (array) $data; - $data = '
  • ' . implode('
  • ', $data) . '
'; - - if (!$keepLayouts) { - $this->disableLayouts(); - } - - return $data; - } -} diff --git a/lib/Zend/Controller/Action/Helper/Cache.php b/lib/Zend/Controller/Action/Helper/Cache.php deleted file mode 100644 index ee9ed61b6df..00000000000 --- a/lib/Zend/Controller/Action/Helper/Cache.php +++ /dev/null @@ -1,289 +0,0 @@ -getRequest()->getControllerName(); - $actions = array_unique($actions); - if (!isset($this->_caching[$controller])) { - $this->_caching[$controller] = array(); - } - if (!empty($tags)) { - $tags = array_unique($tags); - if (!isset($this->_tags[$controller])) { - $this->_tags[$controller] = array(); - } - } - foreach ($actions as $action) { - $this->_caching[$controller][] = $action; - if (!empty($tags)) { - $this->_tags[$controller][$action] = array(); - foreach ($tags as $tag) { - $this->_tags[$controller][$action][] = $tag; - } - } - } - if ($extension) { - if (!isset($this->_extensions[$controller])) { - $this->_extensions[$controller] = array(); - } - foreach ($actions as $action) { - $this->_extensions[$controller][$action] = $extension; - } - } - } - - /** - * Remove a specific page cache static file based on its - * relative URL from the application's public directory. - * The file extension is not required here; usually matches - * the original REQUEST_URI that was cached. - * - * @param string $relativeUrl - * @param bool $recursive - * @return mixed - */ - public function removePage($relativeUrl, $recursive = false) - { - $cache = $this->getCache(Zend_Cache_Manager::PAGECACHE); - $encodedCacheId = $this->_encodeCacheId($relativeUrl); - - if ($recursive) { - $backend = $cache->getBackend(); - if (($backend instanceof Zend_Cache_Backend) - && method_exists($backend, 'removeRecursively') - ) { - $result = $backend->removeRecursively($encodedCacheId); - if (is_null($result) ) { - $result = $backend->removeRecursively($relativeUrl); - } - return $result; - } - } - - $result = $cache->remove($encodedCacheId); - if (is_null($result) ) { - $result = $cache->remove($relativeUrl); - } - return $result; - } - - /** - * Remove a specific page cache static file based on its - * relative URL from the application's public directory. - * The file extension is not required here; usually matches - * the original REQUEST_URI that was cached. - * - * @param array $tags - * @return mixed - */ - public function removePagesTagged(array $tags) - { - return $this->getCache(Zend_Cache_Manager::PAGECACHE) - ->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags); - } - - /** - * Commence page caching for any cacheable actions - * - * @return void - */ - public function preDispatch() - { - $controller = $this->getRequest()->getControllerName(); - $action = $this->getRequest()->getActionName(); - $stats = ob_get_status(true); - foreach ($stats as $status) { - if ($status['name'] == 'Zend_Cache_Frontend_Page::_flush' - || $status['name'] == 'Zend_Cache_Frontend_Capture::_flush') { - $obStarted = true; - } - } - if (!isset($obStarted) && isset($this->_caching[$controller]) && - in_array($action, $this->_caching[$controller])) { - $reqUri = $this->getRequest()->getRequestUri(); - $tags = array(); - if (isset($this->_tags[$controller][$action]) - && !empty($this->_tags[$controller][$action])) { - $tags = array_unique($this->_tags[$controller][$action]); - } - $extension = null; - if (isset($this->_extensions[$controller][$action])) { - $extension = $this->_extensions[$controller][$action]; - } - $this->getCache(Zend_Cache_Manager::PAGECACHE) - ->start($this->_encodeCacheId($reqUri), $tags, $extension); - } - } - - /** - * Encode a Cache ID as hexadecimal. This is a workaround because Backend ID validation - * is trapped in the Frontend classes. Will try to get this reversed for ZF 2.0 - * because it's a major annoyance to have IDs so restricted! - * - * @return string - * @param string $requestUri - */ - protected function _encodeCacheId($requestUri) - { - return bin2hex($requestUri); - } - - /** - * Set an instance of the Cache Manager for this helper - * - * @param Zend_Cache_Manager $manager - * @return void - */ - public function setManager(Zend_Cache_Manager $manager) - { - $this->_manager = $manager; - return $this; - } - - /** - * Get the Cache Manager instance or instantiate the object if not - * exists. Attempts to load from bootstrap if available. - * - * @return Zend_Cache_Manager - */ - public function getManager() - { - if ($this->_manager !== null) { - return $this->_manager; - } - $front = Zend_Controller_Front::getInstance(); - if ($front->getParam('bootstrap') - && $front->getParam('bootstrap')->getResource('CacheManager')) { - return $front->getParam('bootstrap') - ->getResource('CacheManager'); - } - $this->_manager = new Zend_Cache_Manager; - return $this->_manager; - } - - /** - * Return a list of actions for the current Controller marked for - * caching - * - * @return array - */ - public function getCacheableActions() - { - return $this->_caching; - } - - /** - * Return a list of tags set for all cacheable actions - * - * @return array - */ - public function getCacheableTags() - { - return $this->_tags; - } - - /** - * Proxy non-matched methods back to Zend_Cache_Manager where - * appropriate - * - * @param string $method - * @param array $args - * @return mixed - */ - public function __call($method, $args) - { - if (method_exists($this->getManager(), $method)) { - return call_user_func_array( - array($this->getManager(), $method), $args - ); - } - throw new Zend_Controller_Action_Exception('Method does not exist:' - . $method); - } - -} diff --git a/lib/Zend/Controller/Action/Helper/ContextSwitch.php b/lib/Zend/Controller/Action/Helper/ContextSwitch.php deleted file mode 100644 index 608a80e1bd9..00000000000 --- a/lib/Zend/Controller/Action/Helper/ContextSwitch.php +++ /dev/null @@ -1,1394 +0,0 @@ -setConfig($options); - } elseif (is_array($options)) { - $this->setOptions($options); - } - - if (empty($this->_contexts)) { - $this->addContexts(array( - 'json' => array( - 'suffix' => 'json', - 'headers' => array('Content-Type' => 'application/json'), - 'callbacks' => array( - 'init' => 'initJsonContext', - 'post' => 'postJsonContext' - ) - ), - 'xml' => array( - 'suffix' => 'xml', - 'headers' => array('Content-Type' => 'application/xml'), - ) - )); - } - - $this->init(); - } - - /** - * Initialize at start of action controller - * - * Reset the view script suffix to the original state, or store the - * original state. - * - * @return void - */ - public function init() - { - if (null === $this->_viewSuffixOrig) { - $this->_viewSuffixOrig = $this->_getViewRenderer()->getViewSuffix(); - } else { - $this->_getViewRenderer()->setViewSuffix($this->_viewSuffixOrig); - } - } - - /** - * Configure object from array of options - * - * @param array $options - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setOptions(array $options) - { - if (isset($options['contexts'])) { - $this->setContexts($options['contexts']); - unset($options['contexts']); - } - - foreach ($options as $key => $value) { - $method = 'set' . ucfirst($key); - if (in_array($method, $this->_unconfigurable)) { - continue; - } - - if (in_array($method, $this->_specialConfig)) { - $method = '_' . $method; - } - - if (method_exists($this, $method)) { - $this->$method($value); - } - } - return $this; - } - - /** - * Set object state from config object - * - * @param Zend_Config $config - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Strategy pattern: return object - * - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function direct() - { - return $this; - } - - /** - * Initialize context detection and switching - * - * @param mixed $format - * @throws Zend_Controller_Action_Exception - * @return void - */ - public function initContext($format = null) - { - $this->_currentContext = null; - - $controller = $this->getActionController(); - $request = $this->getRequest(); - $action = $request->getActionName(); - - // Return if no context switching enabled, or no context switching - // enabled for this action - $contexts = $this->getActionContexts($action); - if (empty($contexts)) { - return; - } - - // Return if no context parameter provided - if (!$context = $request->getParam($this->getContextParam())) { - if ($format === null) { - return; - } - $context = $format; - $format = null; - } - - // Check if context allowed by action controller - if (!$this->hasActionContext($action, $context)) { - return; - } - - // Return if invalid context parameter provided and no format or invalid - // format provided - if (!$this->hasContext($context)) { - if (empty($format) || !$this->hasContext($format)) { - - return; - } - } - - // Use provided format if passed - if (!empty($format) && $this->hasContext($format)) { - $context = $format; - } - - $suffix = $this->getSuffix($context); - - $this->_getViewRenderer()->setViewSuffix($suffix); - - $headers = $this->getHeaders($context); - if (!empty($headers)) { - $response = $this->getResponse(); - foreach ($headers as $header => $content) { - $response->setHeader($header, $content); - } - } - - if ($this->getAutoDisableLayout()) { - /** - * @see Zend_Layout - */ - #require_once 'Zend/Layout.php'; - $layout = Zend_Layout::getMvcInstance(); - if (null !== $layout) { - $layout->disableLayout(); - } - } - - if (null !== ($callback = $this->getCallback($context, self::TRIGGER_INIT))) { - if (is_string($callback) && method_exists($this, $callback)) { - $this->$callback(); - } elseif (is_string($callback) && function_exists($callback)) { - $callback(); - } elseif (is_array($callback)) { - call_user_func($callback); - } else { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Invalid context callback registered for context "%s"', $context)); - } - } - - $this->_currentContext = $context; - } - - /** - * JSON context extra initialization - * - * Turns off viewRenderer auto-rendering - * - * @return void - */ - public function initJsonContext() - { - if (!$this->getAutoJsonSerialization()) { - return; - } - - $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); - $view = $viewRenderer->view; - if ($view instanceof Zend_View_Interface) { - $viewRenderer->setNoRender(true); - } - } - - /** - * Should JSON contexts auto-serialize? - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setAutoJsonSerialization($flag) - { - $this->_autoJsonSerialization = (bool) $flag; - return $this; - } - - /** - * Get JSON context auto-serialization flag - * - * @return boolean - */ - public function getAutoJsonSerialization() - { - return $this->_autoJsonSerialization; - } - - /** - * Set suffix from array - * - * @param array $spec - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - protected function _setSuffix(array $spec) - { - foreach ($spec as $context => $suffixInfo) { - if (!is_string($context)) { - $context = null; - } - - if (is_string($suffixInfo)) { - $this->setSuffix($context, $suffixInfo); - continue; - } elseif (is_array($suffixInfo)) { - if (isset($suffixInfo['suffix'])) { - $suffix = $suffixInfo['suffix']; - $prependViewRendererSuffix = true; - - if ((null === $context) && isset($suffixInfo['context'])) { - $context = $suffixInfo['context']; - } - - if (isset($suffixInfo['prependViewRendererSuffix'])) { - $prependViewRendererSuffix = $suffixInfo['prependViewRendererSuffix']; - } - - $this->setSuffix($context, $suffix, $prependViewRendererSuffix); - continue; - } - - $count = count($suffixInfo); - switch (true) { - case (($count < 2) && (null === $context)): - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Invalid suffix information provided in config'); - case ($count < 2): - $suffix = array_shift($suffixInfo); - $this->setSuffix($context, $suffix); - break; - case (($count < 3) && (null === $context)): - $context = array_shift($suffixInfo); - $suffix = array_shift($suffixInfo); - $this->setSuffix($context, $suffix); - break; - case (($count == 3) && (null === $context)): - $context = array_shift($suffixInfo); - $suffix = array_shift($suffixInfo); - $prependViewRendererSuffix = array_shift($suffixInfo); - $this->setSuffix($context, $suffix, $prependViewRendererSuffix); - break; - case ($count >= 2): - $suffix = array_shift($suffixInfo); - $prependViewRendererSuffix = array_shift($suffixInfo); - $this->setSuffix($context, $suffix, $prependViewRendererSuffix); - break; - } - } - } - return $this; - } - - /** - * Customize view script suffix to use when switching context. - * - * Passing an empty suffix value to the setters disables the view script - * suffix change. - * - * @param string $context Context type for which to set suffix - * @param string $suffix Suffix to use - * @param boolean $prependViewRendererSuffix Whether or not to prepend the new suffix to the viewrenderer suffix - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setSuffix($context, $suffix, $prependViewRendererSuffix = true) - { - if (!isset($this->_contexts[$context])) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Cannot set suffix; invalid context type "%s"', $context)); - } - - if (empty($suffix)) { - $suffix = ''; - } - - if (is_array($suffix)) { - if (isset($suffix['prependViewRendererSuffix'])) { - $prependViewRendererSuffix = $suffix['prependViewRendererSuffix']; - } - if (isset($suffix['suffix'])) { - $suffix = $suffix['suffix']; - } else { - $suffix = ''; - } - } - - $suffix = (string) $suffix; - - if ($prependViewRendererSuffix) { - if (empty($suffix)) { - $suffix = $this->_getViewRenderer()->getViewSuffix(); - } else { - $suffix .= '.' . $this->_getViewRenderer()->getViewSuffix(); - } - } - - $this->_contexts[$context]['suffix'] = $suffix; - return $this; - } - - /** - * Retrieve suffix for given context type - * - * @param string $type Context type - * @throws Zend_Controller_Action_Exception - * @return string - */ - public function getSuffix($type) - { - if (!isset($this->_contexts[$type])) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Cannot retrieve suffix; invalid context type "%s"', $type)); - } - - return $this->_contexts[$type]['suffix']; - } - - /** - * Does the given context exist? - * - * @param string $context - * @param boolean $throwException - * @throws Zend_Controller_Action_Exception if context does not exist and throwException is true - * @return bool - */ - public function hasContext($context, $throwException = false) - { - if (is_string($context)) { - if (isset($this->_contexts[$context])) { - return true; - } - } elseif (is_array($context)) { - $error = false; - foreach ($context as $test) { - if (!isset($this->_contexts[$test])) { - $error = (string) $test; - break; - } - } - if (false === $error) { - return true; - } - $context = $error; - } elseif (true === $context) { - return true; - } - - if ($throwException) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Context "%s" does not exist', $context)); - } - - return false; - } - - /** - * Add header to context - * - * @param string $context - * @param string $header - * @param string $content - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function addHeader($context, $header, $content) - { - $context = (string) $context; - $this->hasContext($context, true); - - $header = (string) $header; - $content = (string) $content; - - if (isset($this->_contexts[$context]['headers'][$header])) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Cannot add "%s" header to context "%s": already exists', $header, $context)); - } - - $this->_contexts[$context]['headers'][$header] = $content; - return $this; - } - - /** - * Customize response header to use when switching context - * - * Passing an empty header value to the setters disables the response - * header. - * - * @param string $type Context type for which to set suffix - * @param string $header Header to set - * @param string $content Header content - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setHeader($context, $header, $content) - { - $this->hasContext($context, true); - $context = (string) $context; - $header = (string) $header; - $content = (string) $content; - - $this->_contexts[$context]['headers'][$header] = $content; - return $this; - } - - /** - * Add multiple headers at once for a given context - * - * @param string $context - * @param array $headers - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function addHeaders($context, array $headers) - { - foreach ($headers as $header => $content) { - $this->addHeader($context, $header, $content); - } - - return $this; - } - - /** - * Set headers from context => headers pairs - * - * @param array $options - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - protected function _setHeaders(array $options) - { - foreach ($options as $context => $headers) { - if (!is_array($headers)) { - continue; - } - $this->setHeaders($context, $headers); - } - - return $this; - } - - /** - * Set multiple headers at once for a given context - * - * @param string $context - * @param array $headers - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setHeaders($context, array $headers) - { - $this->clearHeaders($context); - foreach ($headers as $header => $content) { - $this->setHeader($context, $header, $content); - } - - return $this; - } - - /** - * Retrieve context header - * - * Returns the value of a given header for a given context type - * - * @param string $context - * @param string $header - * @return string|null - */ - public function getHeader($context, $header) - { - $this->hasContext($context, true); - $context = (string) $context; - $header = (string) $header; - if (isset($this->_contexts[$context]['headers'][$header])) { - return $this->_contexts[$context]['headers'][$header]; - } - - return null; - } - - /** - * Retrieve context headers - * - * Returns all headers for a context as key/value pairs - * - * @param string $context - * @return array - */ - public function getHeaders($context) - { - $this->hasContext($context, true); - $context = (string) $context; - return $this->_contexts[$context]['headers']; - } - - /** - * Remove a single header from a context - * - * @param string $context - * @param string $header - * @return boolean - */ - public function removeHeader($context, $header) - { - $this->hasContext($context, true); - $context = (string) $context; - $header = (string) $header; - if (isset($this->_contexts[$context]['headers'][$header])) { - unset($this->_contexts[$context]['headers'][$header]); - return true; - } - - return false; - } - - /** - * Clear all headers for a given context - * - * @param string $context - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function clearHeaders($context) - { - $this->hasContext($context, true); - $context = (string) $context; - $this->_contexts[$context]['headers'] = array(); - return $this; - } - - /** - * Validate trigger and return in normalized form - * - * @param string $trigger - * @throws Zend_Controller_Action_Exception - * @return string - */ - protected function _validateTrigger($trigger) - { - $trigger = strtoupper($trigger); - if ('TRIGGER_' !== substr($trigger, 0, 8)) { - $trigger = 'TRIGGER_' . $trigger; - } - - if (!in_array($trigger, array(self::TRIGGER_INIT, self::TRIGGER_POST))) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Invalid trigger "%s"', $trigger)); - } - - return $trigger; - } - - /** - * Set a callback for a given context and trigger - * - * @param string $context - * @param string $trigger - * @param string|array $callback - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setCallback($context, $trigger, $callback) - { - $this->hasContext($context, true); - $trigger = $this->_validateTrigger($trigger); - - if (!is_string($callback)) { - if (!is_array($callback) || (2 != count($callback))) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Invalid callback specified'); - } - } - - $this->_contexts[$context]['callbacks'][$trigger] = $callback; - return $this; - } - - /** - * Set callbacks from array of context => callbacks pairs - * - * @param array $options - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - protected function _setCallbacks(array $options) - { - foreach ($options as $context => $callbacks) { - if (!is_array($callbacks)) { - continue; - } - - $this->setCallbacks($context, $callbacks); - } - return $this; - } - - /** - * Set callbacks for a given context - * - * Callbacks should be in trigger/callback pairs. - * - * @param string $context - * @param array $callbacks - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setCallbacks($context, array $callbacks) - { - $this->hasContext($context, true); - $context = (string) $context; - if (!isset($this->_contexts[$context]['callbacks'])) { - $this->_contexts[$context]['callbacks'] = array(); - } - - foreach ($callbacks as $trigger => $callback) { - $this->setCallback($context, $trigger, $callback); - } - return $this; - } - - /** - * Get a single callback for a given context and trigger - * - * @param string $context - * @param string $trigger - * @return string|array|null - */ - public function getCallback($context, $trigger) - { - $this->hasContext($context, true); - $trigger = $this->_validateTrigger($trigger); - if (isset($this->_contexts[$context]['callbacks'][$trigger])) { - return $this->_contexts[$context]['callbacks'][$trigger]; - } - - return null; - } - - /** - * Get all callbacks for a given context - * - * @param string $context - * @return array - */ - public function getCallbacks($context) - { - $this->hasContext($context, true); - return $this->_contexts[$context]['callbacks']; - } - - /** - * Clear a callback for a given context and trigger - * - * @param string $context - * @param string $trigger - * @return boolean - */ - public function removeCallback($context, $trigger) - { - $this->hasContext($context, true); - $trigger = $this->_validateTrigger($trigger); - if (isset($this->_contexts[$context]['callbacks'][$trigger])) { - unset($this->_contexts[$context]['callbacks'][$trigger]); - return true; - } - - return false; - } - - /** - * Clear all callbacks for a given context - * - * @param string $context - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function clearCallbacks($context) - { - $this->hasContext($context, true); - $this->_contexts[$context]['callbacks'] = array(); - return $this; - } - - /** - * Set name of parameter to use when determining context format - * - * @param string $name - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setContextParam($name) - { - $this->_contextParam = (string) $name; - return $this; - } - - /** - * Return context format request parameter name - * - * @return string - */ - public function getContextParam() - { - return $this->_contextParam; - } - - /** - * Indicate default context to use when no context format provided - * - * @param string $type - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setDefaultContext($type) - { - if (!isset($this->_contexts[$type])) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Cannot set default context; invalid context type "%s"', $type)); - } - - $this->_defaultContext = $type; - return $this; - } - - /** - * Return default context - * - * @return string - */ - public function getDefaultContext() - { - return $this->_defaultContext; - } - - /** - * Set flag indicating if layout should be disabled - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setAutoDisableLayout($flag) - { - $this->_disableLayout = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve auto layout disable flag - * - * @return boolean - */ - public function getAutoDisableLayout() - { - return $this->_disableLayout; - } - - /** - * Add new context - * - * @param string $context Context type - * @param array $spec Context specification - * @throws Zend_Controller_Action_Exception - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function addContext($context, array $spec) - { - if ($this->hasContext($context)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Cannot add context "%s"; already exists', $context)); - } - $context = (string) $context; - - $this->_contexts[$context] = array(); - - $this->setSuffix($context, (isset($spec['suffix']) ? $spec['suffix'] : '')) - ->setHeaders($context, (isset($spec['headers']) ? $spec['headers'] : array())) - ->setCallbacks($context, (isset($spec['callbacks']) ? $spec['callbacks'] : array())); - return $this; - } - - /** - * Overwrite existing context - * - * @param string $context Context type - * @param array $spec Context specification - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setContext($context, array $spec) - { - $this->removeContext($context); - return $this->addContext($context, $spec); - } - - /** - * Add multiple contexts - * - * @param array $contexts - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function addContexts(array $contexts) - { - foreach ($contexts as $context => $spec) { - $this->addContext($context, $spec); - } - return $this; - } - - /** - * Set multiple contexts, after first removing all - * - * @param array $contexts - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setContexts(array $contexts) - { - $this->clearContexts(); - foreach ($contexts as $context => $spec) { - $this->addContext($context, $spec); - } - return $this; - } - - /** - * Retrieve context specification - * - * @param string $context - * @return array|null - */ - public function getContext($context) - { - if ($this->hasContext($context)) { - return $this->_contexts[(string) $context]; - } - return null; - } - - /** - * Retrieve context definitions - * - * @return array - */ - public function getContexts() - { - return $this->_contexts; - } - - /** - * Remove a context - * - * @param string $context - * @return boolean - */ - public function removeContext($context) - { - if ($this->hasContext($context)) { - unset($this->_contexts[(string) $context]); - return true; - } - return false; - } - - /** - * Remove all contexts - * - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function clearContexts() - { - $this->_contexts = array(); - return $this; - } - - /** - * Return current context, if any - * - * @return null|string - */ - public function getCurrentContext() - { - return $this->_currentContext; - } - - /** - * Post dispatch processing - * - * Execute postDispatch callback for current context, if available - * - * @throws Zend_Controller_Action_Exception - * @return void - */ - public function postDispatch() - { - $context = $this->getCurrentContext(); - if (null !== $context) { - if (null !== ($callback = $this->getCallback($context, self::TRIGGER_POST))) { - if (is_string($callback) && method_exists($this, $callback)) { - $this->$callback(); - } elseif (is_string($callback) && function_exists($callback)) { - $callback(); - } elseif (is_array($callback)) { - call_user_func($callback); - } else { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Invalid postDispatch context callback registered for context "%s"', $context)); - } - } - } - } - - /** - * JSON post processing - * - * JSON serialize view variables to response body - * - * @return void - */ - public function postJsonContext() - { - if (!$this->getAutoJsonSerialization()) { - return; - } - - $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); - $view = $viewRenderer->view; - if ($view instanceof Zend_View_Interface) { - /** - * @see Zend_Json - */ - if(method_exists($view, 'getVars')) { - #require_once 'Zend/Json.php'; - $vars = Zend_Json::encode($view->getVars()); - $this->getResponse()->setBody($vars); - } else { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('View does not implement the getVars() method needed to encode the view into JSON'); - } - } - } - - /** - * Add one or more contexts to an action - * - * @param string $action - * @param string|array $context - * @return Zend_Controller_Action_Helper_ContextSwitch|void Provides a fluent interface - */ - public function addActionContext($action, $context) - { - $this->hasContext($context, true); - $controller = $this->getActionController(); - if (null === $controller) { - return; - } - $action = (string) $action; - $contextKey = $this->_contextKey; - - if (!isset($controller->$contextKey)) { - $controller->$contextKey = array(); - } - - if (true === $context) { - $contexts = $this->getContexts(); - $controller->{$contextKey}[$action] = array_keys($contexts); - return $this; - } - - $context = (array) $context; - if (!isset($controller->{$contextKey}[$action])) { - $controller->{$contextKey}[$action] = $context; - } else { - $controller->{$contextKey}[$action] = array_merge( - $controller->{$contextKey}[$action], - $context - ); - } - - return $this; - } - - /** - * Set a context as available for a given controller action - * - * @param string $action - * @param string|array $context - * @return Zend_Controller_Action_Helper_ContextSwitch|void Provides a fluent interface - */ - public function setActionContext($action, $context) - { - $this->hasContext($context, true); - $controller = $this->getActionController(); - if (null === $controller) { - return; - } - $action = (string) $action; - $contextKey = $this->_contextKey; - - if (!isset($controller->$contextKey)) { - $controller->$contextKey = array(); - } - - if (true === $context) { - $contexts = $this->getContexts(); - $controller->{$contextKey}[$action] = array_keys($contexts); - } else { - $controller->{$contextKey}[$action] = (array) $context; - } - - return $this; - } - - /** - * Add multiple action/context pairs at once - * - * @param array $contexts - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function addActionContexts(array $contexts) - { - foreach ($contexts as $action => $context) { - $this->addActionContext($action, $context); - } - return $this; - } - - /** - * Overwrite and set multiple action contexts at once - * - * @param array $contexts - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function setActionContexts(array $contexts) - { - foreach ($contexts as $action => $context) { - $this->setActionContext($action, $context); - } - return $this; - } - - /** - * Does a particular controller action have the given context(s)? - * - * @param string $action - * @param string|array $context - * @throws Zend_Controller_Action_Exception - * @return boolean - */ - public function hasActionContext($action, $context) - { - $this->hasContext($context, true); - $controller = $this->getActionController(); - if (null === $controller) { - return false; - } - $action = (string) $action; - $contextKey = $this->_contextKey; - - if (!isset($controller->{$contextKey})) { - return false; - } - - $allContexts = $controller->{$contextKey}; - - if (!is_array($allContexts)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception("Invalid contexts found for controller"); - } - - if (!isset($allContexts[$action])) { - return false; - } - - if (true === $allContexts[$action]) { - return true; - } - - $contexts = $allContexts[$action]; - - if (!is_array($contexts)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf("Invalid contexts found for action '%s'", $action)); - } - - if (is_string($context) && in_array($context, $contexts)) { - return true; - } elseif (is_array($context)) { - $found = true; - foreach ($context as $test) { - if (!in_array($test, $contexts)) { - $found = false; - break; - } - } - return $found; - } - - return false; - } - - /** - * Get contexts for a given action or all actions in the controller - * - * @param string $action - * @return array - */ - public function getActionContexts($action = null) - { - $controller = $this->getActionController(); - if (null === $controller) { - return array(); - } - $contextKey = $this->_contextKey; - - if (!isset($controller->$contextKey)) { - return array(); - } - - if (null !== $action) { - $action = (string) $action; - if (isset($controller->{$contextKey}[$action])) { - return $controller->{$contextKey}[$action]; - } else { - return array(); - } - } - - return $controller->$contextKey; - } - - /** - * Remove one or more contexts for a given controller action - * - * @param string $action - * @param string|array $context - * @return boolean - */ - public function removeActionContext($action, $context) - { - if ($this->hasActionContext($action, $context)) { - $controller = $this->getActionController(); - $contextKey = $this->_contextKey; - $action = (string) $action; - $contexts = $controller->$contextKey; - $actionContexts = $contexts[$action]; - $contexts = (array) $context; - foreach ($contexts as $context) { - $index = array_search($context, $actionContexts); - if (false !== $index) { - unset($controller->{$contextKey}[$action][$index]); - } - } - return true; - } - return false; - } - - /** - * Clear all contexts for a given controller action or all actions - * - * @param string $action - * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface - */ - public function clearActionContexts($action = null) - { - $controller = $this->getActionController(); - $contextKey = $this->_contextKey; - - if (!isset($controller->$contextKey) || empty($controller->$contextKey)) { - return $this; - } - - if (null === $action) { - $controller->$contextKey = array(); - return $this; - } - - $action = (string) $action; - if (isset($controller->{$contextKey}[$action])) { - unset($controller->{$contextKey}[$action]); - } - - return $this; - } - - /** - * Retrieve ViewRenderer - * - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - protected function _getViewRenderer() - { - if (null === $this->_viewRenderer) { - $this->_viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); - } - - return $this->_viewRenderer; - } -} - diff --git a/lib/Zend/Controller/Action/Helper/FlashMessenger.php b/lib/Zend/Controller/Action/Helper/FlashMessenger.php deleted file mode 100644 index 307606aef9e..00000000000 --- a/lib/Zend/Controller/Action/Helper/FlashMessenger.php +++ /dev/null @@ -1,313 +0,0 @@ -getName()); - foreach (self::$_session as $namespace => $messages) { - self::$_messages[$namespace] = $messages; - unset(self::$_session->{$namespace}); - } - } - } - - /** - * postDispatch() - runs after action is dispatched, in this - * case, it is resetting the namespace in case we have forwarded to a different - * action, Flashmessage will be 'clean' (default namespace) - * - * @return Zend_Controller_Action_Helper_FlashMessenger Provides a fluent interface - */ - public function postDispatch() - { - $this->resetNamespace(); - return $this; - } - - /** - * setNamespace() - change the namespace messages are added to, useful for - * per action controller messaging between requests - * - * @param string $namespace - * @return Zend_Controller_Action_Helper_FlashMessenger Provides a fluent interface - */ - public function setNamespace($namespace = 'default') - { - $this->_namespace = $namespace; - return $this; - } - - /** - * getNamespace() - return the current namepsace - * - * @return string - */ - public function getNamespace() - { - return $this->_namespace; - } - - /** - * resetNamespace() - reset the namespace to the default - * - * @return Zend_Controller_Action_Helper_FlashMessenger Provides a fluent interface - */ - public function resetNamespace() - { - $this->setNamespace(); - return $this; - } - - /** - * addMessage() - Add a message to flash message - * - * @param string $message - * @return Zend_Controller_Action_Helper_FlashMessenger Provides a fluent interface - */ - public function addMessage($message, $namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if (self::$_messageAdded === false) { - self::$_session->setExpirationHops(1, null, true); - } - - if (!is_array(self::$_session->{$namespace})) { - self::$_session->{$namespace} = array(); - } - - self::$_session->{$namespace}[] = $message; - self::$_messageAdded = true; - - return $this; - } - - /** - * hasMessages() - Wether a specific namespace has messages - * - * @return boolean - */ - public function hasMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - return isset(self::$_messages[$namespace]); - } - - /** - * getMessages() - Get messages from a specific namespace - * - * @return array - */ - public function getMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasMessages($namespace)) { - return self::$_messages[$namespace]; - } - - return array(); - } - - /** - * Clear all messages from the previous request & current namespace - * - * @return boolean True if messages were cleared, false if none existed - */ - public function clearMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasMessages($namespace)) { - unset(self::$_messages[$namespace]); - return true; - } - - return false; - } - - /** - * hasCurrentMessages() - check to see if messages have been added to current - * namespace within this request - * - * @return boolean - */ - public function hasCurrentMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - return isset(self::$_session->{$namespace}); - } - - /** - * getCurrentMessages() - get messages that have been added to the current - * namespace within this request - * - * @return array - */ - public function getCurrentMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasCurrentMessages($namespace)) { - return self::$_session->{$namespace}; - } - - return array(); - } - - /** - * clear messages from the current request & current namespace - * - * @return boolean - */ - public function clearCurrentMessages($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasCurrentMessages($namespace)) { - unset(self::$_session->{$namespace}); - return true; - } - - return false; - } - - /** - * getIterator() - complete the IteratorAggregate interface, for iterating - * - * @return ArrayObject - */ - public function getIterator($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasMessages($namespace)) { - return new ArrayObject($this->getMessages($namespace)); - } - - return new ArrayObject(); - } - - /** - * count() - Complete the countable interface - * - * @return int - */ - public function count($namespace = null) - { - if (!is_string($namespace) || $namespace == '') { - $namespace = $this->getNamespace(); - } - - if ($this->hasMessages($namespace)) { - return count($this->getMessages($namespace)); - } - - return 0; - } - - /** - * Strategy pattern: proxy to addMessage() - * - * @param string $message - * @return void - */ - public function direct($message, $namespace=NULL) - { - return $this->addMessage($message, $namespace); - } -} diff --git a/lib/Zend/Controller/Action/Helper/Json.php b/lib/Zend/Controller/Action/Helper/Json.php deleted file mode 100644 index 66c3ae9c018..00000000000 --- a/lib/Zend/Controller/Action/Helper/Json.php +++ /dev/null @@ -1,133 +0,0 @@ -true|false - * if $keepLayouts and parmas for Zend_Json::encode are required - * then, the array can contains a 'keepLayout'=>true|false and/or 'encodeData'=>true|false - * that will not be passed to Zend_Json::encode method but will be passed - * to Zend_View_Helper_Json - * @throws Zend_Controller_Action_Helper_Json - * @return string - */ - public function encodeJson($data, $keepLayouts = false, $encodeData = true) - { - /** - * @see Zend_View_Helper_Json - */ - #require_once 'Zend/View/Helper/Json.php'; - $jsonHelper = new Zend_View_Helper_Json(); - $data = $jsonHelper->json($data, $keepLayouts, $encodeData); - - if (!$keepLayouts) { - /** - * @see Zend_Controller_Action_HelperBroker - */ - #require_once 'Zend/Controller/Action/HelperBroker.php'; - Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true); - } - - return $data; - } - - /** - * Encode JSON response and immediately send - * - * @param mixed $data - * @param boolean|array $keepLayouts - * @param $encodeData Encode $data as JSON? - * NOTE: if boolean, establish $keepLayouts to true|false - * if array, admit params for Zend_Json::encode as enableJsonExprFinder=>true|false - * if $keepLayouts and parmas for Zend_Json::encode are required - * then, the array can contains a 'keepLayout'=>true|false and/or 'encodeData'=>true|false - * that will not be passed to Zend_Json::encode method but will be passed - * to Zend_View_Helper_Json - * @return string|void - */ - public function sendJson($data, $keepLayouts = false, $encodeData = true) - { - $data = $this->encodeJson($data, $keepLayouts, $encodeData); - $response = $this->getResponse(); - $response->setBody($data); - - if (!$this->suppressExit) { - $response->sendResponse(); - exit; - } - - return $data; - } - - /** - * Strategy pattern: call helper as helper broker method - * - * Allows encoding JSON. If $sendNow is true, immediately sends JSON - * response. - * - * @param mixed $data - * @param boolean $sendNow - * @param boolean $keepLayouts - * @param boolean $encodeData Encode $data as JSON? - * @return string|void - */ - public function direct($data, $sendNow = true, $keepLayouts = false, $encodeData = true) - { - if ($sendNow) { - return $this->sendJson($data, $keepLayouts, $encodeData); - } - return $this->encodeJson($data, $keepLayouts, $encodeData); - } -} diff --git a/lib/Zend/Controller/Action/Helper/Redirector.php b/lib/Zend/Controller/Action/Helper/Redirector.php deleted file mode 100644 index ec4a2ea180b..00000000000 --- a/lib/Zend/Controller/Action/Helper/Redirector.php +++ /dev/null @@ -1,534 +0,0 @@ -_code; - } - - /** - * Validate HTTP status redirect code - * - * @param int $code - * @throws Zend_Controller_Action_Exception on invalid HTTP status code - * @return true - */ - protected function _checkCode($code) - { - $code = (int)$code; - if ((300 > $code) || (307 < $code) || (304 == $code) || (306 == $code)) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Invalid redirect HTTP status code (' . $code . ')'); - } - - return true; - } - - /** - * Set HTTP status code for {@link _redirect()} behaviour - * - * @param int $code - * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface - */ - public function setCode($code) - { - $this->_checkCode($code); - $this->_code = $code; - return $this; - } - - /** - * Retrieve flag for whether or not {@link _redirect()} will exit when finished. - * - * @return boolean - */ - public function getExit() - { - return $this->_exit; - } - - /** - * Set exit flag for {@link _redirect()} behaviour - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface - */ - public function setExit($flag) - { - $this->_exit = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve flag for whether or not {@link _redirect()} will prepend the - * base URL on relative URLs - * - * @return boolean - */ - public function getPrependBase() - { - return $this->_prependBase; - } - - /** - * Set 'prepend base' flag for {@link _redirect()} behaviour - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface - */ - public function setPrependBase($flag) - { - $this->_prependBase = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve flag for whether or not {@link redirectAndExit()} shall close the session before - * exiting. - * - * @return boolean - */ - public function getCloseSessionOnExit() - { - return $this->_closeSessionOnExit; - } - - /** - * Set flag for whether or not {@link redirectAndExit()} shall close the session before exiting. - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface - */ - public function setCloseSessionOnExit($flag) - { - $this->_closeSessionOnExit = ($flag) ? true : false; - return $this; - } - - /** - * Return use absolute URI flag - * - * @return boolean - */ - public function getUseAbsoluteUri() - { - return $this->_useAbsoluteUri; - } - - /** - * Set use absolute URI flag - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface - */ - public function setUseAbsoluteUri($flag = true) - { - $this->_useAbsoluteUri = ($flag) ? true : false; - return $this; - } - - /** - * Set redirect in response object - * - * @return void - */ - protected function _redirect($url) - { - if ($this->getUseAbsoluteUri() && !preg_match('#^(https?|ftp)://#', $url)) { - $host = (isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:''); - $proto = (isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=="off") ? 'https' : 'http'; - $port = (isset($_SERVER['SERVER_PORT'])?$_SERVER['SERVER_PORT']:80); - $uri = $proto . '://' . $host; - if ((('http' == $proto) && (80 != $port)) || (('https' == $proto) && (443 != $port))) { - // do not append if HTTP_HOST already contains port - if (strrchr($host, ':') === false) { - $uri .= ':' . $port; - } - } - $url = $uri . '/' . ltrim($url, '/'); - } - $this->_redirectUrl = $url; - $this->getResponse()->setRedirect($url, $this->getCode()); - } - - /** - * Retrieve currently set URL for redirect - * - * @return string - */ - public function getRedirectUrl() - { - return $this->_redirectUrl; - } - - /** - * Determine if the baseUrl should be prepended, and prepend if necessary - * - * @param string $url - * @return string - */ - protected function _prependBase($url) - { - if ($this->getPrependBase()) { - $request = $this->getRequest(); - if ($request instanceof Zend_Controller_Request_Http) { - $base = rtrim($request->getBaseUrl(), '/'); - if (!empty($base) && ('/' != $base)) { - $url = $base . '/' . ltrim($url, '/'); - } else { - $url = '/' . ltrim($url, '/'); - } - } - } - - return $url; - } - - /** - * Set a redirect URL of the form /module/controller/action/params - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return void - */ - public function setGotoSimple($action, $controller = null, $module = null, array $params = array()) - { - $dispatcher = $this->getFrontController()->getDispatcher(); - $request = $this->getRequest(); - $curModule = $request->getModuleName(); - $useDefaultController = false; - - if (null === $controller && null !== $module) { - $useDefaultController = true; - } - - if (null === $module) { - $module = $curModule; - } - - if ($module == $dispatcher->getDefaultModule()) { - $module = ''; - } - - if (null === $controller && !$useDefaultController) { - $controller = $request->getControllerName(); - if (empty($controller)) { - $controller = $dispatcher->getDefaultControllerName(); - } - } - - $params[$request->getModuleKey()] = $module; - $params[$request->getControllerKey()] = $controller; - $params[$request->getActionKey()] = $action; - - $router = $this->getFrontController()->getRouter(); - $url = $router->assemble($params, 'default', true); - - $this->_redirect($url); - } - - /** - * Build a URL based on a route - * - * @param array $urlOptions - * @param string $name Route name - * @param boolean $reset - * @param boolean $encode - * @return void - */ - public function setGotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) - { - $router = $this->getFrontController()->getRouter(); - $url = $router->assemble($urlOptions, $name, $reset, $encode); - - $this->_redirect($url); - } - - /** - * Set a redirect URL string - * - * By default, emits a 302 HTTP status header, prepends base URL as defined - * in request object if url is relative, and halts script execution by - * calling exit(). - * - * $options is an optional associative array that can be used to control - * redirect behaviour. The available option keys are: - * - exit: boolean flag indicating whether or not to halt script execution when done - * - prependBase: boolean flag indicating whether or not to prepend the base URL when a relative URL is provided - * - code: integer HTTP status code to use with redirect. Should be between 300 and 307. - * - * _redirect() sets the Location header in the response object. If you set - * the exit flag to false, you can override this header later in code - * execution. - * - * If the exit flag is true (true by default), _redirect() will write and - * close the current session, if any. - * - * @param string $url - * @param array $options - * @return void - */ - public function setGotoUrl($url, array $options = array()) - { - // prevent header injections - $url = str_replace(array("\n", "\r"), '', $url); - - if (null !== $options) { - if (isset($options['exit'])) { - $this->setExit(($options['exit']) ? true : false); - } - if (isset($options['prependBase'])) { - $this->setPrependBase(($options['prependBase']) ? true : false); - } - if (isset($options['code'])) { - $this->setCode($options['code']); - } - } - - // If relative URL, decide if we should prepend base URL - if (!preg_match('|^[a-z]+://|', $url)) { - $url = $this->_prependBase($url); - } - - $this->_redirect($url); - } - - /** - * Perform a redirect to an action/controller/module with params - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return void - */ - public function gotoSimple($action, $controller = null, $module = null, array $params = array()) - { - $this->setGotoSimple($action, $controller, $module, $params); - - if ($this->getExit()) { - $this->redirectAndExit(); - } - } - - /** - * Perform a redirect to an action/controller/module with params, forcing an immdiate exit - * - * @param mixed $action - * @param mixed $controller - * @param mixed $module - * @param array $params - * @return void - */ - public function gotoSimpleAndExit($action, $controller = null, $module = null, array $params = array()) - { - $this->setGotoSimple($action, $controller, $module, $params); - $this->redirectAndExit(); - } - - /** - * Redirect to a route-based URL - * - * Uses route's assemble method to build the URL; route is specified by $name; - * default route is used if none provided. - * - * @param array $urlOptions Array of key/value pairs used to assemble URL - * @param string $name - * @param boolean $reset - * @param boolean $encode - * @return void - */ - public function gotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) - { - $this->setGotoRoute($urlOptions, $name, $reset, $encode); - - if ($this->getExit()) { - $this->redirectAndExit(); - } - } - - /** - * Redirect to a route-based URL, and immediately exit - * - * Uses route's assemble method to build the URL; route is specified by $name; - * default route is used if none provided. - * - * @param array $urlOptions Array of key/value pairs used to assemble URL - * @param string $name - * @param boolean $reset - * @return void - */ - public function gotoRouteAndExit(array $urlOptions = array(), $name = null, $reset = false) - { - $this->setGotoRoute($urlOptions, $name, $reset); - $this->redirectAndExit(); - } - - /** - * Perform a redirect to a url - * - * @param string $url - * @param array $options - * @return void - */ - public function gotoUrl($url, array $options = array()) - { - $this->setGotoUrl($url, $options); - - if ($this->getExit()) { - $this->redirectAndExit(); - } - } - - /** - * Set a URL string for a redirect, perform redirect, and immediately exit - * - * @param string $url - * @param array $options - * @return void - */ - public function gotoUrlAndExit($url, array $options = array()) - { - $this->setGotoUrl($url, $options); - $this->redirectAndExit(); - } - - /** - * exit(): Perform exit for redirector - * - * @return void - */ - public function redirectAndExit() - { - if ($this->getCloseSessionOnExit()) { - // Close session, if started - if (class_exists('Zend_Session', false) && Zend_Session::isStarted()) { - Zend_Session::writeClose(); - } elseif (isset($_SESSION)) { - session_write_close(); - } - } - - $this->getResponse()->sendHeaders(); - exit(); - } - - /** - * direct(): Perform helper when called as - * $this->_helper->redirector($action, $controller, $module, $params) - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return void - */ - public function direct($action, $controller = null, $module = null, array $params = array()) - { - $this->gotoSimple($action, $controller, $module, $params); - } - - /** - * Overloading - * - * Overloading for old 'goto', 'setGoto', and 'gotoAndExit' methods - * - * @param string $method - * @param array $args - * @return mixed - * @throws Zend_Controller_Action_Exception for invalid methods - */ - public function __call($method, $args) - { - $method = strtolower($method); - if ('goto' == $method) { - return call_user_func_array(array($this, 'gotoSimple'), $args); - } - if ('setgoto' == $method) { - return call_user_func_array(array($this, 'setGotoSimple'), $args); - } - if ('gotoandexit' == $method) { - return call_user_func_array(array($this, 'gotoSimpleAndExit'), $args); - } - - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception(sprintf('Invalid method "%s" called on redirector', $method)); - } -} diff --git a/lib/Zend/Controller/Action/Helper/Url.php b/lib/Zend/Controller/Action/Helper/Url.php deleted file mode 100644 index 496d2ce19e0..00000000000 --- a/lib/Zend/Controller/Action/Helper/Url.php +++ /dev/null @@ -1,117 +0,0 @@ -getRequest(); - - if (null === $controller) { - $controller = $request->getControllerName(); - } - - if (null === $module) { - $module = $request->getModuleName(); - } - - $url = $controller . '/' . $action; - if ($module != $this->getFrontController()->getDispatcher()->getDefaultModule()) { - $url = $module . '/' . $url; - } - - if ('' !== ($baseUrl = $this->getFrontController()->getBaseUrl())) { - $url = $baseUrl . '/' . $url; - } - - if (null !== $params) { - $paramPairs = array(); - foreach ($params as $key => $value) { - $paramPairs[] = urlencode($key) . '/' . urlencode($value); - } - $paramString = implode('/', $paramPairs); - $url .= '/' . $paramString; - } - - $url = '/' . ltrim($url, '/'); - - return $url; - } - - /** - * Assembles a URL based on a given route - * - * This method will typically be used for more complex operations, as it - * ties into the route objects registered with the router. - * - * @param array $urlOptions Options passed to the assemble method of the Route object. - * @param mixed $name The name of a Route to use. If null it will use the current Route - * @param boolean $reset - * @param boolean $encode - * @return string Url for the link href attribute. - */ - public function url($urlOptions = array(), $name = null, $reset = false, $encode = true) - { - $router = $this->getFrontController()->getRouter(); - return $router->assemble($urlOptions, $name, $reset, $encode); - } - - /** - * Perform helper when called as $this->_helper->url() from an action controller - * - * Proxies to {@link simple()} - * - * @param string $action - * @param string $controller - * @param string $module - * @param array $params - * @return string - */ - public function direct($action, $controller = null, $module = null, array $params = null) - { - return $this->simple($action, $controller, $module, $params); - } -} diff --git a/lib/Zend/Controller/Action/Helper/ViewRenderer.php b/lib/Zend/Controller/Action/Helper/ViewRenderer.php deleted file mode 100644 index b56f755e984..00000000000 --- a/lib/Zend/Controller/Action/Helper/ViewRenderer.php +++ /dev/null @@ -1,1004 +0,0 @@ - - * // In your bootstrap: - * Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_ViewRenderer()); - * - * // In your action controller methods: - * $viewHelper = $this->_helper->getHelper('view'); - * - * // Don't use controller subdirectories - * $viewHelper->setNoController(true); - * - * // Specify a different script to render: - * $this->_helper->viewRenderer('form'); - * - * - * - * @uses Zend_Controller_Action_Helper_Abstract - * @package Zend_Controller - * @subpackage Zend_Controller_Action_Helper - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Action_Helper_Abstract -{ - /** - * @var Zend_View_Interface - */ - public $view; - - /** - * Word delimiters - * @var array - */ - protected $_delimiters; - - /** - * @var Zend_Filter_Inflector - */ - protected $_inflector; - - /** - * Inflector target - * @var string - */ - protected $_inflectorTarget = ''; - - /** - * Current module directory - * @var string - */ - protected $_moduleDir = ''; - - /** - * Whether or not to autorender using controller name as subdirectory; - * global setting (not reset at next invocation) - * @var boolean - */ - protected $_neverController = false; - - /** - * Whether or not to autorender postDispatch; global setting (not reset at - * next invocation) - * @var boolean - */ - protected $_neverRender = false; - - /** - * Whether or not to use a controller name as a subdirectory when rendering - * @var boolean - */ - protected $_noController = false; - - /** - * Whether or not to autorender postDispatch; per controller/action setting (reset - * at next invocation) - * @var boolean - */ - protected $_noRender = false; - - /** - * Characters representing path delimiters in the controller - * @var string|array - */ - protected $_pathDelimiters; - - /** - * Which named segment of the response to utilize - * @var string - */ - protected $_responseSegment = null; - - /** - * Which action view script to render - * @var string - */ - protected $_scriptAction = null; - - /** - * View object basePath - * @var string - */ - protected $_viewBasePathSpec = ':moduleDir/views'; - - /** - * View script path specification string - * @var string - */ - protected $_viewScriptPathSpec = ':controller/:action.:suffix'; - - /** - * View script path specification string, minus controller segment - * @var string - */ - protected $_viewScriptPathNoControllerSpec = ':action.:suffix'; - - /** - * View script suffix - * @var string - */ - protected $_viewSuffix = 'phtml'; - - /** - * Constructor - * - * Optionally set view object and options. - * - * @param Zend_View_Interface $view - * @param array $options - * @return void - */ - public function __construct(Zend_View_Interface $view = null, array $options = array()) - { - if (null !== $view) { - $this->setView($view); - } - - if (!empty($options)) { - $this->_setOptions($options); - } - } - - /** - * Clone - also make sure the view is cloned. - * - * @return void - */ - public function __clone() - { - if (isset($this->view) && $this->view instanceof Zend_View_Interface) { - $this->view = clone $this->view; - - } - } - - /** - * Set the view object - * - * @param Zend_View_Interface $view - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setView(Zend_View_Interface $view) - { - $this->view = $view; - return $this; - } - - /** - * Get current module name - * - * @return string - */ - public function getModule() - { - $request = $this->getRequest(); - $module = $request->getModuleName(); - if (null === $module) { - $module = $this->getFrontController()->getDispatcher()->getDefaultModule(); - } - - return $module; - } - - /** - * Get module directory - * - * @throws Zend_Controller_Action_Exception - * @return string - */ - public function getModuleDirectory() - { - $module = $this->getModule(); - $moduleDir = $this->getFrontController()->getControllerDirectory($module); - if ((null === $moduleDir) || is_array($moduleDir)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('ViewRenderer cannot locate module directory for module "' . $module . '"'); - } - $this->_moduleDir = dirname($moduleDir); - return $this->_moduleDir; - } - - /** - * Get inflector - * - * @return Zend_Filter_Inflector - */ - public function getInflector() - { - if (null === $this->_inflector) { - /** - * @see Zend_Filter_Inflector - */ - #require_once 'Zend/Filter/Inflector.php'; - /** - * @see Zend_Filter_PregReplace - */ - #require_once 'Zend/Filter/PregReplace.php'; - /** - * @see Zend_Filter_Word_UnderscoreToSeparator - */ - #require_once 'Zend/Filter/Word/UnderscoreToSeparator.php'; - $this->_inflector = new Zend_Filter_Inflector(); - $this->_inflector->setStaticRuleReference('moduleDir', $this->_moduleDir) // moduleDir must be specified before the less specific 'module' - ->addRules(array( - ':module' => array('Word_CamelCaseToDash', 'StringToLower'), - ':controller' => array('Word_CamelCaseToDash', new Zend_Filter_Word_UnderscoreToSeparator('/'), 'StringToLower', new Zend_Filter_PregReplace('/\./', '-')), - ':action' => array('Word_CamelCaseToDash', new Zend_Filter_PregReplace('#[^a-z0-9' . preg_quote('/', '#') . ']+#i', '-'), 'StringToLower'), - )) - ->setStaticRuleReference('suffix', $this->_viewSuffix) - ->setTargetReference($this->_inflectorTarget); - } - - // Ensure that module directory is current - $this->getModuleDirectory(); - - return $this->_inflector; - } - - /** - * Set inflector - * - * @param Zend_Filter_Inflector $inflector - * @param boolean $reference Whether the moduleDir, target, and suffix should be set as references to ViewRenderer properties - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setInflector(Zend_Filter_Inflector $inflector, $reference = false) - { - $this->_inflector = $inflector; - if ($reference) { - $this->_inflector->setStaticRuleReference('suffix', $this->_viewSuffix) - ->setStaticRuleReference('moduleDir', $this->_moduleDir) - ->setTargetReference($this->_inflectorTarget); - } - return $this; - } - - /** - * Set inflector target - * - * @param string $target - * @return void - */ - protected function _setInflectorTarget($target) - { - $this->_inflectorTarget = (string) $target; - } - - /** - * Set internal module directory representation - * - * @param string $dir - * @return void - */ - protected function _setModuleDir($dir) - { - $this->_moduleDir = (string) $dir; - } - - /** - * Get internal module directory representation - * - * @return string - */ - protected function _getModuleDir() - { - return $this->_moduleDir; - } - - /** - * Generate a class prefix for helper and filter classes - * - * @return string - */ - protected function _generateDefaultPrefix() - { - $default = 'Zend_View'; - if (null === $this->_actionController) { - return $default; - } - - $class = get_class($this->_actionController); - - if (!strstr($class, '_')) { - return $default; - } - - $module = $this->getModule(); - if ('default' == $module) { - return $default; - } - - $prefix = substr($class, 0, strpos($class, '_')) . '_View'; - - return $prefix; - } - - /** - * Retrieve base path based on location of current action controller - * - * @return string - */ - protected function _getBasePath() - { - if (null === $this->_actionController) { - return './views'; - } - - $inflector = $this->getInflector(); - $this->_setInflectorTarget($this->getViewBasePathSpec()); - - $dispatcher = $this->getFrontController()->getDispatcher(); - $request = $this->getRequest(); - - $parts = array( - 'module' => (($moduleName = $request->getModuleName()) != '') ? $dispatcher->formatModuleName($moduleName) : $moduleName, - 'controller' => $request->getControllerName(), - 'action' => $dispatcher->formatActionName($request->getActionName()) - ); - - $path = $inflector->filter($parts); - return $path; - } - - /** - * Set options - * - * @param array $options - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - protected function _setOptions(array $options) - { - foreach ($options as $key => $value) - { - switch ($key) { - case 'neverRender': - case 'neverController': - case 'noController': - case 'noRender': - $property = '_' . $key; - $this->{$property} = ($value) ? true : false; - break; - case 'responseSegment': - case 'scriptAction': - case 'viewBasePathSpec': - case 'viewScriptPathSpec': - case 'viewScriptPathNoControllerSpec': - case 'viewSuffix': - $property = '_' . $key; - $this->{$property} = (string) $value; - break; - default: - break; - } - } - - return $this; - } - - /** - * Initialize the view object - * - * $options may contain the following keys: - * - neverRender - flag dis/enabling postDispatch() autorender (affects all subsequent calls) - * - noController - flag indicating whether or not to look for view scripts in subdirectories named after the controller - * - noRender - flag indicating whether or not to autorender postDispatch() - * - responseSegment - which named response segment to render a view script to - * - scriptAction - what action script to render - * - viewBasePathSpec - specification to use for determining view base path - * - viewScriptPathSpec - specification to use for determining view script paths - * - viewScriptPathNoControllerSpec - specification to use for determining view script paths when noController flag is set - * - viewSuffix - what view script filename suffix to use - * - * @param string $path - * @param string $prefix - * @param array $options - * @throws Zend_Controller_Action_Exception - * @return void - */ - public function initView($path = null, $prefix = null, array $options = array()) - { - if (null === $this->view) { - $this->setView(new Zend_View()); - } - - // Reset some flags every time - $options['noController'] = (isset($options['noController'])) ? $options['noController'] : false; - $options['noRender'] = (isset($options['noRender'])) ? $options['noRender'] : false; - $this->_scriptAction = null; - $this->_responseSegment = null; - - // Set options first; may be used to determine other initializations - $this->_setOptions($options); - - // Get base view path - if (empty($path)) { - $path = $this->_getBasePath(); - if (empty($path)) { - /** - * @see Zend_Controller_Action_Exception - */ - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('ViewRenderer initialization failed: retrieved view base path is empty'); - } - } - - if (null === $prefix) { - $prefix = $this->_generateDefaultPrefix(); - } - - // Determine if this path has already been registered - $currentPaths = $this->view->getScriptPaths(); - $path = str_replace(array('/', '\\'), '/', $path); - $pathExists = false; - foreach ($currentPaths as $tmpPath) { - $tmpPath = str_replace(array('/', '\\'), '/', $tmpPath); - if (strstr($tmpPath, $path)) { - $pathExists = true; - break; - } - } - if (!$pathExists) { - $this->view->addBasePath($path, $prefix); - } - - // Register view with action controller (unless already registered) - if ((null !== $this->_actionController) && (null === $this->_actionController->view)) { - $this->_actionController->view = $this->view; - $this->_actionController->viewSuffix = $this->_viewSuffix; - } - } - - /** - * init - initialize view - * - * @return void - */ - public function init() - { - if ($this->getFrontController()->getParam('noViewRenderer')) { - return; - } - - $this->initView(); - } - - /** - * Set view basePath specification - * - * Specification can contain one or more of the following: - * - :moduleDir - current module directory - * - :controller - name of current controller in the request - * - :action - name of current action in the request - * - :module - name of current module in the request - * - * @param string $path - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setViewBasePathSpec($path) - { - $this->_viewBasePathSpec = (string) $path; - return $this; - } - - /** - * Retrieve the current view basePath specification string - * - * @return string - */ - public function getViewBasePathSpec() - { - return $this->_viewBasePathSpec; - } - - /** - * Set view script path specification - * - * Specification can contain one or more of the following: - * - :moduleDir - current module directory - * - :controller - name of current controller in the request - * - :action - name of current action in the request - * - :module - name of current module in the request - * - * @param string $path - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setViewScriptPathSpec($path) - { - $this->_viewScriptPathSpec = (string) $path; - return $this; - } - - /** - * Retrieve the current view script path specification string - * - * @return string - */ - public function getViewScriptPathSpec() - { - return $this->_viewScriptPathSpec; - } - - /** - * Set view script path specification (no controller variant) - * - * Specification can contain one or more of the following: - * - :moduleDir - current module directory - * - :controller - name of current controller in the request - * - :action - name of current action in the request - * - :module - name of current module in the request - * - * :controller will likely be ignored in this variant. - * - * @param string $path - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setViewScriptPathNoControllerSpec($path) - { - $this->_viewScriptPathNoControllerSpec = (string) $path; - return $this; - } - - /** - * Retrieve the current view script path specification string (no controller variant) - * - * @return string - */ - public function getViewScriptPathNoControllerSpec() - { - return $this->_viewScriptPathNoControllerSpec; - } - - /** - * Get a view script based on an action and/or other variables - * - * Uses values found in current request if no values passed in $vars. - * - * If {@link $_noController} is set, uses {@link $_viewScriptPathNoControllerSpec}; - * otherwise, uses {@link $_viewScriptPathSpec}. - * - * @param string $action - * @param array $vars - * @return string - */ - public function getViewScript($action = null, array $vars = array()) - { - $request = $this->getRequest(); - if ((null === $action) && (!isset($vars['action']))) { - $action = $this->getScriptAction(); - if (null === $action) { - $action = $request->getActionName(); - } - $vars['action'] = $action; - } elseif (null !== $action) { - $vars['action'] = $action; - } - - $replacePattern = array('/[^a-z0-9]+$/i', '/^[^a-z0-9]+/i'); - $vars['action'] = preg_replace($replacePattern, '', $vars['action']); - - $inflector = $this->getInflector(); - if ($this->getNoController() || $this->getNeverController()) { - $this->_setInflectorTarget($this->getViewScriptPathNoControllerSpec()); - } else { - $this->_setInflectorTarget($this->getViewScriptPathSpec()); - } - return $this->_translateSpec($vars); - } - - /** - * Set the neverRender flag (i.e., globally dis/enable autorendering) - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setNeverRender($flag = true) - { - $this->_neverRender = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve neverRender flag value - * - * @return boolean - */ - public function getNeverRender() - { - return $this->_neverRender; - } - - /** - * Set the noRender flag (i.e., whether or not to autorender) - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setNoRender($flag = true) - { - $this->_noRender = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve noRender flag value - * - * @return boolean - */ - public function getNoRender() - { - return $this->_noRender; - } - - /** - * Set the view script to use - * - * @param string $name - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setScriptAction($name) - { - $this->_scriptAction = (string) $name; - return $this; - } - - /** - * Retrieve view script name - * - * @return string - */ - public function getScriptAction() - { - return $this->_scriptAction; - } - - /** - * Set the response segment name - * - * @param string $name - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setResponseSegment($name) - { - if (null === $name) { - $this->_responseSegment = null; - } else { - $this->_responseSegment = (string) $name; - } - - return $this; - } - - /** - * Retrieve named response segment name - * - * @return string - */ - public function getResponseSegment() - { - return $this->_responseSegment; - } - - /** - * Set the noController flag (i.e., whether or not to render into controller subdirectories) - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setNoController($flag = true) - { - $this->_noController = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve noController flag value - * - * @return boolean - */ - public function getNoController() - { - return $this->_noController; - } - - /** - * Set the neverController flag (i.e., whether or not to render into controller subdirectories) - * - * @param boolean $flag - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setNeverController($flag = true) - { - $this->_neverController = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve neverController flag value - * - * @return boolean - */ - public function getNeverController() - { - return $this->_neverController; - } - - /** - * Set view script suffix - * - * @param string $suffix - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setViewSuffix($suffix) - { - $this->_viewSuffix = (string) $suffix; - return $this; - } - - /** - * Get view script suffix - * - * @return string - */ - public function getViewSuffix() - { - return $this->_viewSuffix; - } - - /** - * Set options for rendering a view script - * - * @param string $action View script to render - * @param string $name Response named segment to render to - * @param boolean $noController Whether or not to render within a subdirectory named after the controller - * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface - */ - public function setRender($action = null, $name = null, $noController = null) - { - if (null !== $action) { - $this->setScriptAction($action); - } - - if (null !== $name) { - $this->setResponseSegment($name); - } - - if (null !== $noController) { - $this->setNoController($noController); - } - - return $this; - } - - /** - * Inflect based on provided vars - * - * Allowed variables are: - * - :moduleDir - current module directory - * - :module - current module name - * - :controller - current controller name - * - :action - current action name - * - :suffix - view script file suffix - * - * @param array $vars - * @return string - */ - protected function _translateSpec(array $vars = array()) - { - $inflector = $this->getInflector(); - $request = $this->getRequest(); - $dispatcher = $this->getFrontController()->getDispatcher(); - - // Format module name - $module = $dispatcher->formatModuleName($request->getModuleName()); - - // Format controller name - #require_once 'Zend/Filter/Word/CamelCaseToDash.php'; - $filter = new Zend_Filter_Word_CamelCaseToDash(); - $controller = $filter->filter($request->getControllerName()); - $controller = $dispatcher->formatControllerName($controller); - if ('Controller' == substr($controller, -10)) { - $controller = substr($controller, 0, -10); - } - - // Format action name - $action = $dispatcher->formatActionName($request->getActionName()); - - $params = compact('module', 'controller', 'action'); - foreach ($vars as $key => $value) { - switch ($key) { - case 'module': - case 'controller': - case 'action': - case 'moduleDir': - case 'suffix': - $params[$key] = (string) $value; - break; - default: - break; - } - } - - if (isset($params['suffix'])) { - $origSuffix = $this->getViewSuffix(); - $this->setViewSuffix($params['suffix']); - } - if (isset($params['moduleDir'])) { - $origModuleDir = $this->_getModuleDir(); - $this->_setModuleDir($params['moduleDir']); - } - - $filtered = $inflector->filter($params); - - if (isset($params['suffix'])) { - $this->setViewSuffix($origSuffix); - } - if (isset($params['moduleDir'])) { - $this->_setModuleDir($origModuleDir); - } - - return $filtered; - } - - /** - * Render a view script (optionally to a named response segment) - * - * Sets the noRender flag to true when called. - * - * @param string $script - * @param string $name - * @return void - */ - public function renderScript($script, $name = null) - { - if (null === $name) { - $name = $this->getResponseSegment(); - } - - $this->getResponse()->appendBody( - $this->view->render($script), - $name - ); - - $this->setNoRender(); - } - - /** - * Render a view based on path specifications - * - * Renders a view based on the view script path specifications. - * - * @param string $action - * @param string $name - * @param boolean $noController - * @return void - */ - public function render($action = null, $name = null, $noController = null) - { - $this->setRender($action, $name, $noController); - $path = $this->getViewScript(); - $this->renderScript($path, $name); - } - - /** - * Render a script based on specification variables - * - * Pass an action, and one or more specification variables (view script suffix) - * to determine the view script path, and render that script. - * - * @param string $action - * @param array $vars - * @param string $name - * @return void - */ - public function renderBySpec($action = null, array $vars = array(), $name = null) - { - if (null !== $name) { - $this->setResponseSegment($name); - } - - $path = $this->getViewScript($action, $vars); - - $this->renderScript($path); - } - - /** - * postDispatch - auto render a view - * - * Only autorenders if: - * - _noRender is false - * - action controller is present - * - request has not been re-dispatched (i.e., _forward() has not been called) - * - response is not a redirect - * - * @return void - */ - public function postDispatch() - { - if ($this->_shouldRender()) { - $this->render(); - } - } - - /** - * Should the ViewRenderer render a view script? - * - * @return boolean - */ - protected function _shouldRender() - { - return (!$this->getFrontController()->getParam('noViewRenderer') - && !$this->_neverRender - && !$this->_noRender - && (null !== $this->_actionController) - && $this->getRequest()->isDispatched() - && !$this->getResponse()->isRedirect() - ); - } - - /** - * Use this helper as a method; proxies to setRender() - * - * @param string $action - * @param string $name - * @param boolean $noController - * @return void - */ - public function direct($action = null, $name = null, $noController = null) - { - $this->setRender($action, $name, $noController); - } -} diff --git a/lib/Zend/Controller/Action/HelperBroker.php b/lib/Zend/Controller/Action/HelperBroker.php deleted file mode 100644 index 8f5b0e74f97..00000000000 --- a/lib/Zend/Controller/Action/HelperBroker.php +++ /dev/null @@ -1,381 +0,0 @@ - 'Zend/Controller/Action/Helper/', - )); - } - return self::$_pluginLoader; - } - - /** - * addPrefix() - Add repository of helpers by prefix - * - * @param string $prefix - */ - static public function addPrefix($prefix) - { - $prefix = rtrim($prefix, '_'); - $path = str_replace('_', DIRECTORY_SEPARATOR, $prefix); - self::getPluginLoader()->addPrefixPath($prefix, $path); - } - - /** - * addPath() - Add path to repositories where Action_Helpers could be found. - * - * @param string $path - * @param string $prefix Optional; defaults to 'Zend_Controller_Action_Helper' - * @return void - */ - static public function addPath($path, $prefix = 'Zend_Controller_Action_Helper') - { - self::getPluginLoader()->addPrefixPath($prefix, $path); - } - - /** - * addHelper() - Add helper objects - * - * @param Zend_Controller_Action_Helper_Abstract $helper - * @return void - */ - static public function addHelper(Zend_Controller_Action_Helper_Abstract $helper) - { - self::getStack()->push($helper); - return; - } - - /** - * resetHelpers() - * - * @return void - */ - static public function resetHelpers() - { - self::$_stack = null; - return; - } - - /** - * Retrieve or initialize a helper statically - * - * Retrieves a helper object statically, loading on-demand if the helper - * does not already exist in the stack. Always returns a helper, unless - * the helper class cannot be found. - * - * @param string $name - * @return Zend_Controller_Action_Helper_Abstract - */ - public static function getStaticHelper($name) - { - $name = self::_normalizeHelperName($name); - $stack = self::getStack(); - - if (!isset($stack->{$name})) { - self::_loadHelper($name); - } - - return $stack->{$name}; - } - - /** - * getExistingHelper() - get helper by name - * - * Static method to retrieve helper object. Only retrieves helpers already - * initialized with the broker (either via addHelper() or on-demand loading - * via getHelper()). - * - * Throws an exception if the referenced helper does not exist in the - * stack; use {@link hasHelper()} to check if the helper is registered - * prior to retrieving it. - * - * @param string $name - * @return Zend_Controller_Action_Helper_Abstract - * @throws Zend_Controller_Action_Exception - */ - public static function getExistingHelper($name) - { - $name = self::_normalizeHelperName($name); - $stack = self::getStack(); - - if (!isset($stack->{$name})) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Action helper "' . $name . '" has not been registered with the helper broker'); - } - - return $stack->{$name}; - } - - /** - * Return all registered helpers as helper => object pairs - * - * @return array - */ - public static function getExistingHelpers() - { - return self::getStack()->getHelpersByName(); - } - - /** - * Is a particular helper loaded in the broker? - * - * @param string $name - * @return boolean - */ - public static function hasHelper($name) - { - $name = self::_normalizeHelperName($name); - return isset(self::getStack()->{$name}); - } - - /** - * Remove a particular helper from the broker - * - * @param string $name - * @return boolean - */ - public static function removeHelper($name) - { - $name = self::_normalizeHelperName($name); - $stack = self::getStack(); - if (isset($stack->{$name})) { - unset($stack->{$name}); - } - - return false; - } - - /** - * Lazy load the priority stack and return it - * - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public static function getStack() - { - if (self::$_stack == null) { - self::$_stack = new Zend_Controller_Action_HelperBroker_PriorityStack(); - } - - return self::$_stack; - } - - /** - * Constructor - * - * @param Zend_Controller_Action $actionController - * @return void - */ - public function __construct(Zend_Controller_Action $actionController) - { - $this->_actionController = $actionController; - foreach (self::getStack() as $helper) { - $helper->setActionController($actionController); - $helper->init(); - } - } - - /** - * notifyPreDispatch() - called by action controller dispatch method - * - * @return void - */ - public function notifyPreDispatch() - { - foreach (self::getStack() as $helper) { - $helper->preDispatch(); - } - } - - /** - * notifyPostDispatch() - called by action controller dispatch method - * - * @return void - */ - public function notifyPostDispatch() - { - foreach (self::getStack() as $helper) { - $helper->postDispatch(); - } - } - - /** - * getHelper() - get helper by name - * - * @param string $name - * @return Zend_Controller_Action_Helper_Abstract - */ - public function getHelper($name) - { - $name = self::_normalizeHelperName($name); - $stack = self::getStack(); - - if (!isset($stack->{$name})) { - self::_loadHelper($name); - } - - $helper = $stack->{$name}; - - $initialize = false; - if (null === ($actionController = $helper->getActionController())) { - $initialize = true; - } elseif ($actionController !== $this->_actionController) { - $initialize = true; - } - - if ($initialize) { - $helper->setActionController($this->_actionController) - ->init(); - } - - return $helper; - } - - /** - * Method overloading - * - * @param string $method - * @param array $args - * @return mixed - * @throws Zend_Controller_Action_Exception if helper does not have a direct() method - */ - public function __call($method, $args) - { - $helper = $this->getHelper($method); - if (!method_exists($helper, 'direct')) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Helper "' . $method . '" does not support overloading via direct()'); - } - return call_user_func_array(array($helper, 'direct'), $args); - } - - /** - * Retrieve helper by name as object property - * - * @param string $name - * @return Zend_Controller_Action_Helper_Abstract - */ - public function __get($name) - { - return $this->getHelper($name); - } - - /** - * Normalize helper name for lookups - * - * @param string $name - * @return string - */ - protected static function _normalizeHelperName($name) - { - if (strpos($name, '_') !== false) { - $name = str_replace(' ', '', ucwords(str_replace('_', ' ', $name))); - } - - return ucfirst($name); - } - - /** - * Load a helper - * - * @param string $name - * @return void - */ - protected static function _loadHelper($name) - { - try { - $class = self::getPluginLoader()->load($name); - } catch (Zend_Loader_PluginLoader_Exception $e) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Action Helper by name ' . $name . ' not found', 0, $e); - } - - $helper = new $class(); - - if (!$helper instanceof Zend_Controller_Action_Helper_Abstract) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('Helper name ' . $name . ' -> class ' . $class . ' is not of type Zend_Controller_Action_Helper_Abstract'); - } - - self::getStack()->push($helper); - } -} diff --git a/lib/Zend/Controller/Action/HelperBroker/PriorityStack.php b/lib/Zend/Controller/Action/HelperBroker/PriorityStack.php deleted file mode 100644 index 24630fdc47a..00000000000 --- a/lib/Zend/Controller/Action/HelperBroker/PriorityStack.php +++ /dev/null @@ -1,280 +0,0 @@ -_helpersByNameRef)) { - return false; - } - - return $this->_helpersByNameRef[$helperName]; - } - - /** - * Magic property overloading for returning if helper is set by name - * - * @param string $helperName The helper name - * @return Zend_Controller_Action_Helper_Abstract - */ - public function __isset($helperName) - { - return array_key_exists($helperName, $this->_helpersByNameRef); - } - - /** - * Magic property overloading for unsetting if helper is exists by name - * - * @param string $helperName The helper name - * @return Zend_Controller_Action_Helper_Abstract - */ - public function __unset($helperName) - { - return $this->offsetUnset($helperName); - } - - /** - * push helper onto the stack - * - * @param Zend_Controller_Action_Helper_Abstract $helper - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public function push(Zend_Controller_Action_Helper_Abstract $helper) - { - $this->offsetSet($this->getNextFreeHigherPriority(), $helper); - return $this; - } - - /** - * Return something iterable - * - * @return array - */ - public function getIterator() - { - return new ArrayObject($this->_helpersByPriority); - } - - /** - * offsetExists() - * - * @param int|string $priorityOrHelperName - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public function offsetExists($priorityOrHelperName) - { - if (is_string($priorityOrHelperName)) { - return array_key_exists($priorityOrHelperName, $this->_helpersByNameRef); - } else { - return array_key_exists($priorityOrHelperName, $this->_helpersByPriority); - } - } - - /** - * offsetGet() - * - * @param int|string $priorityOrHelperName - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public function offsetGet($priorityOrHelperName) - { - if (!$this->offsetExists($priorityOrHelperName)) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('A helper with priority ' . $priorityOrHelperName . ' does not exist.'); - } - - if (is_string($priorityOrHelperName)) { - return $this->_helpersByNameRef[$priorityOrHelperName]; - } else { - return $this->_helpersByPriority[$priorityOrHelperName]; - } - } - - /** - * offsetSet() - * - * @param int $priority - * @param Zend_Controller_Action_Helper_Abstract $helper - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public function offsetSet($priority, $helper) - { - $priority = (int) $priority; - - if (!$helper instanceof Zend_Controller_Action_Helper_Abstract) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('$helper must extend Zend_Controller_Action_Helper_Abstract.'); - } - - if (array_key_exists($helper->getName(), $this->_helpersByNameRef)) { - // remove any object with the same name to retain BC compailitbility - // @todo At ZF 2.0 time throw an exception here. - $this->offsetUnset($helper->getName()); - } - - if (array_key_exists($priority, $this->_helpersByPriority)) { - $priority = $this->getNextFreeHigherPriority($priority); // ensures LIFO - trigger_error("A helper with the same priority already exists, reassigning to $priority", E_USER_WARNING); - } - - $this->_helpersByPriority[$priority] = $helper; - $this->_helpersByNameRef[$helper->getName()] = $helper; - - if ($priority == ($nextFreeDefault = $this->getNextFreeHigherPriority($this->_nextDefaultPriority))) { - $this->_nextDefaultPriority = $nextFreeDefault; - } - - krsort($this->_helpersByPriority); // always make sure priority and LIFO are both enforced - return $this; - } - - /** - * offsetUnset() - * - * @param int|string $priorityOrHelperName Priority integer or the helper name - * @return Zend_Controller_Action_HelperBroker_PriorityStack - */ - public function offsetUnset($priorityOrHelperName) - { - if (!$this->offsetExists($priorityOrHelperName)) { - #require_once 'Zend/Controller/Action/Exception.php'; - throw new Zend_Controller_Action_Exception('A helper with priority or name ' . $priorityOrHelperName . ' does not exist.'); - } - - if (is_string($priorityOrHelperName)) { - $helperName = $priorityOrHelperName; - $helper = $this->_helpersByNameRef[$helperName]; - $priority = array_search($helper, $this->_helpersByPriority, true); - } else { - $priority = $priorityOrHelperName; - $helperName = $this->_helpersByPriority[$priorityOrHelperName]->getName(); - } - - unset($this->_helpersByNameRef[$helperName]); - unset($this->_helpersByPriority[$priority]); - return $this; - } - - /** - * return the count of helpers - * - * @return int - */ - public function count() - { - return count($this->_helpersByPriority); - } - - /** - * Find the next free higher priority. If an index is given, it will - * find the next free highest priority after it. - * - * @param int $indexPriority OPTIONAL - * @return int - */ - public function getNextFreeHigherPriority($indexPriority = null) - { - if ($indexPriority == null) { - $indexPriority = $this->_nextDefaultPriority; - } - - $priorities = array_keys($this->_helpersByPriority); - - while (in_array($indexPriority, $priorities)) { - $indexPriority++; - } - - return $indexPriority; - } - - /** - * Find the next free lower priority. If an index is given, it will - * find the next free lower priority before it. - * - * @param int $indexPriority - * @return int - */ - public function getNextFreeLowerPriority($indexPriority = null) - { - if ($indexPriority == null) { - $indexPriority = $this->_nextDefaultPriority; - } - - $priorities = array_keys($this->_helpersByPriority); - - while (in_array($indexPriority, $priorities)) { - $indexPriority--; - } - - return $indexPriority; - } - - /** - * return the highest priority - * - * @return int - */ - public function getHighestPriority() - { - return max(array_keys($this->_helpersByPriority)); - } - - /** - * return the lowest priority - * - * @return int - */ - public function getLowestPriority() - { - return min(array_keys($this->_helpersByPriority)); - } - - /** - * return the helpers referenced by name - * - * @return array - */ - public function getHelpersByName() - { - return $this->_helpersByNameRef; - } - -} diff --git a/lib/Zend/Controller/Action/Interface.php b/lib/Zend/Controller/Action/Interface.php deleted file mode 100644 index db354637a10..00000000000 --- a/lib/Zend/Controller/Action/Interface.php +++ /dev/null @@ -1,69 +0,0 @@ -setParams($params); - } - - /** - * Formats a string into a controller name. This is used to take a raw - * controller name, such as one stored inside a Zend_Controller_Request_Abstract - * object, and reformat it to a proper class name that a class extending - * Zend_Controller_Action would use. - * - * @param string $unformatted - * @return string - */ - public function formatControllerName($unformatted) - { - return ucfirst($this->_formatName($unformatted)) . 'Controller'; - } - - /** - * Formats a string into an action name. This is used to take a raw - * action name, such as one that would be stored inside a Zend_Controller_Request_Abstract - * object, and reformat into a proper method name that would be found - * inside a class extending Zend_Controller_Action. - * - * @param string $unformatted - * @return string - */ - public function formatActionName($unformatted) - { - $formatted = $this->_formatName($unformatted, true); - return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . 'Action'; - } - - /** - * Verify delimiter - * - * Verify a delimiter to use in controllers or actions. May be a single - * string or an array of strings. - * - * @param string|array $spec - * @return array - * @throws Zend_Controller_Dispatcher_Exception with invalid delimiters - */ - public function _verifyDelimiter($spec) - { - if (is_string($spec)) { - return (array) $spec; - } elseif (is_array($spec)) { - $allStrings = true; - foreach ($spec as $delim) { - if (!is_string($delim)) { - $allStrings = false; - break; - } - } - - if (!$allStrings) { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Word delimiter array must contain only strings'); - } - - return $spec; - } - - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Invalid word delimiter'); - } - - /** - * Retrieve the word delimiter character(s) used in - * controller or action names - * - * @return array - */ - public function getWordDelimiter() - { - return $this->_wordDelimiter; - } - - /** - * Set word delimiter - * - * Set the word delimiter to use in controllers and actions. May be a - * single string or an array of strings. - * - * @param string|array $spec - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setWordDelimiter($spec) - { - $spec = $this->_verifyDelimiter($spec); - $this->_wordDelimiter = $spec; - - return $this; - } - - /** - * Retrieve the path delimiter character(s) used in - * controller names - * - * @return array - */ - public function getPathDelimiter() - { - return $this->_pathDelimiter; - } - - /** - * Set path delimiter - * - * Set the path delimiter to use in controllers. May be a single string or - * an array of strings. - * - * @param string $spec - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setPathDelimiter($spec) - { - if (!is_string($spec)) { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Invalid path delimiter'); - } - $this->_pathDelimiter = $spec; - - return $this; - } - - /** - * Formats a string from a URI into a PHP-friendly name. - * - * By default, replaces words separated by the word separator character(s) - * with camelCaps. If $isAction is false, it also preserves replaces words - * separated by the path separation character with an underscore, making - * the following word Title cased. All non-alphanumeric characters are - * removed. - * - * @param string $unformatted - * @param boolean $isAction Defaults to false - * @return string - */ - protected function _formatName($unformatted, $isAction = false) - { - // preserve directories - if (!$isAction) { - $segments = explode($this->getPathDelimiter(), $unformatted); - } else { - $segments = (array) $unformatted; - } - - foreach ($segments as $key => $segment) { - $segment = str_replace($this->getWordDelimiter(), ' ', strtolower($segment)); - $segment = preg_replace('/[^a-z0-9 ]/', '', $segment); - $segments[$key] = str_replace(' ', '', ucwords($segment)); - } - - return implode('_', $segments); - } - - /** - * Retrieve front controller instance - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - if (null === $this->_frontController) { - #require_once 'Zend/Controller/Front.php'; - $this->_frontController = Zend_Controller_Front::getInstance(); - } - - return $this->_frontController; - } - - /** - * Set front controller instance - * - * @param Zend_Controller_Front $controller - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setFrontController(Zend_Controller_Front $controller) - { - $this->_frontController = $controller; - return $this; - } - - /** - * Add or modify a parameter to use when instantiating an action controller - * - * @param string $name - * @param mixed $value - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setParam($name, $value) - { - $name = (string) $name; - $this->_invokeParams[$name] = $value; - return $this; - } - - /** - * Set parameters to pass to action controller constructors - * - * @param array $params - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setParams(array $params) - { - $this->_invokeParams = array_merge($this->_invokeParams, $params); - return $this; - } - - /** - * Retrieve a single parameter from the controller parameter stack - * - * @param string $name - * @return mixed - */ - public function getParam($name) - { - if(isset($this->_invokeParams[$name])) { - return $this->_invokeParams[$name]; - } - - return null; - } - - /** - * Retrieve action controller instantiation parameters - * - * @return array - */ - public function getParams() - { - return $this->_invokeParams; - } - - /** - * Clear the controller parameter stack - * - * By default, clears all parameters. If a parameter name is given, clears - * only that parameter; if an array of parameter names is provided, clears - * each. - * - * @param null|string|array single key or array of keys for params to clear - * @return Zend_Controller_Dispatcher_Abstract - */ - public function clearParams($name = null) - { - if (null === $name) { - $this->_invokeParams = array(); - } elseif (is_string($name) && isset($this->_invokeParams[$name])) { - unset($this->_invokeParams[$name]); - } elseif (is_array($name)) { - foreach ($name as $key) { - if (is_string($key) && isset($this->_invokeParams[$key])) { - unset($this->_invokeParams[$key]); - } - } - } - - return $this; - } - - /** - * Set response object to pass to action controllers - * - * @param Zend_Controller_Response_Abstract|null $response - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setResponse(Zend_Controller_Response_Abstract $response = null) - { - $this->_response = $response; - return $this; - } - - /** - * Return the registered response object - * - * @return Zend_Controller_Response_Abstract|null - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Set the default controller (minus any formatting) - * - * @param string $controller - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setDefaultControllerName($controller) - { - $this->_defaultController = (string) $controller; - return $this; - } - - /** - * Retrieve the default controller name (minus formatting) - * - * @return string - */ - public function getDefaultControllerName() - { - return $this->_defaultController; - } - - /** - * Set the default action (minus any formatting) - * - * @param string $action - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setDefaultAction($action) - { - $this->_defaultAction = (string) $action; - return $this; - } - - /** - * Retrieve the default action name (minus formatting) - * - * @return string - */ - public function getDefaultAction() - { - return $this->_defaultAction; - } - - /** - * Set the default module - * - * @param string $module - * @return Zend_Controller_Dispatcher_Abstract - */ - public function setDefaultModule($module) - { - $this->_defaultModule = (string) $module; - return $this; - } - - /** - * Retrieve the default module - * - * @return string - */ - public function getDefaultModule() - { - return $this->_defaultModule; - } -} diff --git a/lib/Zend/Controller/Dispatcher/Exception.php b/lib/Zend/Controller/Dispatcher/Exception.php deleted file mode 100644 index 7a295dc4470..00000000000 --- a/lib/Zend/Controller/Dispatcher/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_curModule = $this->getDefaultModule(); - } - - /** - * Add a single path to the controller directory stack - * - * @param string $path - * @param string $module - * @return Zend_Controller_Dispatcher_Standard - */ - public function addControllerDirectory($path, $module = null) - { - if (null === $module) { - $module = $this->_defaultModule; - } - - $module = (string) $module; - $path = rtrim((string) $path, '/\\'); - - $this->_controllerDirectory[$module] = $path; - return $this; - } - - /** - * Set controller directory - * - * @param array|string $directory - * @return Zend_Controller_Dispatcher_Standard - */ - public function setControllerDirectory($directory, $module = null) - { - $this->_controllerDirectory = array(); - - if (is_string($directory)) { - $this->addControllerDirectory($directory, $module); - } elseif (is_array($directory)) { - foreach ((array) $directory as $module => $path) { - $this->addControllerDirectory($path, $module); - } - } else { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Controller directory spec must be either a string or an array'); - } - - return $this; - } - - /** - * Return the currently set directories for Zend_Controller_Action class - * lookup - * - * If a module is specified, returns just that directory. - * - * @param string $module Module name - * @return array|string Returns array of all directories by default, single - * module directory if module argument provided - */ - public function getControllerDirectory($module = null) - { - if (null === $module) { - return $this->_controllerDirectory; - } - - $module = (string) $module; - if (array_key_exists($module, $this->_controllerDirectory)) { - return $this->_controllerDirectory[$module]; - } - - return null; - } - - /** - * Remove a controller directory by module name - * - * @param string $module - * @return bool - */ - public function removeControllerDirectory($module) - { - $module = (string) $module; - if (array_key_exists($module, $this->_controllerDirectory)) { - unset($this->_controllerDirectory[$module]); - return true; - } - return false; - } - - /** - * Format the module name. - * - * @param string $unformatted - * @return string - */ - public function formatModuleName($unformatted) - { - if (($this->_defaultModule == $unformatted) && !$this->getParam('prefixDefaultModule')) { - return $unformatted; - } - - return ucfirst($this->_formatName($unformatted)); - } - - /** - * Format action class name - * - * @param string $moduleName Name of the current module - * @param string $className Name of the action class - * @return string Formatted class name - */ - public function formatClassName($moduleName, $className) - { - return $this->formatModuleName($moduleName) . '_' . $className; - } - - /** - * Convert a class name to a filename - * - * @param string $class - * @return string - */ - public function classToFilename($class) - { - return str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; - } - - /** - * Returns TRUE if the Zend_Controller_Request_Abstract object can be - * dispatched to a controller. - * - * Use this method wisely. By default, the dispatcher will fall back to the - * default controller (either in the module specified or the global default) - * if a given controller does not exist. This method returning false does - * not necessarily indicate the dispatcher will not still dispatch the call. - * - * @param Zend_Controller_Request_Abstract $action - * @return boolean - */ - public function isDispatchable(Zend_Controller_Request_Abstract $request) - { - $className = $this->getControllerClass($request); - if (!$className) { - return false; - } - - $finalClass = $className; - if (($this->_defaultModule != $this->_curModule) - || $this->getParam('prefixDefaultModule')) - { - $finalClass = $this->formatClassName($this->_curModule, $className); - } - if (class_exists($finalClass, false)) { - return true; - } - - $fileSpec = $this->classToFilename($className); - $dispatchDir = $this->getDispatchDirectory(); - $test = $dispatchDir . DIRECTORY_SEPARATOR . $fileSpec; - return Zend_Loader::isReadable($test); - } - - /** - * Dispatch to a controller/action - * - * By default, if a controller is not dispatchable, dispatch() will throw - * an exception. If you wish to use the default controller instead, set the - * param 'useDefaultControllerAlways' via {@link setParam()}. - * - * @param Zend_Controller_Request_Abstract $request - * @param Zend_Controller_Response_Abstract $response - * @return void - * @throws Zend_Controller_Dispatcher_Exception - */ - public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response) - { - $this->setResponse($response); - - /** - * Get controller class - */ - if (!$this->isDispatchable($request)) { - $controller = $request->getControllerName(); - if (!$this->getParam('useDefaultControllerAlways') && !empty($controller)) { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Invalid controller specified (' . $request->getControllerName() . ')'); - } - - $className = $this->getDefaultControllerClass($request); - } else { - $className = $this->getControllerClass($request); - if (!$className) { - $className = $this->getDefaultControllerClass($request); - } - } - - /** - * If we're in a module or prefixDefaultModule is on, we must add the module name - * prefix to the contents of $className, as getControllerClass does not do that automatically. - * We must keep a separate variable because modules are not strictly PSR-0: We need the no-module-prefix - * class name to do the class->file mapping, but the full class name to insantiate the controller - */ - $moduleClassName = $className; - if (($this->_defaultModule != $this->_curModule) - || $this->getParam('prefixDefaultModule')) - { - $moduleClassName = $this->formatClassName($this->_curModule, $className); - } - - /** - * Load the controller class file - */ - $className = $this->loadClass($className); - - /** - * Instantiate controller with request, response, and invocation - * arguments; throw exception if it's not an action controller - */ - $controller = new $moduleClassName($request, $this->getResponse(), $this->getParams()); - if (!($controller instanceof Zend_Controller_Action_Interface) && - !($controller instanceof Zend_Controller_Action)) { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception( - 'Controller "' . $moduleClassName . '" is not an instance of Zend_Controller_Action_Interface' - ); - } - - /** - * Retrieve the action name - */ - $action = $this->getActionMethod($request); - - /** - * Dispatch the method call - */ - $request->setDispatched(true); - - // by default, buffer output - $disableOb = $this->getParam('disableOutputBuffering'); - $obLevel = ob_get_level(); - if (empty($disableOb)) { - ob_start(); - } - - try { - $controller->dispatch($action); - } catch (Exception $e) { - // Clean output buffer on error - $curObLevel = ob_get_level(); - if ($curObLevel > $obLevel) { - do { - ob_get_clean(); - $curObLevel = ob_get_level(); - } while ($curObLevel > $obLevel); - } - throw $e; - } - - if (empty($disableOb)) { - $content = ob_get_clean(); - $response->appendBody($content); - } - - // Destroy the page controller instance and reflection objects - $controller = null; - } - - /** - * Load a controller class - * - * Attempts to load the controller class file from - * {@link getControllerDirectory()}. If the controller belongs to a - * module, looks for the module prefix to the controller class. - * - * @param string $className - * @return string Class name loaded - * @throws Zend_Controller_Dispatcher_Exception if class not loaded - */ - public function loadClass($className) - { - $finalClass = $className; - if (($this->_defaultModule != $this->_curModule) - || $this->getParam('prefixDefaultModule')) - { - $finalClass = $this->formatClassName($this->_curModule, $className); - } - if (class_exists($finalClass, false)) { - return $finalClass; - } - - $dispatchDir = $this->getDispatchDirectory(); - $loadFile = $dispatchDir . DIRECTORY_SEPARATOR . $this->classToFilename($className); - - if (Zend_Loader::isReadable($loadFile)) { - include_once $loadFile; - } else { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Cannot load controller class "' . $className . '" from file "' . $loadFile . "'"); - } - - if (!class_exists($finalClass, false)) { - #require_once 'Zend/Controller/Dispatcher/Exception.php'; - throw new Zend_Controller_Dispatcher_Exception('Invalid controller class ("' . $finalClass . '")'); - } - - return $finalClass; - } - - /** - * Get controller class name - * - * Try request first; if not found, try pulling from request parameter; - * if still not found, fallback to default - * - * @param Zend_Controller_Request_Abstract $request - * @return string|false Returns class name on success - */ - public function getControllerClass(Zend_Controller_Request_Abstract $request) - { - $controllerName = $request->getControllerName(); - if (empty($controllerName)) { - if (!$this->getParam('useDefaultControllerAlways')) { - return false; - } - $controllerName = $this->getDefaultControllerName(); - $request->setControllerName($controllerName); - } - - $className = $this->formatControllerName($controllerName); - - $controllerDirs = $this->getControllerDirectory(); - $module = $request->getModuleName(); - if ($this->isValidModule($module)) { - $this->_curModule = $module; - $this->_curDirectory = $controllerDirs[$module]; - } elseif ($this->isValidModule($this->_defaultModule)) { - $request->setModuleName($this->_defaultModule); - $this->_curModule = $this->_defaultModule; - $this->_curDirectory = $controllerDirs[$this->_defaultModule]; - } else { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('No default module defined for this application'); - } - - return $className; - } - - /** - * Determine if a given module is valid - * - * @param string $module - * @return bool - */ - public function isValidModule($module) - { - if (!is_string($module)) { - return false; - } - - $module = strtolower($module); - $controllerDir = $this->getControllerDirectory(); - foreach (array_keys($controllerDir) as $moduleName) { - if ($module == strtolower($moduleName)) { - return true; - } - } - - return false; - } - - /** - * Retrieve default controller class - * - * Determines whether the default controller to use lies within the - * requested module, or if the global default should be used. - * - * By default, will only use the module default unless that controller does - * not exist; if this is the case, it falls back to the default controller - * in the default module. - * - * @param Zend_Controller_Request_Abstract $request - * @return string - */ - public function getDefaultControllerClass(Zend_Controller_Request_Abstract $request) - { - $controller = $this->getDefaultControllerName(); - $default = $this->formatControllerName($controller); - $request->setControllerName($controller) - ->setActionName(null); - - $module = $request->getModuleName(); - $controllerDirs = $this->getControllerDirectory(); - $this->_curModule = $this->_defaultModule; - $this->_curDirectory = $controllerDirs[$this->_defaultModule]; - if ($this->isValidModule($module)) { - $found = false; - if (class_exists($default, false)) { - $found = true; - } else { - $moduleDir = $controllerDirs[$module]; - $fileSpec = $moduleDir . DIRECTORY_SEPARATOR . $this->classToFilename($default); - if (Zend_Loader::isReadable($fileSpec)) { - $found = true; - $this->_curDirectory = $moduleDir; - } - } - if ($found) { - $request->setModuleName($module); - $this->_curModule = $this->formatModuleName($module); - } - } else { - $request->setModuleName($this->_defaultModule); - } - - return $default; - } - - /** - * Return the value of the currently selected dispatch directory (as set by - * {@link getController()}) - * - * @return string - */ - public function getDispatchDirectory() - { - return $this->_curDirectory; - } - - /** - * Determine the action name - * - * First attempt to retrieve from request; then from request params - * using action key; default to default action - * - * Returns formatted action name - * - * @param Zend_Controller_Request_Abstract $request - * @return string - */ - public function getActionMethod(Zend_Controller_Request_Abstract $request) - { - $action = $request->getActionName(); - if (empty($action)) { - $action = $this->getDefaultAction(); - $request->setActionName($action); - } - - return $this->formatActionName($action); - } -} diff --git a/lib/Zend/Controller/Exception.php b/lib/Zend/Controller/Exception.php deleted file mode 100644 index f9f04819f5d..00000000000 --- a/lib/Zend/Controller/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_plugins = new Zend_Controller_Plugin_Broker(); - } - - /** - * Enforce singleton; disallow cloning - * - * @return void - */ - private function __clone() - { - } - - /** - * Singleton instance - * - * @return Zend_Controller_Front - */ - public static function getInstance() - { - if (null === self::$_instance) { - self::$_instance = new self(); - } - - return self::$_instance; - } - - /** - * Resets all object properties of the singleton instance - * - * Primarily used for testing; could be used to chain front controllers. - * - * Also resets action helper broker, clearing all registered helpers. - * - * @return void - */ - public function resetInstance() - { - $reflection = new ReflectionObject($this); - foreach ($reflection->getProperties() as $property) { - $name = $property->getName(); - switch ($name) { - case '_instance': - break; - case '_controllerDir': - case '_invokeParams': - $this->{$name} = array(); - break; - case '_plugins': - $this->{$name} = new Zend_Controller_Plugin_Broker(); - break; - case '_throwExceptions': - case '_returnResponse': - $this->{$name} = false; - break; - case '_moduleControllerDirectoryName': - $this->{$name} = 'controllers'; - break; - default: - $this->{$name} = null; - break; - } - } - Zend_Controller_Action_HelperBroker::resetHelpers(); - } - - /** - * Convenience feature, calls setControllerDirectory()->setRouter()->dispatch() - * - * In PHP 5.1.x, a call to a static method never populates $this -- so run() - * may actually be called after setting up your front controller. - * - * @param string|array $controllerDirectory Path to Zend_Controller_Action - * controller classes or array of such paths - * @return void - * @throws Zend_Controller_Exception if called from an object instance - */ - public static function run($controllerDirectory) - { - self::getInstance() - ->setControllerDirectory($controllerDirectory) - ->dispatch(); - } - - /** - * Add a controller directory to the controller directory stack - * - * If $args is presented and is a string, uses it for the array key mapping - * to the directory specified. - * - * @param string $directory - * @param string $module Optional argument; module with which to associate directory. If none provided, assumes 'default' - * @return Zend_Controller_Front - * @throws Zend_Controller_Exception if directory not found or readable - */ - public function addControllerDirectory($directory, $module = null) - { - $this->getDispatcher()->addControllerDirectory($directory, $module); - return $this; - } - - /** - * Set controller directory - * - * Stores controller directory(ies) in dispatcher. May be an array of - * directories or a string containing a single directory. - * - * @param string|array $directory Path to Zend_Controller_Action controller - * classes or array of such paths - * @param string $module Optional module name to use with string $directory - * @return Zend_Controller_Front - */ - public function setControllerDirectory($directory, $module = null) - { - $this->getDispatcher()->setControllerDirectory($directory, $module); - return $this; - } - - /** - * Retrieve controller directory - * - * Retrieves: - * - Array of all controller directories if no $name passed - * - String path if $name passed and exists as a key in controller directory array - * - null if $name passed but does not exist in controller directory keys - * - * @param string $name Default null - * @return array|string|null - */ - public function getControllerDirectory($name = null) - { - return $this->getDispatcher()->getControllerDirectory($name); - } - - /** - * Remove a controller directory by module name - * - * @param string $module - * @return bool - */ - public function removeControllerDirectory($module) - { - return $this->getDispatcher()->removeControllerDirectory($module); - } - - /** - * Specify a directory as containing modules - * - * Iterates through the directory, adding any subdirectories as modules; - * the subdirectory within each module named after {@link $_moduleControllerDirectoryName} - * will be used as the controller directory path. - * - * @param string $path - * @return Zend_Controller_Front - */ - public function addModuleDirectory($path) - { - try{ - $dir = new DirectoryIterator($path); - } catch(Exception $e) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception("Directory $path not readable", 0, $e); - } - foreach ($dir as $file) { - if ($file->isDot() || !$file->isDir()) { - continue; - } - - $module = $file->getFilename(); - - // Don't use SCCS directories as modules - if (preg_match('/^[^a-z]/i', $module) || ('CVS' == $module)) { - continue; - } - - $moduleDir = $file->getPathname() . DIRECTORY_SEPARATOR . $this->getModuleControllerDirectoryName(); - $this->addControllerDirectory($moduleDir, $module); - } - - return $this; - } - - /** - * Return the path to a module directory (but not the controllers directory within) - * - * @param string $module - * @return string|null - */ - public function getModuleDirectory($module = null) - { - if (null === $module) { - $request = $this->getRequest(); - if (null !== $request) { - $module = $this->getRequest()->getModuleName(); - } - if (empty($module)) { - $module = $this->getDispatcher()->getDefaultModule(); - } - } - - $controllerDir = $this->getControllerDirectory($module); - - if ((null === $controllerDir) || !is_string($controllerDir)) { - return null; - } - - return dirname($controllerDir); - } - - /** - * Set the directory name within a module containing controllers - * - * @param string $name - * @return Zend_Controller_Front - */ - public function setModuleControllerDirectoryName($name = 'controllers') - { - $this->_moduleControllerDirectoryName = (string) $name; - - return $this; - } - - /** - * Return the directory name within a module containing controllers - * - * @return string - */ - public function getModuleControllerDirectoryName() - { - return $this->_moduleControllerDirectoryName; - } - - /** - * Set the default controller (unformatted string) - * - * @param string $controller - * @return Zend_Controller_Front - */ - public function setDefaultControllerName($controller) - { - $dispatcher = $this->getDispatcher(); - $dispatcher->setDefaultControllerName($controller); - return $this; - } - - /** - * Retrieve the default controller (unformatted string) - * - * @return string - */ - public function getDefaultControllerName() - { - return $this->getDispatcher()->getDefaultControllerName(); - } - - /** - * Set the default action (unformatted string) - * - * @param string $action - * @return Zend_Controller_Front - */ - public function setDefaultAction($action) - { - $dispatcher = $this->getDispatcher(); - $dispatcher->setDefaultAction($action); - return $this; - } - - /** - * Retrieve the default action (unformatted string) - * - * @return string - */ - public function getDefaultAction() - { - return $this->getDispatcher()->getDefaultAction(); - } - - /** - * Set the default module name - * - * @param string $module - * @return Zend_Controller_Front - */ - public function setDefaultModule($module) - { - $dispatcher = $this->getDispatcher(); - $dispatcher->setDefaultModule($module); - return $this; - } - - /** - * Retrieve the default module - * - * @return string - */ - public function getDefaultModule() - { - return $this->getDispatcher()->getDefaultModule(); - } - - /** - * Set request class/object - * - * Set the request object. The request holds the request environment. - * - * If a class name is provided, it will instantiate it - * - * @param string|Zend_Controller_Request_Abstract $request - * @throws Zend_Controller_Exception if invalid request class - * @return Zend_Controller_Front - */ - public function setRequest($request) - { - if (is_string($request)) { - if (!class_exists($request)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($request); - } - $request = new $request(); - } - if (!$request instanceof Zend_Controller_Request_Abstract) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid request class'); - } - - $this->_request = $request; - - return $this; - } - - /** - * Return the request object. - * - * @return null|Zend_Controller_Request_Abstract - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Set router class/object - * - * Set the router object. The router is responsible for mapping - * the request to a controller and action. - * - * If a class name is provided, instantiates router with any parameters - * registered via {@link setParam()} or {@link setParams()}. - * - * @param string|Zend_Controller_Router_Interface $router - * @throws Zend_Controller_Exception if invalid router class - * @return Zend_Controller_Front - */ - public function setRouter($router) - { - if (is_string($router)) { - if (!class_exists($router)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($router); - } - $router = new $router(); - } - - if (!$router instanceof Zend_Controller_Router_Interface) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid router class'); - } - - $router->setFrontController($this); - $this->_router = $router; - - return $this; - } - - /** - * Return the router object. - * - * Instantiates a Zend_Controller_Router_Rewrite object if no router currently set. - * - * @return Zend_Controller_Router_Interface - */ - public function getRouter() - { - if (null == $this->_router) { - #require_once 'Zend/Controller/Router/Rewrite.php'; - $this->setRouter(new Zend_Controller_Router_Rewrite()); - } - - return $this->_router; - } - - /** - * Set the base URL used for requests - * - * Use to set the base URL segment of the REQUEST_URI to use when - * determining PATH_INFO, etc. Examples: - * - /admin - * - /myapp - * - /subdir/index.php - * - * Note that the URL should not include the full URI. Do not use: - * - http://example.com/admin - * - http://example.com/myapp - * - http://example.com/subdir/index.php - * - * If a null value is passed, this can be used as well for autodiscovery (default). - * - * @param string $base - * @return Zend_Controller_Front - * @throws Zend_Controller_Exception for non-string $base - */ - public function setBaseUrl($base = null) - { - if (!is_string($base) && (null !== $base)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Rewrite base must be a string'); - } - - $this->_baseUrl = $base; - - if ((null !== ($request = $this->getRequest())) && (method_exists($request, 'setBaseUrl'))) { - $request->setBaseUrl($base); - } - - return $this; - } - - /** - * Retrieve the currently set base URL - * - * @return string - */ - public function getBaseUrl() - { - $request = $this->getRequest(); - if ((null !== $request) && method_exists($request, 'getBaseUrl')) { - return $request->getBaseUrl(); - } - - return $this->_baseUrl; - } - - /** - * Set the dispatcher object. The dispatcher is responsible for - * taking a Zend_Controller_Dispatcher_Token object, instantiating the controller, and - * call the action method of the controller. - * - * @param Zend_Controller_Dispatcher_Interface $dispatcher - * @return Zend_Controller_Front - */ - public function setDispatcher(Zend_Controller_Dispatcher_Interface $dispatcher) - { - $this->_dispatcher = $dispatcher; - return $this; - } - - /** - * Return the dispatcher object. - * - * @return Zend_Controller_Dispatcher_Interface - */ - public function getDispatcher() - { - /** - * Instantiate the default dispatcher if one was not set. - */ - if (!$this->_dispatcher instanceof Zend_Controller_Dispatcher_Interface) { - #require_once 'Zend/Controller/Dispatcher/Standard.php'; - $this->_dispatcher = new Zend_Controller_Dispatcher_Standard(); - } - return $this->_dispatcher; - } - - /** - * Set response class/object - * - * Set the response object. The response is a container for action - * responses and headers. Usage is optional. - * - * If a class name is provided, instantiates a response object. - * - * @param string|Zend_Controller_Response_Abstract $response - * @throws Zend_Controller_Exception if invalid response class - * @return Zend_Controller_Front - */ - public function setResponse($response) - { - if (is_string($response)) { - if (!class_exists($response)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($response); - } - $response = new $response(); - } - if (!$response instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid response class'); - } - - $this->_response = $response; - - return $this; - } - - /** - * Return the response object. - * - * @return null|Zend_Controller_Response_Abstract - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Add or modify a parameter to use when instantiating an action controller - * - * @param string $name - * @param mixed $value - * @return Zend_Controller_Front - */ - public function setParam($name, $value) - { - $name = (string) $name; - $this->_invokeParams[$name] = $value; - return $this; - } - - /** - * Set parameters to pass to action controller constructors - * - * @param array $params - * @return Zend_Controller_Front - */ - public function setParams(array $params) - { - $this->_invokeParams = array_merge($this->_invokeParams, $params); - return $this; - } - - /** - * Retrieve a single parameter from the controller parameter stack - * - * @param string $name - * @return mixed - */ - public function getParam($name) - { - if(isset($this->_invokeParams[$name])) { - return $this->_invokeParams[$name]; - } - - return null; - } - - /** - * Retrieve action controller instantiation parameters - * - * @return array - */ - public function getParams() - { - return $this->_invokeParams; - } - - /** - * Clear the controller parameter stack - * - * By default, clears all parameters. If a parameter name is given, clears - * only that parameter; if an array of parameter names is provided, clears - * each. - * - * @param null|string|array single key or array of keys for params to clear - * @return Zend_Controller_Front - */ - public function clearParams($name = null) - { - if (null === $name) { - $this->_invokeParams = array(); - } elseif (is_string($name) && isset($this->_invokeParams[$name])) { - unset($this->_invokeParams[$name]); - } elseif (is_array($name)) { - foreach ($name as $key) { - if (is_string($key) && isset($this->_invokeParams[$key])) { - unset($this->_invokeParams[$key]); - } - } - } - - return $this; - } - - /** - * Register a plugin. - * - * @param Zend_Controller_Plugin_Abstract $plugin - * @param int $stackIndex Optional; stack index for plugin - * @return Zend_Controller_Front - */ - public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null) - { - $this->_plugins->registerPlugin($plugin, $stackIndex); - return $this; - } - - /** - * Unregister a plugin. - * - * @param string|Zend_Controller_Plugin_Abstract $plugin Plugin class or object to unregister - * @return Zend_Controller_Front - */ - public function unregisterPlugin($plugin) - { - $this->_plugins->unregisterPlugin($plugin); - return $this; - } - - /** - * Is a particular plugin registered? - * - * @param string $class - * @return bool - */ - public function hasPlugin($class) - { - return $this->_plugins->hasPlugin($class); - } - - /** - * Retrieve a plugin or plugins by class - * - * @param string $class - * @return false|Zend_Controller_Plugin_Abstract|array - */ - public function getPlugin($class) - { - return $this->_plugins->getPlugin($class); - } - - /** - * Retrieve all plugins - * - * @return array - */ - public function getPlugins() - { - return $this->_plugins->getPlugins(); - } - - /** - * Set the throwExceptions flag and retrieve current status - * - * Set whether exceptions encounted in the dispatch loop should be thrown - * or caught and trapped in the response object. - * - * Default behaviour is to trap them in the response object; call this - * method to have them thrown. - * - * Passing no value will return the current value of the flag; passing a - * boolean true or false value will set the flag and return the current - * object instance. - * - * @param boolean $flag Defaults to null (return flag state) - * @return boolean|Zend_Controller_Front Used as a setter, returns object; as a getter, returns boolean - */ - public function throwExceptions($flag = null) - { - if ($flag !== null) { - $this->_throwExceptions = (bool) $flag; - return $this; - } - - return $this->_throwExceptions; - } - - /** - * Set whether {@link dispatch()} should return the response without first - * rendering output. By default, output is rendered and dispatch() returns - * nothing. - * - * @param boolean $flag - * @return boolean|Zend_Controller_Front Used as a setter, returns object; as a getter, returns boolean - */ - public function returnResponse($flag = null) - { - if (true === $flag) { - $this->_returnResponse = true; - return $this; - } elseif (false === $flag) { - $this->_returnResponse = false; - return $this; - } - - return $this->_returnResponse; - } - - /** - * Dispatch an HTTP request to a controller/action. - * - * @param Zend_Controller_Request_Abstract|null $request - * @param Zend_Controller_Response_Abstract|null $response - * @return void|Zend_Controller_Response_Abstract Returns response object if returnResponse() is true - */ - public function dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null) - { - if (!$this->getParam('noErrorHandler') && !$this->_plugins->hasPlugin('Zend_Controller_Plugin_ErrorHandler')) { - // Register with stack index of 100 - #require_once 'Zend/Controller/Plugin/ErrorHandler.php'; - $this->_plugins->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(), 100); - } - - if (!$this->getParam('noViewRenderer') && !Zend_Controller_Action_HelperBroker::hasHelper('viewRenderer')) { - #require_once 'Zend/Controller/Action/Helper/ViewRenderer.php'; - Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-80, new Zend_Controller_Action_Helper_ViewRenderer()); - } - - /** - * Instantiate default request object (HTTP version) if none provided - */ - if (null !== $request) { - $this->setRequest($request); - } elseif ((null === $request) && (null === ($request = $this->getRequest()))) { - #require_once 'Zend/Controller/Request/Http.php'; - $request = new Zend_Controller_Request_Http(); - $this->setRequest($request); - } - - /** - * Set base URL of request object, if available - */ - if (is_callable(array($this->_request, 'setBaseUrl'))) { - if (null !== $this->_baseUrl) { - $this->_request->setBaseUrl($this->_baseUrl); - } - } - - /** - * Instantiate default response object (HTTP version) if none provided - */ - if (null !== $response) { - $this->setResponse($response); - } elseif ((null === $this->_response) && (null === ($this->_response = $this->getResponse()))) { - #require_once 'Zend/Controller/Response/Http.php'; - $response = new Zend_Controller_Response_Http(); - $this->setResponse($response); - } - - /** - * Register request and response objects with plugin broker - */ - $this->_plugins - ->setRequest($this->_request) - ->setResponse($this->_response); - - /** - * Initialize router - */ - $router = $this->getRouter(); - $router->setParams($this->getParams()); - - /** - * Initialize dispatcher - */ - $dispatcher = $this->getDispatcher(); - $dispatcher->setParams($this->getParams()) - ->setResponse($this->_response); - - // Begin dispatch - try { - /** - * Route request to controller/action, if a router is provided - */ - - /** - * Notify plugins of router startup - */ - $this->_plugins->routeStartup($this->_request); - - try { - $router->route($this->_request); - } catch (Exception $e) { - if ($this->throwExceptions()) { - throw $e; - } - - $this->_response->setException($e); - } - - /** - * Notify plugins of router completion - */ - $this->_plugins->routeShutdown($this->_request); - - /** - * Notify plugins of dispatch loop startup - */ - $this->_plugins->dispatchLoopStartup($this->_request); - - /** - * Attempt to dispatch the controller/action. If the $this->_request - * indicates that it needs to be dispatched, move to the next - * action in the request. - */ - do { - $this->_request->setDispatched(true); - - /** - * Notify plugins of dispatch startup - */ - $this->_plugins->preDispatch($this->_request); - - /** - * Skip requested action if preDispatch() has reset it - */ - if (!$this->_request->isDispatched()) { - continue; - } - - /** - * Dispatch request - */ - try { - $dispatcher->dispatch($this->_request, $this->_response); - } catch (Exception $e) { - if ($this->throwExceptions()) { - throw $e; - } - $this->_response->setException($e); - } - - /** - * Notify plugins of dispatch completion - */ - $this->_plugins->postDispatch($this->_request); - } while (!$this->_request->isDispatched()); - } catch (Exception $e) { - if ($this->throwExceptions()) { - throw $e; - } - - $this->_response->setException($e); - } - - /** - * Notify plugins of dispatch loop completion - */ - try { - $this->_plugins->dispatchLoopShutdown(); - } catch (Exception $e) { - if ($this->throwExceptions()) { - throw $e; - } - - $this->_response->setException($e); - } - - if ($this->returnResponse()) { - return $this->_response; - } - - $this->_response->sendResponse(); - } -} diff --git a/lib/Zend/Controller/Plugin/Abstract.php b/lib/Zend/Controller/Plugin/Abstract.php deleted file mode 100644 index 7e590b7eef0..00000000000 --- a/lib/Zend/Controller/Plugin/Abstract.php +++ /dev/null @@ -1,151 +0,0 @@ -_request = $request; - return $this; - } - - /** - * Get request object - * - * @return Zend_Controller_Request_Abstract $request - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Set response object - * - * @param Zend_Controller_Response_Abstract $response - * @return Zend_Controller_Plugin_Abstract - */ - public function setResponse(Zend_Controller_Response_Abstract $response) - { - $this->_response = $response; - return $this; - } - - /** - * Get response object - * - * @return Zend_Controller_Response_Abstract $response - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Called before Zend_Controller_Front begins evaluating the - * request against its routes. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function routeStartup(Zend_Controller_Request_Abstract $request) - {} - - /** - * Called after Zend_Controller_Router exits. - * - * Called after Zend_Controller_Front exits from the router. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function routeShutdown(Zend_Controller_Request_Abstract $request) - {} - - /** - * Called before Zend_Controller_Front enters its dispatch loop. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) - {} - - /** - * Called before an action is dispatched by Zend_Controller_Dispatcher. - * - * This callback allows for proxy or filter behavior. By altering the - * request and resetting its dispatched flag (via - * {@link Zend_Controller_Request_Abstract::setDispatched() setDispatched(false)}), - * the current action may be skipped. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function preDispatch(Zend_Controller_Request_Abstract $request) - {} - - /** - * Called after an action is dispatched by Zend_Controller_Dispatcher. - * - * This callback allows for proxy or filter behavior. By altering the - * request and resetting its dispatched flag (via - * {@link Zend_Controller_Request_Abstract::setDispatched() setDispatched(false)}), - * a new action may be specified for dispatching. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function postDispatch(Zend_Controller_Request_Abstract $request) - {} - - /** - * Called before Zend_Controller_Front exits its dispatch loop. - * - * @return void - */ - public function dispatchLoopShutdown() - {} -} diff --git a/lib/Zend/Controller/Plugin/ActionStack.php b/lib/Zend/Controller/Plugin/ActionStack.php deleted file mode 100644 index c3d2cb5eea0..00000000000 --- a/lib/Zend/Controller/Plugin/ActionStack.php +++ /dev/null @@ -1,280 +0,0 @@ -setRegistry($registry); - - if (null !== $key) { - $this->setRegistryKey($key); - } else { - $key = $this->getRegistryKey(); - } - - $registry[$key] = array(); - } - - /** - * Set registry object - * - * @param Zend_Registry $registry - * @return Zend_Controller_Plugin_ActionStack - */ - public function setRegistry(Zend_Registry $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * Retrieve registry object - * - * @return Zend_Registry - */ - public function getRegistry() - { - return $this->_registry; - } - - /** - * Retrieve registry key - * - * @return string - */ - public function getRegistryKey() - { - return $this->_registryKey; - } - - /** - * Set registry key - * - * @param string $key - * @return Zend_Controller_Plugin_ActionStack - */ - public function setRegistryKey($key) - { - $this->_registryKey = (string) $key; - return $this; - } - - /** - * Set clearRequestParams flag - * - * @param bool $clearRequestParams - * @return Zend_Controller_Plugin_ActionStack - */ - public function setClearRequestParams($clearRequestParams) - { - $this->_clearRequestParams = (bool) $clearRequestParams; - return $this; - } - - /** - * Retrieve clearRequestParams flag - * - * @return bool - */ - public function getClearRequestParams() - { - return $this->_clearRequestParams; - } - - /** - * Retrieve action stack - * - * @return array - */ - public function getStack() - { - $registry = $this->getRegistry(); - $stack = $registry[$this->getRegistryKey()]; - return $stack; - } - - /** - * Save stack to registry - * - * @param array $stack - * @return Zend_Controller_Plugin_ActionStack - */ - protected function _saveStack(array $stack) - { - $registry = $this->getRegistry(); - $registry[$this->getRegistryKey()] = $stack; - return $this; - } - - /** - * Push an item onto the stack - * - * @param Zend_Controller_Request_Abstract $next - * @return Zend_Controller_Plugin_ActionStack - */ - public function pushStack(Zend_Controller_Request_Abstract $next) - { - $stack = $this->getStack(); - array_push($stack, $next); - return $this->_saveStack($stack); - } - - /** - * Pop an item off the action stack - * - * @return false|Zend_Controller_Request_Abstract - */ - public function popStack() - { - $stack = $this->getStack(); - if (0 == count($stack)) { - return false; - } - - $next = array_pop($stack); - $this->_saveStack($stack); - - if (!$next instanceof Zend_Controller_Request_Abstract) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('ArrayStack should only contain request objects'); - } - $action = $next->getActionName(); - if (empty($action)) { - return $this->popStack($stack); - } - - $request = $this->getRequest(); - $controller = $next->getControllerName(); - if (empty($controller)) { - $next->setControllerName($request->getControllerName()); - } - - $module = $next->getModuleName(); - if (empty($module)) { - $next->setModuleName($request->getModuleName()); - } - - return $next; - } - - /** - * postDispatch() plugin hook -- check for actions in stack, and dispatch if any found - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function postDispatch(Zend_Controller_Request_Abstract $request) - { - // Don't move on to next request if this is already an attempt to - // forward - if (!$request->isDispatched()) { - return; - } - - $this->setRequest($request); - $stack = $this->getStack(); - if (empty($stack)) { - return; - } - $next = $this->popStack(); - if (!$next) { - return; - } - - $this->forward($next); - } - - /** - * Forward request with next action - * - * @param array $next - * @return void - */ - public function forward(Zend_Controller_Request_Abstract $next) - { - $request = $this->getRequest(); - if ($this->getClearRequestParams()) { - $request->clearParams(); - } - - $request->setModuleName($next->getModuleName()) - ->setControllerName($next->getControllerName()) - ->setActionName($next->getActionName()) - ->setParams($next->getParams()) - ->setDispatched(false); - } -} diff --git a/lib/Zend/Controller/Plugin/Broker.php b/lib/Zend/Controller/Plugin/Broker.php deleted file mode 100644 index 3e1c87f3e1c..00000000000 --- a/lib/Zend/Controller/Plugin/Broker.php +++ /dev/null @@ -1,365 +0,0 @@ -_plugins, true)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Plugin already registered'); - } - - $stackIndex = (int) $stackIndex; - - if ($stackIndex) { - if (isset($this->_plugins[$stackIndex])) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Plugin with stackIndex "' . $stackIndex . '" already registered'); - } - $this->_plugins[$stackIndex] = $plugin; - } else { - $stackIndex = count($this->_plugins); - while (isset($this->_plugins[$stackIndex])) { - ++$stackIndex; - } - $this->_plugins[$stackIndex] = $plugin; - } - - $request = $this->getRequest(); - if ($request) { - $this->_plugins[$stackIndex]->setRequest($request); - } - $response = $this->getResponse(); - if ($response) { - $this->_plugins[$stackIndex]->setResponse($response); - } - - ksort($this->_plugins); - - return $this; - } - - /** - * Unregister a plugin. - * - * @param string|Zend_Controller_Plugin_Abstract $plugin Plugin object or class name - * @return Zend_Controller_Plugin_Broker - */ - public function unregisterPlugin($plugin) - { - if ($plugin instanceof Zend_Controller_Plugin_Abstract) { - // Given a plugin object, find it in the array - $key = array_search($plugin, $this->_plugins, true); - if (false === $key) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Plugin never registered.'); - } - unset($this->_plugins[$key]); - } elseif (is_string($plugin)) { - // Given a plugin class, find all plugins of that class and unset them - foreach ($this->_plugins as $key => $_plugin) { - $type = get_class($_plugin); - if ($plugin == $type) { - unset($this->_plugins[$key]); - } - } - } - return $this; - } - - /** - * Is a plugin of a particular class registered? - * - * @param string $class - * @return bool - */ - public function hasPlugin($class) - { - foreach ($this->_plugins as $plugin) { - $type = get_class($plugin); - if ($class == $type) { - return true; - } - } - - return false; - } - - /** - * Retrieve a plugin or plugins by class - * - * @param string $class Class name of plugin(s) desired - * @return false|Zend_Controller_Plugin_Abstract|array Returns false if none found, plugin if only one found, and array of plugins if multiple plugins of same class found - */ - public function getPlugin($class) - { - $found = array(); - foreach ($this->_plugins as $plugin) { - $type = get_class($plugin); - if ($class == $type) { - $found[] = $plugin; - } - } - - switch (count($found)) { - case 0: - return false; - case 1: - return $found[0]; - default: - return $found; - } - } - - /** - * Retrieve all plugins - * - * @return array - */ - public function getPlugins() - { - return $this->_plugins; - } - - /** - * Set request object, and register with each plugin - * - * @param Zend_Controller_Request_Abstract $request - * @return Zend_Controller_Plugin_Broker - */ - public function setRequest(Zend_Controller_Request_Abstract $request) - { - $this->_request = $request; - - foreach ($this->_plugins as $plugin) { - $plugin->setRequest($request); - } - - return $this; - } - - /** - * Get request object - * - * @return Zend_Controller_Request_Abstract $request - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Set response object - * - * @param Zend_Controller_Response_Abstract $response - * @return Zend_Controller_Plugin_Broker - */ - public function setResponse(Zend_Controller_Response_Abstract $response) - { - $this->_response = $response; - - foreach ($this->_plugins as $plugin) { - $plugin->setResponse($response); - } - - - return $this; - } - - /** - * Get response object - * - * @return Zend_Controller_Response_Abstract $response - */ - public function getResponse() - { - return $this->_response; - } - - - /** - * Called before Zend_Controller_Front begins evaluating the - * request against its routes. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function routeStartup(Zend_Controller_Request_Abstract $request) - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->routeStartup($request); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - } - } - } - } - - - /** - * Called before Zend_Controller_Front exits its iterations over - * the route set. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function routeShutdown(Zend_Controller_Request_Abstract $request) - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->routeShutdown($request); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - } - } - } - } - - - /** - * Called before Zend_Controller_Front enters its dispatch loop. - * - * During the dispatch loop, Zend_Controller_Front keeps a - * Zend_Controller_Request_Abstract object, and uses - * Zend_Controller_Dispatcher to dispatch the - * Zend_Controller_Request_Abstract object to controllers/actions. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->dispatchLoopStartup($request); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - } - } - } - } - - - /** - * Called before an action is dispatched by Zend_Controller_Dispatcher. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function preDispatch(Zend_Controller_Request_Abstract $request) - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->preDispatch($request); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - // skip rendering of normal dispatch give the error handler a try - $this->getRequest()->setDispatched(false); - } - } - } - } - - - /** - * Called after an action is dispatched by Zend_Controller_Dispatcher. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function postDispatch(Zend_Controller_Request_Abstract $request) - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->postDispatch($request); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - } - } - } - } - - - /** - * Called before Zend_Controller_Front exits its dispatch loop. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - public function dispatchLoopShutdown() - { - foreach ($this->_plugins as $plugin) { - try { - $plugin->dispatchLoopShutdown(); - } catch (Exception $e) { - if (Zend_Controller_Front::getInstance()->throwExceptions()) { - throw new Zend_Controller_Exception($e->getMessage() . $e->getTraceAsString(), $e->getCode(), $e); - } else { - $this->getResponse()->setException($e); - } - } - } - } -} diff --git a/lib/Zend/Controller/Plugin/ErrorHandler.php b/lib/Zend/Controller/Plugin/ErrorHandler.php deleted file mode 100644 index 41859620913..00000000000 --- a/lib/Zend/Controller/Plugin/ErrorHandler.php +++ /dev/null @@ -1,300 +0,0 @@ -setErrorHandler($options); - } - - /** - * setErrorHandler() - setup the error handling options - * - * @param array $options - * @return Zend_Controller_Plugin_ErrorHandler - */ - public function setErrorHandler(Array $options = array()) - { - if (isset($options['module'])) { - $this->setErrorHandlerModule($options['module']); - } - if (isset($options['controller'])) { - $this->setErrorHandlerController($options['controller']); - } - if (isset($options['action'])) { - $this->setErrorHandlerAction($options['action']); - } - return $this; - } - - /** - * Set the module name for the error handler - * - * @param string $module - * @return Zend_Controller_Plugin_ErrorHandler - */ - public function setErrorHandlerModule($module) - { - $this->_errorModule = (string) $module; - return $this; - } - - /** - * Retrieve the current error handler module - * - * @return string - */ - public function getErrorHandlerModule() - { - if (null === $this->_errorModule) { - $this->_errorModule = Zend_Controller_Front::getInstance()->getDispatcher()->getDefaultModule(); - } - return $this->_errorModule; - } - - /** - * Set the controller name for the error handler - * - * @param string $controller - * @return Zend_Controller_Plugin_ErrorHandler - */ - public function setErrorHandlerController($controller) - { - $this->_errorController = (string) $controller; - return $this; - } - - /** - * Retrieve the current error handler controller - * - * @return string - */ - public function getErrorHandlerController() - { - return $this->_errorController; - } - - /** - * Set the action name for the error handler - * - * @param string $action - * @return Zend_Controller_Plugin_ErrorHandler - */ - public function setErrorHandlerAction($action) - { - $this->_errorAction = (string) $action; - return $this; - } - - /** - * Retrieve the current error handler action - * - * @return string - */ - public function getErrorHandlerAction() - { - return $this->_errorAction; - } - - /** - * Route shutdown hook -- Ccheck for router exceptions - * - * @param Zend_Controller_Request_Abstract $request - */ - public function routeShutdown(Zend_Controller_Request_Abstract $request) - { - $this->_handleError($request); - } - - /** - * Pre dispatch hook -- check for exceptions and dispatch error handler if - * necessary - * - * @param Zend_Controller_Request_Abstract $request - */ - public function preDispatch(Zend_Controller_Request_Abstract $request) - { - $this->_handleError($request); - } - - /** - * Post dispatch hook -- check for exceptions and dispatch error handler if - * necessary - * - * @param Zend_Controller_Request_Abstract $request - */ - public function postDispatch(Zend_Controller_Request_Abstract $request) - { - $this->_handleError($request); - } - - /** - * Handle errors and exceptions - * - * If the 'noErrorHandler' front controller flag has been set, - * returns early. - * - * @param Zend_Controller_Request_Abstract $request - * @return void - */ - protected function _handleError(Zend_Controller_Request_Abstract $request) - { - $frontController = Zend_Controller_Front::getInstance(); - if ($frontController->getParam('noErrorHandler')) { - return; - } - - $response = $this->getResponse(); - - if ($this->_isInsideErrorHandlerLoop) { - $exceptions = $response->getException(); - if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) { - // Exception thrown by error handler; tell the front controller to throw it - $frontController->throwExceptions(true); - throw array_pop($exceptions); - } - } - - // check for an exception AND allow the error handler controller the option to forward - if (($response->isException()) && (!$this->_isInsideErrorHandlerLoop)) { - $this->_isInsideErrorHandlerLoop = true; - - // Get exception information - $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); - $exceptions = $response->getException(); - $exception = $exceptions[0]; - $exceptionType = get_class($exception); - $error->exception = $exception; - switch ($exceptionType) { - case 'Zend_Controller_Router_Exception': - if (404 == $exception->getCode()) { - $error->type = self::EXCEPTION_NO_ROUTE; - } else { - $error->type = self::EXCEPTION_OTHER; - } - break; - case 'Zend_Controller_Dispatcher_Exception': - $error->type = self::EXCEPTION_NO_CONTROLLER; - break; - case 'Zend_Controller_Action_Exception': - if (404 == $exception->getCode()) { - $error->type = self::EXCEPTION_NO_ACTION; - } else { - $error->type = self::EXCEPTION_OTHER; - } - break; - default: - $error->type = self::EXCEPTION_OTHER; - break; - } - - // Keep a copy of the original request - $error->request = clone $request; - - // get a count of the number of exceptions encountered - $this->_exceptionCountAtFirstEncounter = count($exceptions); - - // Forward to the error handler - $request->setParam('error_handler', $error) - ->setModuleName($this->getErrorHandlerModule()) - ->setControllerName($this->getErrorHandlerController()) - ->setActionName($this->getErrorHandlerAction()) - ->setDispatched(false); - } - } -} diff --git a/lib/Zend/Controller/Plugin/PutHandler.php b/lib/Zend/Controller/Plugin/PutHandler.php deleted file mode 100644 index c1ba0358801..00000000000 --- a/lib/Zend/Controller/Plugin/PutHandler.php +++ /dev/null @@ -1,60 +0,0 @@ -_request->isPut()) { - $putParams = array(); - parse_str($this->_request->getRawBody(), $putParams); - $request->setParams($putParams); - } - } -} diff --git a/lib/Zend/Controller/Request/Abstract.php b/lib/Zend/Controller/Request/Abstract.php deleted file mode 100644 index d57238f46be..00000000000 --- a/lib/Zend/Controller/Request/Abstract.php +++ /dev/null @@ -1,356 +0,0 @@ -_module) { - $this->_module = $this->getParam($this->getModuleKey()); - } - - return $this->_module; - } - - /** - * Set the module name to use - * - * @param string $value - * @return Zend_Controller_Request_Abstract - */ - public function setModuleName($value) - { - $this->_module = $value; - return $this; - } - - /** - * Retrieve the controller name - * - * @return string - */ - public function getControllerName() - { - if (null === $this->_controller) { - $this->_controller = $this->getParam($this->getControllerKey()); - } - - return $this->_controller; - } - - /** - * Set the controller name to use - * - * @param string $value - * @return Zend_Controller_Request_Abstract - */ - public function setControllerName($value) - { - $this->_controller = $value; - return $this; - } - - /** - * Retrieve the action name - * - * @return string - */ - public function getActionName() - { - if (null === $this->_action) { - $this->_action = $this->getParam($this->getActionKey()); - } - - return $this->_action; - } - - /** - * Set the action name - * - * @param string $value - * @return Zend_Controller_Request_Abstract - */ - public function setActionName($value) - { - $this->_action = $value; - /** - * @see ZF-3465 - */ - if (null === $value) { - $this->setParam($this->getActionKey(), $value); - } - return $this; - } - - /** - * Retrieve the module key - * - * @return string - */ - public function getModuleKey() - { - return $this->_moduleKey; - } - - /** - * Set the module key - * - * @param string $key - * @return Zend_Controller_Request_Abstract - */ - public function setModuleKey($key) - { - $this->_moduleKey = (string) $key; - return $this; - } - - /** - * Retrieve the controller key - * - * @return string - */ - public function getControllerKey() - { - return $this->_controllerKey; - } - - /** - * Set the controller key - * - * @param string $key - * @return Zend_Controller_Request_Abstract - */ - public function setControllerKey($key) - { - $this->_controllerKey = (string) $key; - return $this; - } - - /** - * Retrieve the action key - * - * @return string - */ - public function getActionKey() - { - return $this->_actionKey; - } - - /** - * Set the action key - * - * @param string $key - * @return Zend_Controller_Request_Abstract - */ - public function setActionKey($key) - { - $this->_actionKey = (string) $key; - return $this; - } - - /** - * Get an action parameter - * - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed - */ - public function getParam($key, $default = null) - { - $key = (string) $key; - if (isset($this->_params[$key])) { - return $this->_params[$key]; - } - - return $default; - } - - /** - * Retrieve only user params (i.e, any param specific to the object and not the environment) - * - * @return array - */ - public function getUserParams() - { - return $this->_params; - } - - /** - * Retrieve a single user param (i.e, a param specific to the object and not the environment) - * - * @param string $key - * @param string $default Default value to use if key not found - * @return mixed - */ - public function getUserParam($key, $default = null) - { - if (isset($this->_params[$key])) { - return $this->_params[$key]; - } - - return $default; - } - - /** - * Set an action parameter - * - * A $value of null will unset the $key if it exists - * - * @param string $key - * @param mixed $value - * @return Zend_Controller_Request_Abstract - */ - public function setParam($key, $value) - { - $key = (string) $key; - - if ((null === $value) && isset($this->_params[$key])) { - unset($this->_params[$key]); - } elseif (null !== $value) { - $this->_params[$key] = $value; - } - - return $this; - } - - /** - * Get all action parameters - * - * @return array - */ - public function getParams() - { - return $this->_params; - } - - /** - * Set action parameters en masse; does not overwrite - * - * Null values will unset the associated key. - * - * @param array $array - * @return Zend_Controller_Request_Abstract - */ - public function setParams(array $array) - { - $this->_params = $this->_params + (array) $array; - - foreach ($array as $key => $value) { - if (null === $value) { - unset($this->_params[$key]); - } - } - - return $this; - } - - /** - * Unset all user parameters - * - * @return Zend_Controller_Request_Abstract - */ - public function clearParams() - { - $this->_params = array(); - return $this; - } - - /** - * Set flag indicating whether or not request has been dispatched - * - * @param boolean $flag - * @return Zend_Controller_Request_Abstract - */ - public function setDispatched($flag = true) - { - $this->_dispatched = $flag ? true : false; - return $this; - } - - /** - * Determine if the request has been dispatched - * - * @return boolean - */ - public function isDispatched() - { - return $this->_dispatched; - } -} diff --git a/lib/Zend/Controller/Request/Apache404.php b/lib/Zend/Controller/Request/Apache404.php deleted file mode 100644 index 22a6527201d..00000000000 --- a/lib/Zend/Controller/Request/Apache404.php +++ /dev/null @@ -1,82 +0,0 @@ -_requestUri = $requestUri; - return $this; - } -} diff --git a/lib/Zend/Controller/Request/Exception.php b/lib/Zend/Controller/Request/Exception.php deleted file mode 100644 index 9e4e17ce7d2..00000000000 --- a/lib/Zend/Controller/Request/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -valid()) { - $path = $uri->getPath(); - $query = $uri->getQuery(); - if (!empty($query)) { - $path .= '?' . $query; - } - - $this->setRequestUri($path); - } else { - #require_once 'Zend/Controller/Request/Exception.php'; - throw new Zend_Controller_Request_Exception('Invalid URI provided to constructor'); - } - } else { - $this->setRequestUri(); - } - } - - /** - * Access values contained in the superglobals as public members - * Order of precedence: 1. GET, 2. POST, 3. COOKIE, 4. SERVER, 5. ENV - * - * @see http://msdn.microsoft.com/en-us/library/system.web.httprequest.item.aspx - * @param string $key - * @return mixed - */ - public function __get($key) - { - switch (true) { - case isset($this->_params[$key]): - return $this->_params[$key]; - case isset($_GET[$key]): - return $_GET[$key]; - case isset($_POST[$key]): - return $_POST[$key]; - case isset($_COOKIE[$key]): - return $_COOKIE[$key]; - case ($key == 'REQUEST_URI'): - return $this->getRequestUri(); - case ($key == 'PATH_INFO'): - return $this->getPathInfo(); - case isset($_SERVER[$key]): - return $_SERVER[$key]; - case isset($_ENV[$key]): - return $_ENV[$key]; - default: - return null; - } - } - - /** - * Alias to __get - * - * @param string $key - * @return mixed - */ - public function get($key) - { - return $this->__get($key); - } - - /** - * Set values - * - * In order to follow {@link __get()}, which operates on a number of - * superglobals, setting values through overloading is not allowed and will - * raise an exception. Use setParam() instead. - * - * @param string $key - * @param mixed $value - * @return void - * @throws Zend_Controller_Request_Exception - */ - public function __set($key, $value) - { - #require_once 'Zend/Controller/Request/Exception.php'; - throw new Zend_Controller_Request_Exception('Setting values in superglobals not allowed; please use setParam()'); - } - - /** - * Alias to __set() - * - * @param string $key - * @param mixed $value - * @return void - */ - public function set($key, $value) - { - return $this->__set($key, $value); - } - - /** - * Check to see if a property is set - * - * @param string $key - * @return boolean - */ - public function __isset($key) - { - switch (true) { - case isset($this->_params[$key]): - return true; - case isset($_GET[$key]): - return true; - case isset($_POST[$key]): - return true; - case isset($_COOKIE[$key]): - return true; - case isset($_SERVER[$key]): - return true; - case isset($_ENV[$key]): - return true; - default: - return false; - } - } - - /** - * Alias to __isset() - * - * @param string $key - * @return boolean - */ - public function has($key) - { - return $this->__isset($key); - } - - /** - * Set GET values - * - * @param string|array $spec - * @param null|mixed $value - * @return Zend_Controller_Request_Http - */ - public function setQuery($spec, $value = null) - { - if ((null === $value) && !is_array($spec)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid value passed to setQuery(); must be either array of values or key/value pair'); - } - if ((null === $value) && is_array($spec)) { - foreach ($spec as $key => $value) { - $this->setQuery($key, $value); - } - return $this; - } - $_GET[(string) $spec] = $value; - return $this; - } - - /** - * Retrieve a member of the $_GET superglobal - * - * If no $key is passed, returns the entire $_GET array. - * - * @todo How to retrieve from nested arrays - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed Returns null if key does not exist - */ - public function getQuery($key = null, $default = null) - { - if (null === $key) { - return $_GET; - } - - return (isset($_GET[$key])) ? $_GET[$key] : $default; - } - - /** - * Set POST values - * - * @param string|array $spec - * @param null|mixed $value - * @return Zend_Controller_Request_Http - */ - public function setPost($spec, $value = null) - { - if ((null === $value) && !is_array($spec)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid value passed to setPost(); must be either array of values or key/value pair'); - } - if ((null === $value) && is_array($spec)) { - foreach ($spec as $key => $value) { - $this->setPost($key, $value); - } - return $this; - } - $_POST[(string) $spec] = $value; - return $this; - } - - /** - * Retrieve a member of the $_POST superglobal - * - * If no $key is passed, returns the entire $_POST array. - * - * @todo How to retrieve from nested arrays - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed Returns null if key does not exist - */ - public function getPost($key = null, $default = null) - { - if (null === $key) { - return $_POST; - } - - return (isset($_POST[$key])) ? $_POST[$key] : $default; - } - - /** - * Retrieve a member of the $_COOKIE superglobal - * - * If no $key is passed, returns the entire $_COOKIE array. - * - * @todo How to retrieve from nested arrays - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed Returns null if key does not exist - */ - public function getCookie($key = null, $default = null) - { - if (null === $key) { - return $_COOKIE; - } - - return (isset($_COOKIE[$key])) ? $_COOKIE[$key] : $default; - } - - /** - * Retrieve a member of the $_SERVER superglobal - * - * If no $key is passed, returns the entire $_SERVER array. - * - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed Returns null if key does not exist - */ - public function getServer($key = null, $default = null) - { - if (null === $key) { - return $_SERVER; - } - - return (isset($_SERVER[$key])) ? $_SERVER[$key] : $default; - } - - /** - * Retrieve a member of the $_ENV superglobal - * - * If no $key is passed, returns the entire $_ENV array. - * - * @param string $key - * @param mixed $default Default value to use if key not found - * @return mixed Returns null if key does not exist - */ - public function getEnv($key = null, $default = null) - { - if (null === $key) { - return $_ENV; - } - - return (isset($_ENV[$key])) ? $_ENV[$key] : $default; - } - - /** - * Set the REQUEST_URI on which the instance operates - * - * If no request URI is passed, uses the value in $_SERVER['REQUEST_URI'], - * $_SERVER['HTTP_X_REWRITE_URL'], or $_SERVER['ORIG_PATH_INFO'] + $_SERVER['QUERY_STRING']. - * - * @param string $requestUri - * @return Zend_Controller_Request_Http - */ - public function setRequestUri($requestUri = null) - { - if ($requestUri === null) { - if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { - // IIS with Microsoft Rewrite Module - $requestUri = $_SERVER['HTTP_X_ORIGINAL_URL']; - } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { - // IIS with ISAPI_Rewrite - $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; - } elseif ( - // IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem) - isset($_SERVER['IIS_WasUrlRewritten']) - && $_SERVER['IIS_WasUrlRewritten'] == '1' - && isset($_SERVER['UNENCODED_URL']) - && $_SERVER['UNENCODED_URL'] != '' - ) { - $requestUri = $_SERVER['UNENCODED_URL']; - } elseif (isset($_SERVER['REQUEST_URI'])) { - $requestUri = $_SERVER['REQUEST_URI']; - // Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path - $schemeAndHttpHost = $this->getScheme() . '://' . $this->getHttpHost(); - if (strpos($requestUri, $schemeAndHttpHost) === 0) { - $requestUri = substr($requestUri, strlen($schemeAndHttpHost)); - } - } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI - $requestUri = $_SERVER['ORIG_PATH_INFO']; - if (!empty($_SERVER['QUERY_STRING'])) { - $requestUri .= '?' . $_SERVER['QUERY_STRING']; - } - } else { - return $this; - } - } elseif (!is_string($requestUri)) { - return $this; - } else { - // Set GET items, if available - if (false !== ($pos = strpos($requestUri, '?'))) { - // Get key => value pairs and set $_GET - $query = substr($requestUri, $pos + 1); - parse_str($query, $vars); - $this->setQuery($vars); - } - } - - $this->_requestUri = $requestUri; - return $this; - } - - /** - * Returns the REQUEST_URI taking into account - * platform differences between Apache and IIS - * - * @return string - */ - public function getRequestUri() - { - if (empty($this->_requestUri)) { - $this->setRequestUri(); - } - - return $this->_requestUri; - } - - /** - * Set the base URL of the request; i.e., the segment leading to the script name - * - * E.g.: - * - /admin - * - /myapp - * - /subdir/index.php - * - * Do not use the full URI when providing the base. The following are - * examples of what not to use: - * - http://example.com/admin (should be just /admin) - * - http://example.com/subdir/index.php (should be just /subdir/index.php) - * - * If no $baseUrl is provided, attempts to determine the base URL from the - * environment, using SCRIPT_FILENAME, SCRIPT_NAME, PHP_SELF, and - * ORIG_SCRIPT_NAME in its determination. - * - * @param mixed $baseUrl - * @return Zend_Controller_Request_Http - */ - public function setBaseUrl($baseUrl = null) - { - if ((null !== $baseUrl) && !is_string($baseUrl)) { - return $this; - } - - if ($baseUrl === null) { - $filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : ''; - - if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename) { - $baseUrl = $_SERVER['SCRIPT_NAME']; - } elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) { - $baseUrl = $_SERVER['PHP_SELF']; - } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) { - $baseUrl = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 shared hosting compatibility - } else { - // Backtrack up the script_filename to find the portion matching - // php_self - $path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : ''; - $file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : ''; - $segs = explode('/', trim($file, '/')); - $segs = array_reverse($segs); - $index = 0; - $last = count($segs); - $baseUrl = ''; - do { - $seg = $segs[$index]; - $baseUrl = '/' . $seg . $baseUrl; - ++$index; - } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos)); - } - - // Does the baseUrl have anything in common with the request_uri? - $requestUri = $this->getRequestUri(); - - if (0 === strpos($requestUri, $baseUrl)) { - // full $baseUrl matches - $this->_baseUrl = $baseUrl; - return $this; - } - - if (0 === strpos($requestUri, dirname($baseUrl))) { - // directory portion of $baseUrl matches - $this->_baseUrl = rtrim(dirname($baseUrl), '/'); - return $this; - } - - $truncatedRequestUri = $requestUri; - if (($pos = strpos($requestUri, '?')) !== false) { - $truncatedRequestUri = substr($requestUri, 0, $pos); - } - - $basename = basename($baseUrl); - if (empty($basename) || !strpos($truncatedRequestUri, $basename)) { - // no match whatsoever; set it blank - $this->_baseUrl = ''; - return $this; - } - - // If using mod_rewrite or ISAPI_Rewrite strip the script filename - // out of baseUrl. $pos !== 0 makes sure it is not matching a value - // from PATH_INFO or QUERY_STRING - if ((strlen($requestUri) >= strlen($baseUrl)) - && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) - { - $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); - } - } - - $this->_baseUrl = rtrim($baseUrl, '/'); - return $this; - } - - /** - * Everything in REQUEST_URI before PATH_INFO - *
- * - * @return string - */ - public function getBaseUrl($raw = false) - { - if (null === $this->_baseUrl) { - $this->setBaseUrl(); - } - - return (($raw == false) ? urldecode($this->_baseUrl) : $this->_baseUrl); - } - - /** - * Set the base path for the URL - * - * @param string|null $basePath - * @return Zend_Controller_Request_Http - */ - public function setBasePath($basePath = null) - { - if ($basePath === null) { - $filename = (isset($_SERVER['SCRIPT_FILENAME'])) - ? basename($_SERVER['SCRIPT_FILENAME']) - : ''; - - $baseUrl = $this->getBaseUrl(); - if (empty($baseUrl)) { - $this->_basePath = ''; - return $this; - } - - if (basename($baseUrl) === $filename) { - $basePath = dirname($baseUrl); - } else { - $basePath = $baseUrl; - } - } - - if (substr(PHP_OS, 0, 3) === 'WIN') { - $basePath = str_replace('\\', '/', $basePath); - } - - $this->_basePath = rtrim($basePath, '/'); - return $this; - } - - /** - * Everything in REQUEST_URI before PATH_INFO not including the filename - * - * - * @return string - */ - public function getBasePath() - { - if (null === $this->_basePath) { - $this->setBasePath(); - } - - return $this->_basePath; - } - - /** - * Set the PATH_INFO string - * - * @param string|null $pathInfo - * @return Zend_Controller_Request_Http - */ - public function setPathInfo($pathInfo = null) - { - if ($pathInfo === null) { - $baseUrl = $this->getBaseUrl(); // this actually calls setBaseUrl() & setRequestUri() - $baseUrlRaw = $this->getBaseUrl(false); - $baseUrlEncoded = urlencode($baseUrlRaw); - - if (null === ($requestUri = $this->getRequestUri())) { - return $this; - } - - // Remove the query string from REQUEST_URI - if ($pos = strpos($requestUri, '?')) { - $requestUri = substr($requestUri, 0, $pos); - } - - if (!empty($baseUrl) || !empty($baseUrlRaw)) { - if (strpos($requestUri, $baseUrl) === 0) { - $pathInfo = substr($requestUri, strlen($baseUrl)); - } elseif (strpos($requestUri, $baseUrlRaw) === 0) { - $pathInfo = substr($requestUri, strlen($baseUrlRaw)); - } elseif (strpos($requestUri, $baseUrlEncoded) === 0) { - $pathInfo = substr($requestUri, strlen($baseUrlEncoded)); - } else { - $pathInfo = $requestUri; - } - } else { - $pathInfo = $requestUri; - } - - } - - $this->_pathInfo = (string) $pathInfo; - return $this; - } - - /** - * Returns everything between the BaseUrl and QueryString. - * This value is calculated instead of reading PATH_INFO - * directly from $_SERVER due to cross-platform differences. - * - * @return string - */ - public function getPathInfo() - { - if (empty($this->_pathInfo)) { - $this->setPathInfo(); - } - - return $this->_pathInfo; - } - - /** - * Set allowed parameter sources - * - * Can be empty array, or contain one or more of '_GET' or '_POST'. - * - * @param array $paramSoures - * @return Zend_Controller_Request_Http - */ - public function setParamSources(array $paramSources = array()) - { - $this->_paramSources = $paramSources; - return $this; - } - - /** - * Get list of allowed parameter sources - * - * @return array - */ - public function getParamSources() - { - return $this->_paramSources; - } - - /** - * Set a userland parameter - * - * Uses $key to set a userland parameter. If $key is an alias, the actual - * key will be retrieved and used to set the parameter. - * - * @param mixed $key - * @param mixed $value - * @return Zend_Controller_Request_Http - */ - public function setParam($key, $value) - { - $key = (null !== ($alias = $this->getAlias($key))) ? $alias : $key; - parent::setParam($key, $value); - return $this; - } - - /** - * Retrieve a parameter - * - * Retrieves a parameter from the instance. Priority is in the order of - * userland parameters (see {@link setParam()}), $_GET, $_POST. If a - * parameter matching the $key is not found, null is returned. - * - * If the $key is an alias, the actual key aliased will be used. - * - * @param mixed $key - * @param mixed $default Default value to use if key not found - * @return mixed - */ - public function getParam($key, $default = null) - { - $keyName = (null !== ($alias = $this->getAlias($key))) ? $alias : $key; - - $paramSources = $this->getParamSources(); - if (isset($this->_params[$keyName])) { - return $this->_params[$keyName]; - } elseif (in_array('_GET', $paramSources) && (isset($_GET[$keyName]))) { - return $_GET[$keyName]; - } elseif (in_array('_POST', $paramSources) && (isset($_POST[$keyName]))) { - return $_POST[$keyName]; - } - - return $default; - } - - /** - * Retrieve an array of parameters - * - * Retrieves a merged array of parameters, with precedence of userland - * params (see {@link setParam()}), $_GET, $_POST (i.e., values in the - * userland params will take precedence over all others). - * - * @return array - */ - public function getParams() - { - $return = $this->_params; - $paramSources = $this->getParamSources(); - if (in_array('_GET', $paramSources) - && isset($_GET) - && is_array($_GET) - ) { - $return += $_GET; - } - if (in_array('_POST', $paramSources) - && isset($_POST) - && is_array($_POST) - ) { - $return += $_POST; - } - return $return; - } - - /** - * Set parameters - * - * Set one or more parameters. Parameters are set as userland parameters, - * using the keys specified in the array. - * - * @param array $params - * @return Zend_Controller_Request_Http - */ - public function setParams(array $params) - { - foreach ($params as $key => $value) { - $this->setParam($key, $value); - } - return $this; - } - - /** - * Set a key alias - * - * Set an alias used for key lookups. $name specifies the alias, $target - * specifies the actual key to use. - * - * @param string $name - * @param string $target - * @return Zend_Controller_Request_Http - */ - public function setAlias($name, $target) - { - $this->_aliases[$name] = $target; - return $this; - } - - /** - * Retrieve an alias - * - * Retrieve the actual key represented by the alias $name. - * - * @param string $name - * @return string|null Returns null when no alias exists - */ - public function getAlias($name) - { - if (isset($this->_aliases[$name])) { - return $this->_aliases[$name]; - } - - return null; - } - - /** - * Retrieve the list of all aliases - * - * @return array - */ - public function getAliases() - { - return $this->_aliases; - } - - /** - * Return the method by which the request was made - * - * @return string - */ - public function getMethod() - { - return $this->getServer('REQUEST_METHOD'); - } - - /** - * Was the request made by POST? - * - * @return boolean - */ - public function isPost() - { - if ('POST' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by GET? - * - * @return boolean - */ - public function isGet() - { - if ('GET' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by PUT? - * - * @return boolean - */ - public function isPut() - { - if ('PUT' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by DELETE? - * - * @return boolean - */ - public function isDelete() - { - if ('DELETE' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by HEAD? - * - * @return boolean - */ - public function isHead() - { - if ('HEAD' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by OPTIONS? - * - * @return boolean - */ - public function isOptions() - { - if ('OPTIONS' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Was the request made by PATCH? - * - * @return boolean - */ - public function isPatch() - { - if ('PATCH' == $this->getMethod()) { - return true; - } - - return false; - } - - /** - * Is the request a Javascript XMLHttpRequest? - * - * Should work with Prototype/Script.aculo.us, possibly others. - * - * @return boolean - */ - public function isXmlHttpRequest() - { - return ($this->getHeader('X_REQUESTED_WITH') == 'XMLHttpRequest'); - } - - /** - * Is this a Flash request? - * - * @return boolean - */ - public function isFlashRequest() - { - $header = strtolower($this->getHeader('USER_AGENT')); - return (strstr($header, ' flash')) ? true : false; - } - - /** - * Is https secure request - * - * @return boolean - */ - public function isSecure() - { - return ($this->getScheme() === self::SCHEME_HTTPS); - } - - /** - * Return the raw body of the request, if present - * - * @return string|false Raw body, or false if not present - */ - public function getRawBody() - { - if (null === $this->_rawBody) { - $body = file_get_contents('php://input'); - - if (strlen(trim($body)) > 0) { - $this->_rawBody = $body; - } else { - $this->_rawBody = false; - } - } - return $this->_rawBody; - } - - /** - * Return the value of the given HTTP header. Pass the header name as the - * plain, HTTP-specified header name. Ex.: Ask for 'Accept' to get the - * Accept header, 'Accept-Encoding' to get the Accept-Encoding header. - * - * @param string $header HTTP header name - * @return string|false HTTP header value, or false if not found - * @throws Zend_Controller_Request_Exception - */ - public function getHeader($header) - { - if (empty($header)) { - #require_once 'Zend/Controller/Request/Exception.php'; - throw new Zend_Controller_Request_Exception('An HTTP header name is required'); - } - - // Try to get it from the $_SERVER array first - $temp = strtoupper(str_replace('-', '_', $header)); - if (isset($_SERVER['HTTP_' . $temp])) { - return $_SERVER['HTTP_' . $temp]; - } - - /* - * Try to get it from the $_SERVER array on POST request or CGI environment - * @see https://www.ietf.org/rfc/rfc3875 (4.1.2. and 4.1.3.) - */ - if (isset($_SERVER[$temp]) - && in_array($temp, array('CONTENT_TYPE', 'CONTENT_LENGTH')) - ) { - return $_SERVER[$temp]; - } - - // This seems to be the only way to get the Authorization header on - // Apache - if (function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - if (isset($headers[$header])) { - return $headers[$header]; - } - $header = strtolower($header); - foreach ($headers as $key => $value) { - if (strtolower($key) == $header) { - return $value; - } - } - } - - return false; - } - - /** - * Get the request URI scheme - * - * @return string - */ - public function getScheme() - { - return ($this->getServer('HTTPS') == 'on') ? self::SCHEME_HTTPS : self::SCHEME_HTTP; - } - - /** - * Get the HTTP host. - * - * "Host" ":" host [ ":" port ] ; Section 3.2.2 - * Note the HTTP Host header is not the same as the URI host. - * It includes the port while the URI host doesn't. - * - * @return string - */ - public function getHttpHost() - { - $host = $this->getServer('HTTP_HOST'); - if (!empty($host)) { - return $host; - } - - $scheme = $this->getScheme(); - $name = $this->getServer('SERVER_NAME'); - $port = $this->getServer('SERVER_PORT'); - - if(null === $name) { - return ''; - } - elseif (($scheme == self::SCHEME_HTTP && $port == 80) || ($scheme == self::SCHEME_HTTPS && $port == 443)) { - return $name; - } else { - return $name . ':' . $port; - } - } - - /** - * Get the client's IP addres - * - * @param boolean $checkProxy - * @return string - */ - public function getClientIp($checkProxy = true) - { - if ($checkProxy && $this->getServer('HTTP_CLIENT_IP') != null) { - $ip = $this->getServer('HTTP_CLIENT_IP'); - } else if ($checkProxy && $this->getServer('HTTP_X_FORWARDED_FOR') != null) { - $ip = $this->getServer('HTTP_X_FORWARDED_FOR'); - } else { - $ip = $this->getServer('REMOTE_ADDR'); - } - - return $ip; - } -} diff --git a/lib/Zend/Controller/Request/HttpTestCase.php b/lib/Zend/Controller/Request/HttpTestCase.php deleted file mode 100644 index 33824d0e494..00000000000 --- a/lib/Zend/Controller/Request/HttpTestCase.php +++ /dev/null @@ -1,277 +0,0 @@ -_rawBody = (string) $content; - return $this; - } - - /** - * Get RAW POST body - * - * @return string|null - */ - public function getRawBody() - { - return $this->_rawBody; - } - - /** - * Clear raw POST body - * - * @return Zend_Controller_Request_HttpTestCase - */ - public function clearRawBody() - { - $this->_rawBody = null; - return $this; - } - - /** - * Set a cookie - * - * @param string $key - * @param mixed $value - * @return Zend_Controller_Request_HttpTestCase - */ - public function setCookie($key, $value) - { - $_COOKIE[(string) $key] = $value; - return $this; - } - - /** - * Set multiple cookies at once - * - * @param array $cookies - * @return void - */ - public function setCookies(array $cookies) - { - foreach ($cookies as $key => $value) { - $_COOKIE[$key] = $value; - } - return $this; - } - - /** - * Clear all cookies - * - * @return Zend_Controller_Request_HttpTestCase - */ - public function clearCookies() - { - $_COOKIE = array(); - return $this; - } - - /** - * Set request method - * - * @param string $type - * @return Zend_Controller_Request_HttpTestCase - */ - public function setMethod($type) - { - $type = strtoupper(trim((string) $type)); - if (!in_array($type, $this->_validMethodTypes)) { - #require_once 'Zend/Controller/Exception.php'; - throw new Zend_Controller_Exception('Invalid request method specified'); - } - $this->_method = $type; - return $this; - } - - /** - * Get request method - * - * @return string|null - */ - public function getMethod() - { - return $this->_method; - } - - /** - * Set a request header - * - * @param string $key - * @param string $value - * @return Zend_Controller_Request_HttpTestCase - */ - public function setHeader($key, $value) - { - $key = $this->_normalizeHeaderName($key); - $this->_headers[$key] = (string) $value; - return $this; - } - - /** - * Set request headers - * - * @param array $headers - * @return Zend_Controller_Request_HttpTestCase - */ - public function setHeaders(array $headers) - { - foreach ($headers as $key => $value) { - $this->setHeader($key, $value); - } - return $this; - } - - /** - * Get request header - * - * @param string $header - * @param mixed $default - * @return string|null - */ - public function getHeader($header, $default = null) - { - $header = $this->_normalizeHeaderName($header); - if (array_key_exists($header, $this->_headers)) { - return $this->_headers[$header]; - } - return $default; - } - - /** - * Get all request headers - * - * @return array - */ - public function getHeaders() - { - return $this->_headers; - } - - /** - * Clear request headers - * - * @return Zend_Controller_Request_HttpTestCase - */ - public function clearHeaders() - { - $this->_headers = array(); - return $this; - } - - /** - * Get REQUEST_URI - * - * @return null|string - */ - public function getRequestUri() - { - return $this->_requestUri; - } - - /** - * Normalize a header name for setting and retrieval - * - * @param string $name - * @return string - */ - protected function _normalizeHeaderName($name) - { - $name = strtoupper((string) $name); - $name = str_replace('-', '_', $name); - return $name; - } -} diff --git a/lib/Zend/Controller/Request/Simple.php b/lib/Zend/Controller/Request/Simple.php deleted file mode 100644 index 492db7d56af..00000000000 --- a/lib/Zend/Controller/Request/Simple.php +++ /dev/null @@ -1,55 +0,0 @@ -setActionName($action); - } - - if ($controller) { - $this->setControllerName($controller); - } - - if ($module) { - $this->setModuleName($module); - } - - if ($params) { - $this->setParams($params); - } - } - -} diff --git a/lib/Zend/Controller/Response/Abstract.php b/lib/Zend/Controller/Response/Abstract.php deleted file mode 100644 index dd3127e2ad3..00000000000 --- a/lib/Zend/Controller/Response/Abstract.php +++ /dev/null @@ -1,796 +0,0 @@ -canSendHeaders(true); - $name = $this->_normalizeHeader($name); - $value = (string) $value; - - if ($replace) { - foreach ($this->_headers as $key => $header) { - if ($name == $header['name']) { - unset($this->_headers[$key]); - } - } - } - - $this->_headers[] = array( - 'name' => $name, - 'value' => $value, - 'replace' => $replace - ); - - return $this; - } - - /** - * Set redirect URL - * - * Sets Location header and response code. Forces replacement of any prior - * redirects. - * - * @param string $url - * @param int $code - * @return Zend_Controller_Response_Abstract - */ - public function setRedirect($url, $code = 302) - { - $this->canSendHeaders(true); - $this->setHeader('Location', $url, true) - ->setHttpResponseCode($code); - - return $this; - } - - /** - * Is this a redirect? - * - * @return boolean - */ - public function isRedirect() - { - return $this->_isRedirect; - } - - /** - * Return array of headers; see {@link $_headers} for format - * - * @return array - */ - public function getHeaders() - { - return $this->_headers; - } - - /** - * Clear headers - * - * @return Zend_Controller_Response_Abstract - */ - public function clearHeaders() - { - $this->_headers = array(); - - return $this; - } - - /** - * Clears the specified HTTP header - * - * @param string $name - * @return Zend_Controller_Response_Abstract - */ - public function clearHeader($name) - { - if (! count($this->_headers)) { - return $this; - } - - foreach ($this->_headers as $index => $header) { - if ($name == $header['name']) { - unset($this->_headers[$index]); - } - } - - return $this; - } - - /** - * Set raw HTTP header - * - * Allows setting non key => value headers, such as status codes - * - * @param string $value - * @return Zend_Controller_Response_Abstract - */ - public function setRawHeader($value) - { - $this->canSendHeaders(true); - if ('Location' == substr($value, 0, 8)) { - $this->_isRedirect = true; - } - $this->_headersRaw[] = (string) $value; - return $this; - } - - /** - * Retrieve all {@link setRawHeader() raw HTTP headers} - * - * @return array - */ - public function getRawHeaders() - { - return $this->_headersRaw; - } - - /** - * Clear all {@link setRawHeader() raw HTTP headers} - * - * @return Zend_Controller_Response_Abstract - */ - public function clearRawHeaders() - { - $this->_headersRaw = array(); - return $this; - } - - /** - * Clears the specified raw HTTP header - * - * @param string $headerRaw - * @return Zend_Controller_Response_Abstract - */ - public function clearRawHeader($headerRaw) - { - if (! count($this->_headersRaw)) { - return $this; - } - - $key = array_search($headerRaw, $this->_headersRaw); - if ($key !== false) { - unset($this->_headersRaw[$key]); - } - - return $this; - } - - /** - * Clear all headers, normal and raw - * - * @return Zend_Controller_Response_Abstract - */ - public function clearAllHeaders() - { - return $this->clearHeaders() - ->clearRawHeaders(); - } - - /** - * Set HTTP response code to use with headers - * - * @param int $code - * @return Zend_Controller_Response_Abstract - */ - public function setHttpResponseCode($code) - { - if (!is_int($code) || (100 > $code) || (599 < $code)) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Invalid HTTP response code'); - } - - if ((300 <= $code) && (307 >= $code)) { - $this->_isRedirect = true; - } else { - $this->_isRedirect = false; - } - - $this->_httpResponseCode = $code; - return $this; - } - - /** - * Retrieve HTTP response code - * - * @return int - */ - public function getHttpResponseCode() - { - return $this->_httpResponseCode; - } - - /** - * Can we send headers? - * - * @param boolean $throw Whether or not to throw an exception if headers have been sent; defaults to false - * @return boolean - * @throws Zend_Controller_Response_Exception - */ - public function canSendHeaders($throw = false) - { - $ok = headers_sent($file, $line); - if ($ok && $throw && $this->headersSentThrowsException) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Cannot send headers; headers already sent in ' . $file . ', line ' . $line); - } - - return !$ok; - } - - /** - * Send all headers - * - * Sends any headers specified. If an {@link setHttpResponseCode() HTTP response code} - * has been specified, it is sent with the first header. - * - * @return Zend_Controller_Response_Abstract - */ - public function sendHeaders() - { - // Only check if we can send headers if we have headers to send - if (count($this->_headersRaw) || count($this->_headers) || (200 != $this->_httpResponseCode)) { - $this->canSendHeaders(true); - } elseif (200 == $this->_httpResponseCode) { - // Haven't changed the response code, and we have no headers - return $this; - } - - $httpCodeSent = false; - - foreach ($this->_headersRaw as $header) { - if (!$httpCodeSent && $this->_httpResponseCode) { - header($header, true, $this->_httpResponseCode); - $httpCodeSent = true; - } else { - header($header); - } - } - - foreach ($this->_headers as $header) { - if (!$httpCodeSent && $this->_httpResponseCode) { - header($header['name'] . ': ' . $header['value'], $header['replace'], $this->_httpResponseCode); - $httpCodeSent = true; - } else { - header($header['name'] . ': ' . $header['value'], $header['replace']); - } - } - - if (!$httpCodeSent) { - header('HTTP/1.1 ' . $this->_httpResponseCode); - $httpCodeSent = true; - } - - return $this; - } - - /** - * Set body content - * - * If $name is not passed, or is not a string, resets the entire body and - * sets the 'default' key to $content. - * - * If $name is a string, sets the named segment in the body array to - * $content. - * - * @param string $content - * @param null|string $name - * @return Zend_Controller_Response_Abstract - */ - public function setBody($content, $name = null) - { - if ((null === $name) || !is_string($name)) { - $this->_body = array('default' => (string) $content); - } else { - $this->_body[$name] = (string) $content; - } - - return $this; - } - - /** - * Append content to the body content - * - * @param string $content - * @param null|string $name - * @return Zend_Controller_Response_Abstract - */ - public function appendBody($content, $name = null) - { - if ((null === $name) || !is_string($name)) { - if (isset($this->_body['default'])) { - $this->_body['default'] .= (string) $content; - } else { - return $this->append('default', $content); - } - } elseif (isset($this->_body[$name])) { - $this->_body[$name] .= (string) $content; - } else { - return $this->append($name, $content); - } - - return $this; - } - - /** - * Clear body array - * - * With no arguments, clears the entire body array. Given a $name, clears - * just that named segment; if no segment matching $name exists, returns - * false to indicate an error. - * - * @param string $name Named segment to clear - * @return boolean - */ - public function clearBody($name = null) - { - if (null !== $name) { - $name = (string) $name; - if (isset($this->_body[$name])) { - unset($this->_body[$name]); - return true; - } - - return false; - } - - $this->_body = array(); - return true; - } - - /** - * Return the body content - * - * If $spec is false, returns the concatenated values of the body content - * array. If $spec is boolean true, returns the body content array. If - * $spec is a string and matches a named segment, returns the contents of - * that segment; otherwise, returns null. - * - * @param boolean $spec - * @return string|array|null - */ - public function getBody($spec = false) - { - if (false === $spec) { - ob_start(); - $this->outputBody(); - return ob_get_clean(); - } elseif (true === $spec) { - return $this->_body; - } elseif (is_string($spec) && isset($this->_body[$spec])) { - return $this->_body[$spec]; - } - - return null; - } - - /** - * Append a named body segment to the body content array - * - * If segment already exists, replaces with $content and places at end of - * array. - * - * @param string $name - * @param string $content - * @return Zend_Controller_Response_Abstract - */ - public function append($name, $content) - { - if (!is_string($name)) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); - } - - if (isset($this->_body[$name])) { - unset($this->_body[$name]); - } - $this->_body[$name] = (string) $content; - return $this; - } - - /** - * Prepend a named body segment to the body content array - * - * If segment already exists, replaces with $content and places at top of - * array. - * - * @param string $name - * @param string $content - * @return void - */ - public function prepend($name, $content) - { - if (!is_string($name)) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); - } - - if (isset($this->_body[$name])) { - unset($this->_body[$name]); - } - - $new = array($name => (string) $content); - $this->_body = $new + $this->_body; - - return $this; - } - - /** - * Insert a named segment into the body content array - * - * @param string $name - * @param string $content - * @param string $parent - * @param boolean $before Whether to insert the new segment before or - * after the parent. Defaults to false (after) - * @return Zend_Controller_Response_Abstract - */ - public function insert($name, $content, $parent = null, $before = false) - { - if (!is_string($name)) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); - } - - if ((null !== $parent) && !is_string($parent)) { - #require_once 'Zend/Controller/Response/Exception.php'; - throw new Zend_Controller_Response_Exception('Invalid body segment parent key ("' . gettype($parent) . '")'); - } - - if (isset($this->_body[$name])) { - unset($this->_body[$name]); - } - - if ((null === $parent) || !isset($this->_body[$parent])) { - return $this->append($name, $content); - } - - $ins = array($name => (string) $content); - $keys = array_keys($this->_body); - $loc = array_search($parent, $keys); - if (!$before) { - // Increment location if not inserting before - ++$loc; - } - - if (0 === $loc) { - // If location of key is 0, we're prepending - $this->_body = $ins + $this->_body; - } elseif ($loc >= (count($this->_body))) { - // If location of key is maximal, we're appending - $this->_body = $this->_body + $ins; - } else { - // Otherwise, insert at location specified - $pre = array_slice($this->_body, 0, $loc); - $post = array_slice($this->_body, $loc); - $this->_body = $pre + $ins + $post; - } - - return $this; - } - - /** - * Echo the body segments - * - * @return void - */ - public function outputBody() - { - $body = implode('', $this->_body); - echo $body; - } - - /** - * Register an exception with the response - * - * @param Exception $e - * @return Zend_Controller_Response_Abstract - */ - public function setException(Exception $e) - { - $this->_exceptions[] = $e; - return $this; - } - - /** - * Retrieve the exception stack - * - * @return array - */ - public function getException() - { - return $this->_exceptions; - } - - /** - * Has an exception been registered with the response? - * - * @return boolean - */ - public function isException() - { - return !empty($this->_exceptions); - } - - /** - * Does the response object contain an exception of a given type? - * - * @param string $type - * @return boolean - */ - public function hasExceptionOfType($type) - { - foreach ($this->_exceptions as $e) { - if ($e instanceof $type) { - return true; - } - } - - return false; - } - - /** - * Does the response object contain an exception with a given message? - * - * @param string $message - * @return boolean - */ - public function hasExceptionOfMessage($message) - { - foreach ($this->_exceptions as $e) { - if ($message == $e->getMessage()) { - return true; - } - } - - return false; - } - - /** - * Does the response object contain an exception with a given code? - * - * @param int $code - * @return boolean - */ - public function hasExceptionOfCode($code) - { - $code = (int) $code; - foreach ($this->_exceptions as $e) { - if ($code == $e->getCode()) { - return true; - } - } - - return false; - } - - /** - * Retrieve all exceptions of a given type - * - * @param string $type - * @return false|array - */ - public function getExceptionByType($type) - { - $exceptions = array(); - foreach ($this->_exceptions as $e) { - if ($e instanceof $type) { - $exceptions[] = $e; - } - } - - if (empty($exceptions)) { - $exceptions = false; - } - - return $exceptions; - } - - /** - * Retrieve all exceptions of a given message - * - * @param string $message - * @return false|array - */ - public function getExceptionByMessage($message) - { - $exceptions = array(); - foreach ($this->_exceptions as $e) { - if ($message == $e->getMessage()) { - $exceptions[] = $e; - } - } - - if (empty($exceptions)) { - $exceptions = false; - } - - return $exceptions; - } - - /** - * Retrieve all exceptions of a given code - * - * @param mixed $code - * @return void - */ - public function getExceptionByCode($code) - { - $code = (int) $code; - $exceptions = array(); - foreach ($this->_exceptions as $e) { - if ($code == $e->getCode()) { - $exceptions[] = $e; - } - } - - if (empty($exceptions)) { - $exceptions = false; - } - - return $exceptions; - } - - /** - * Whether or not to render exceptions (off by default) - * - * If called with no arguments or a null argument, returns the value of the - * flag; otherwise, sets it and returns the current value. - * - * @param boolean $flag Optional - * @return boolean - */ - public function renderExceptions($flag = null) - { - if (null !== $flag) { - $this->_renderExceptions = $flag ? true : false; - } - - return $this->_renderExceptions; - } - - /** - * Send the response, including all headers, rendering exceptions if so - * requested. - * - * @return void - */ - public function sendResponse() - { - $this->sendHeaders(); - - if ($this->isException() && $this->renderExceptions()) { - $exceptions = ''; - foreach ($this->getException() as $e) { - $exceptions .= $e->__toString() . "\n"; - } - echo $exceptions; - return; - } - - $this->outputBody(); - } - - /** - * Magic __toString functionality - * - * Proxies to {@link sendResponse()} and returns response value as string - * using output buffering. - * - * @return string - */ - public function __toString() - { - ob_start(); - $this->sendResponse(); - return ob_get_clean(); - } -} diff --git a/lib/Zend/Controller/Response/Cli.php b/lib/Zend/Controller/Response/Cli.php deleted file mode 100644 index 5d9ce9b239b..00000000000 --- a/lib/Zend/Controller/Response/Cli.php +++ /dev/null @@ -1,68 +0,0 @@ -isException() && $this->renderExceptions()) { - $exceptions = ''; - foreach ($this->getException() as $e) { - $exceptions .= $e->__toString() . "\n"; - } - return $exceptions; - } - - return $this->_body; - } -} diff --git a/lib/Zend/Controller/Response/Exception.php b/lib/Zend/Controller/Response/Exception.php deleted file mode 100644 index 842c0e357ce..00000000000 --- a/lib/Zend/Controller/Response/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -_headersRaw as $header) { - $headers[] = $header; - } - foreach ($this->_headers as $header) { - $name = $header['name']; - $key = strtolower($name); - if (array_key_exists($name, $headers)) { - if ($header['replace']) { - $headers[$key] = $header['name'] . ': ' . $header['value']; - } - } else { - $headers[$key] = $header['name'] . ': ' . $header['value']; - } - } - return $headers; - } - - /** - * Can we send headers? - * - * @param bool $throw - * @return void - */ - public function canSendHeaders($throw = false) - { - return true; - } - - /** - * Return the concatenated body segments - * - * @return string - */ - public function outputBody() - { - $fullContent = ''; - foreach ($this->_body as $content) { - $fullContent .= $content; - } - return $fullContent; - } - - /** - * Get body and/or body segments - * - * @param bool|string $spec - * @return string|array|null - */ - public function getBody($spec = false) - { - if (false === $spec) { - return $this->outputBody(); - } elseif (true === $spec) { - return $this->_body; - } elseif (is_string($spec) && isset($this->_body[$spec])) { - return $this->_body[$spec]; - } - - return null; - } - - /** - * "send" Response - * - * Concats all response headers, and then final body (separated by two - * newlines) - * - * @return string - */ - public function sendResponse() - { - $headers = $this->sendHeaders(); - $content = implode("\n", $headers) . "\n\n"; - - if ($this->isException() && $this->renderExceptions()) { - $exceptions = ''; - foreach ($this->getException() as $e) { - $exceptions .= $e->__toString() . "\n"; - } - $content .= $exceptions; - } else { - $content .= $this->outputBody(); - } - - return $content; - } -} diff --git a/lib/Zend/Controller/Router/Abstract.php b/lib/Zend/Controller/Router/Abstract.php deleted file mode 100644 index bd80babc1f5..00000000000 --- a/lib/Zend/Controller/Router/Abstract.php +++ /dev/null @@ -1,178 +0,0 @@ -setParams($params); - } - - /** - * Add or modify a parameter to use when instantiating an action controller - * - * @param string $name - * @param mixed $value - * @return Zend_Controller_Router_Abstract - */ - public function setParam($name, $value) - { - $name = (string)$name; - $this->_invokeParams[$name] = $value; - - return $this; - } - - /** - * Set parameters to pass to action controller constructors - * - * @param array $params - * @return Zend_Controller_Router_Abstract - */ - public function setParams(array $params) - { - $this->_invokeParams = array_merge($this->_invokeParams, $params); - - return $this; - } - - /** - * Retrieve a single parameter from the controller parameter stack - * - * @param string $name - * @return mixed - */ - public function getParam($name) - { - if (isset($this->_invokeParams[$name])) { - return $this->_invokeParams[$name]; - } - - return null; - } - - /** - * Retrieve action controller instantiation parameters - * - * @return array - */ - public function getParams() - { - return $this->_invokeParams; - } - - /** - * Clear the controller parameter stack - * - * By default, clears all parameters. If a parameter name is given, clears - * only that parameter; if an array of parameter names is provided, clears - * each. - * - * @param null|string|array single key or array of keys for params to clear - * @return Zend_Controller_Router_Abstract - */ - public function clearParams($name = null) - { - if (null === $name) { - $this->_invokeParams = array(); - } elseif (is_string($name) && isset($this->_invokeParams[$name])) { - unset($this->_invokeParams[$name]); - } elseif (is_array($name)) { - foreach ($name as $key) { - if (is_string($key) && isset($this->_invokeParams[$key])) { - unset($this->_invokeParams[$key]); - } - } - } - - return $this; - } - - /** - * Retrieve Front Controller - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - // Used cache version if found - if (null !== $this->_frontController) { - return $this->_frontController; - } - - #require_once 'Zend/Controller/Front.php'; - $this->_frontController = Zend_Controller_Front::getInstance(); - - return $this->_frontController; - } - - /** - * Set Front Controller - * - * @param Zend_Controller_Front $controller - * @return Zend_Controller_Router_Interface - */ - public function setFrontController(Zend_Controller_Front $controller) - { - $this->_frontController = $controller; - - return $this; - } -} diff --git a/lib/Zend/Controller/Router/Exception.php b/lib/Zend/Controller/Router/Exception.php deleted file mode 100644 index 40bfd685586..00000000000 --- a/lib/Zend/Controller/Router/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -hasRoute('default')) { - $dispatcher = $this->getFrontController()->getDispatcher(); - $request = $this->getFrontController()->getRequest(); - - #require_once 'Zend/Controller/Router/Route/Module.php'; - $compat = new Zend_Controller_Router_Route_Module(array(), $dispatcher, $request); - - $this->_routes = array('default' => $compat) + $this->_routes; - } - - return $this; - } - - /** - * Add route to the route chain - * - * If route contains method setRequest(), it is initialized with a request object - * - * @param string $name Name of the route - * @param Zend_Controller_Router_Route_Interface $route Instance of the route - * @return Zend_Controller_Router_Rewrite - */ - public function addRoute($name, Zend_Controller_Router_Route_Interface $route) - { - if (method_exists($route, 'setRequest')) { - $route->setRequest($this->getFrontController()->getRequest()); - } - - $this->_routes[$name] = $route; - - return $this; - } - - /** - * Add routes to the route chain - * - * @param array $routes Array of routes with names as keys and routes as values - * @return Zend_Controller_Router_Rewrite - */ - public function addRoutes($routes) - { - foreach ($routes as $name => $route) { - $this->addRoute($name, $route); - } - - return $this; - } - - /** - * Create routes out of Zend_Config configuration - * - * Example INI: - * routes.archive.route = "archive/:year/*" - * routes.archive.defaults.controller = archive - * routes.archive.defaults.action = show - * routes.archive.defaults.year = 2000 - * routes.archive.reqs.year = "\d+" - * - * routes.news.type = "Zend_Controller_Router_Route_Static" - * routes.news.route = "news" - * routes.news.defaults.controller = "news" - * routes.news.defaults.action = "list" - * - * And finally after you have created a Zend_Config with above ini: - * $router = new Zend_Controller_Router_Rewrite(); - * $router->addConfig($config, 'routes'); - * - * @param Zend_Config $config Configuration object - * @param string $section Name of the config section containing route's definitions - * @throws Zend_Controller_Router_Exception - * @return Zend_Controller_Router_Rewrite - */ - public function addConfig(Zend_Config $config, $section = null) - { - if ($section !== null) { - if ($config->{$section} === null) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("No route configuration in section '{$section}'"); - } - - $config = $config->{$section}; - } - - foreach ($config as $name => $info) { - $route = $this->_getRouteFromConfig($info); - - if ($route instanceof Zend_Controller_Router_Route_Chain) { - if (!isset($info->chain)) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("No chain defined"); - } - - if ($info->chain instanceof Zend_Config) { - $childRouteNames = $info->chain; - } else { - $childRouteNames = explode(',', $info->chain); - } - - foreach ($childRouteNames as $childRouteName) { - $childRoute = $this->getRoute(trim($childRouteName)); - $route->chain($childRoute); - } - - $this->addRoute($name, $route); - } elseif (isset($info->chains) && $info->chains instanceof Zend_Config) { - $this->_addChainRoutesFromConfig($name, $route, $info->chains); - } else { - $this->addRoute($name, $route); - } - } - - return $this; - } - - /** - * Get a route frm a config instance - * - * @param Zend_Config $info - * @return Zend_Controller_Router_Route_Interface - */ - protected function _getRouteFromConfig(Zend_Config $info) - { - $class = (isset($info->type)) ? $info->type : 'Zend_Controller_Router_Route'; - if (!class_exists($class)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($class); - } - - $route = call_user_func( - array( - $class, - 'getInstance' - ), $info - ); - - if (isset($info->abstract) && $info->abstract && method_exists($route, 'isAbstract')) { - $route->isAbstract(true); - } - - return $route; - } - - /** - * Add chain routes from a config route - * - * @param string $name - * @param Zend_Controller_Router_Route_Interface $route - * @param Zend_Config $childRoutesInfo - * @return void - */ - protected function _addChainRoutesFromConfig( - $name, - Zend_Controller_Router_Route_Interface $route, - Zend_Config $childRoutesInfo - ) - { - foreach ($childRoutesInfo as $childRouteName => $childRouteInfo) { - if (is_string($childRouteInfo)) { - $childRouteName = $childRouteInfo; - $childRoute = $this->getRoute($childRouteName); - } else { - $childRoute = $this->_getRouteFromConfig($childRouteInfo); - } - - if ($route instanceof Zend_Controller_Router_Route_Chain) { - $chainRoute = clone $route; - $chainRoute->chain($childRoute); - } else { - $chainRoute = $route->chain($childRoute); - } - - $chainName = $name . $this->_chainNameSeparator . $childRouteName; - - if (isset($childRouteInfo->chains)) { - $this->_addChainRoutesFromConfig($chainName, $chainRoute, $childRouteInfo->chains); - } else { - $this->addRoute($chainName, $chainRoute); - } - } - } - - /** - * Remove a route from the route chain - * - * @param string $name Name of the route - * @throws Zend_Controller_Router_Exception - * @return Zend_Controller_Router_Rewrite - */ - public function removeRoute($name) - { - if (!isset($this->_routes[$name])) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("Route $name is not defined"); - } - - unset($this->_routes[$name]); - - return $this; - } - - /** - * Remove all standard default routes - * - * @return Zend_Controller_Router_Rewrite - */ - public function removeDefaultRoutes() - { - $this->_useDefaultRoutes = false; - - return $this; - } - - /** - * Check if named route exists - * - * @param string $name Name of the route - * @return boolean - */ - public function hasRoute($name) - { - return isset($this->_routes[$name]); - } - - /** - * Retrieve a named route - * - * @param string $name Name of the route - * @throws Zend_Controller_Router_Exception - * @return Zend_Controller_Router_Route_Interface Route object - */ - public function getRoute($name) - { - if (!isset($this->_routes[$name])) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("Route $name is not defined"); - } - - return $this->_routes[$name]; - } - - /** - * Retrieve a currently matched route - * - * @throws Zend_Controller_Router_Exception - * @return Zend_Controller_Router_Route_Interface Route object - */ - public function getCurrentRoute() - { - if (!isset($this->_currentRoute)) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("Current route is not defined"); - } - - return $this->getRoute($this->_currentRoute); - } - - /** - * Retrieve a name of currently matched route - * - * @throws Zend_Controller_Router_Exception - * @return string Route name - */ - public function getCurrentRouteName() - { - if (!isset($this->_currentRoute)) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception("Current route is not defined"); - } - - return $this->_currentRoute; - } - - /** - * Retrieve an array of routes added to the route chain - * - * @return array All of the defined routes - */ - public function getRoutes() - { - return $this->_routes; - } - - /** - * Find a matching route to the current PATH_INFO and inject - * returning values to the Request object. - * - * @param Zend_Controller_Request_Abstract $request - * @throws Zend_Controller_Router_Exception - * @return Zend_Controller_Request_Abstract Request object - */ - public function route(Zend_Controller_Request_Abstract $request) - { - if (!$request instanceof Zend_Controller_Request_Http) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception( - 'Zend_Controller_Router_Rewrite requires a Zend_Controller_Request_Http-based request object' - ); - } - - if ($this->_useDefaultRoutes) { - $this->addDefaultRoutes(); - } - - // Find the matching route - $routeMatched = false; - - foreach (array_reverse($this->_routes, true) as $name => $route) { - // TODO: Should be an interface method. Hack for 1.0 BC - if (method_exists($route, 'isAbstract') && $route->isAbstract()) { - continue; - } - - // TODO: Should be an interface method. Hack for 1.0 BC - if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) { - $match = $request->getPathInfo(); - } else { - $match = $request; - } - - if ($params = $route->match($match)) { - $this->_setRequestParams($request, $params); - $this->_currentRoute = $name; - $routeMatched = true; - break; - } - } - - if (!$routeMatched) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception('No route matched the request', 404); - } - - if ($this->_useCurrentParamsAsGlobal) { - $params = $request->getParams(); - foreach ($params as $param => $value) { - $this->setGlobalParam($param, $value); - } - } - - return $request; - } - - /** - * Sets parameters for request object - * - * Module name, controller name and action name - * - * @param Zend_Controller_Request_Abstract $request - * @param array $params - */ - protected function _setRequestParams($request, $params) - { - foreach ($params as $param => $value) { - - $request->setParam($param, $value); - - if ($param === $request->getModuleKey()) { - $request->setModuleName($value); - } - if ($param === $request->getControllerKey()) { - $request->setControllerName($value); - } - if ($param === $request->getActionKey()) { - $request->setActionName($value); - } - } - } - - /** - * Generates a URL path that can be used in URL creation, redirection, etc. - * - * @param array $userParams Options passed by a user used to override parameters - * @param mixed $name The name of a Route to use - * @param bool $reset Whether to reset to the route defaults ignoring URL params - * @param bool $encode Tells to encode URL parts on output - * @throws Zend_Controller_Router_Exception - * @return string Resulting absolute URL path - */ - public function assemble($userParams, $name = null, $reset = false, $encode = true) - { - if (!is_array($userParams)) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception('userParams must be an array'); - } - - if ($name == null) { - try { - $name = $this->getCurrentRouteName(); - } catch (Zend_Controller_Router_Exception $e) { - $name = 'default'; - } - } - - // Use UNION (+) in order to preserve numeric keys - $params = $userParams + $this->_globalParams; - - $route = $this->getRoute($name); - $url = $route->assemble($params, $reset, $encode); - - if (!preg_match('|^[a-z]+://|', $url)) { - $url = rtrim($this->getFrontController()->getBaseUrl(), self::URI_DELIMITER) . self::URI_DELIMITER . $url; - } - - return $url; - } - - /** - * Set a global parameter - * - * @param string $name - * @param mixed $value - * @return Zend_Controller_Router_Rewrite - */ - public function setGlobalParam($name, $value) - { - $this->_globalParams[$name] = $value; - - return $this; - } - - /** - * Set the separator to use with chain names - * - * @param string $separator The separator to use - * @return Zend_Controller_Router_Rewrite - */ - public function setChainNameSeparator($separator) - { - $this->_chainNameSeparator = $separator; - - return $this; - } - - /** - * Get the separator to use for chain names - * - * @return string - */ - public function getChainNameSeparator() - { - return $this->_chainNameSeparator; - } - - /** - * Determines/returns whether to use the request parameters as global parameters. - * - * @param boolean|null $use - * Null/unset when you want to retrieve the current state. - * True when request parameters should be global, false otherwise - * @return boolean|Zend_Controller_Router_Rewrite - * Returns a boolean if first param isn't set, returns an - * instance of Zend_Controller_Router_Rewrite otherwise. - * - */ - public function useRequestParametersAsGlobal($use = null) - { - if ($use === null) { - return $this->_useCurrentParamsAsGlobal; - } - - $this->_useCurrentParamsAsGlobal = (bool)$use; - - return $this; - } -} diff --git a/lib/Zend/Controller/Router/Route.php b/lib/Zend/Controller/Router/Route.php deleted file mode 100644 index 0d136c49f64..00000000000 --- a/lib/Zend/Controller/Router/Route.php +++ /dev/null @@ -1,605 +0,0 @@ -reqs instanceof Zend_Config) ? $config->reqs->toArray() : array(); - $defs = ($config->defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - - return new self($config->route, $defs, $reqs); - } - - /** - * Prepares the route for mapping by splitting (exploding) it - * to a corresponding atomic parts. These parts are assigned - * a position which is later used for matching and preparing values. - * - * @param string $route Map used to match with later submitted URL path - * @param array $defaults Defaults for map variables with keys as variable names - * @param array $reqs Regular expression requirements for variables (keys as variable names) - * @param Zend_Translate $translator Translator to use for this instance - * @param mixed|null $locale - */ - public function __construct( - $route, $defaults = array(), $reqs = array(), Zend_Translate $translator = null, $locale = null - ) - { - $route = trim($route, $this->_urlDelimiter); - $this->_defaults = (array)$defaults; - $this->_requirements = (array)$reqs; - $this->_translator = $translator; - $this->_locale = $locale; - - if ($route !== '') { - foreach (explode($this->_urlDelimiter, $route) as $pos => $part) { - if (substr($part, 0, 1) == $this->_urlVariable && substr($part, 1, 1) != $this->_urlVariable) { - $name = substr($part, 1); - - if (substr($name, 0, 1) === '@' && substr($name, 1, 1) !== '@') { - $name = substr($name, 1); - $this->_translatable[] = $name; - $this->_isTranslated = true; - } - - $this->_parts[$pos] = (isset($reqs[$name]) ? $reqs[$name] : $this->_defaultRegex); - $this->_variables[$pos] = $name; - } else { - if (substr($part, 0, 1) == $this->_urlVariable) { - $part = substr($part, 1); - } - - if (substr($part, 0, 1) === '@' && substr($part, 1, 1) !== '@') { - $this->_isTranslated = true; - } - - $this->_parts[$pos] = $part; - - if ($part !== '*') { - $this->_staticCount++; - } - } - } - } - } - - /** - * Matches a user submitted path with parts defined by a map. Assigns and - * returns an array of variables on a successful match. - * - * @param string $path Path used to match against this routing map - * @param boolean $partial - * @throws Zend_Controller_Router_Exception - * @return array|false An array of assigned values or a false on a mismatch - */ - public function match($path, $partial = false) - { - if ($this->_isTranslated) { - $translateMessages = $this->getTranslator()->getMessages(); - } - - $pathStaticCount = 0; - $values = array(); - $matchedPath = ''; - - if (!$partial) { - $path = trim($path, $this->_urlDelimiter); - } - - if ($path !== '') { - $path = explode($this->_urlDelimiter, $path); - - foreach ($path as $pos => $pathPart) { - // Path is longer than a route, it's not a match - if (!array_key_exists($pos, $this->_parts)) { - if ($partial) { - break; - } else { - return false; - } - } - - $matchedPath .= $pathPart . $this->_urlDelimiter; - - // If it's a wildcard, get the rest of URL as wildcard data and stop matching - if ($this->_parts[$pos] == '*') { - $count = count($path); - for ($i = $pos; $i < $count; $i += 2) { - $var = urldecode($path[$i]); - if (!isset($this->_wildcardData[$var]) && !isset($this->_defaults[$var]) - && !isset($values[$var]) - ) { - $this->_wildcardData[$var] = (isset($path[$i + 1])) ? urldecode($path[$i + 1]) : null; - } - } - - $matchedPath = implode($this->_urlDelimiter, $path); - break; - } - - $name = isset($this->_variables[$pos]) ? $this->_variables[$pos] : null; - $pathPart = urldecode($pathPart); - - // Translate value if required - $part = $this->_parts[$pos]; - if ($this->_isTranslated - && (substr($part, 0, 1) === '@' && substr($part, 1, 1) !== '@' - && $name === null) - || $name !== null && in_array($name, $this->_translatable) - ) { - if (substr($part, 0, 1) === '@') { - $part = substr($part, 1); - } - - if (($originalPathPart = array_search($pathPart, $translateMessages)) !== false) { - $pathPart = $originalPathPart; - } - } - - if (substr($part, 0, 2) === '@@') { - $part = substr($part, 1); - } - - // If it's a static part, match directly - if ($name === null && $part != $pathPart) { - return false; - } - - // If it's a variable with requirement, match a regex. If not - everything matches - if ($part !== null - && !preg_match( - $this->_regexDelimiter . '^' . $part . '$' . $this->_regexDelimiter . 'iu', $pathPart - ) - ) { - return false; - } - - // If it's a variable store it's value for later - if ($name !== null) { - $values[$name] = $pathPart; - } else { - $pathStaticCount++; - } - } - } - - // Check if all static mappings have been matched - if ($this->_staticCount != $pathStaticCount) { - return false; - } - - $return = $values + $this->_wildcardData + $this->_defaults; - - // Check if all map variables have been initialized - foreach ($this->_variables as $var) { - if (!array_key_exists($var, $return)) { - return false; - } elseif ($return[$var] == '' || $return[$var] === null) { - // Empty variable? Replace with the default value. - $return[$var] = $this->_defaults[$var]; - } - } - - $this->setMatchedPath(rtrim($matchedPath, $this->_urlDelimiter)); - - $this->_values = $values; - - return $return; - } - - /** - * Assembles user submitted parameters forming a URL path defined by this route - * - * @param array $data An array of variable and value pairs used as parameters - * @param boolean $reset Whether or not to set route defaults with those provided in $data - * @param boolean $encode - * @param boolean $partial - * @throws Zend_Controller_Router_Exception - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = false, $partial = false) - { - if ($this->_isTranslated) { - $translator = $this->getTranslator(); - - if (isset($data['@locale'])) { - $locale = $data['@locale']; - unset($data['@locale']); - } else { - $locale = $this->getLocale(); - } - } - - $url = array(); - $flag = false; - - foreach ($this->_parts as $key => $part) { - $name = isset($this->_variables[$key]) ? $this->_variables[$key] : null; - - $useDefault = false; - if (isset($name) && array_key_exists($name, $data) && $data[$name] === null) { - $useDefault = true; - } - - if (isset($name)) { - if (isset($data[$name]) && !$useDefault) { - $value = $data[$name]; - unset($data[$name]); - } elseif (!$reset && !$useDefault && isset($this->_values[$name])) { - $value = $this->_values[$name]; - } elseif (!$reset && !$useDefault && isset($this->_wildcardData[$name])) { - $value = $this->_wildcardData[$name]; - } elseif (array_key_exists($name, $this->_defaults)) { - $value = $this->_defaults[$name]; - } else { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception($name . ' is not specified'); - } - - if ($this->_isTranslated && in_array($name, $this->_translatable)) { - $url[$key] = $translator->translate($value, $locale); - } else { - $url[$key] = $value; - } - } elseif ($part != '*') { - if ($this->_isTranslated && substr($part, 0, 1) === '@') { - if (substr($part, 1, 1) !== '@') { - $url[$key] = $translator->translate(substr($part, 1), $locale); - } else { - $url[$key] = substr($part, 1); - } - } else { - if (substr($part, 0, 2) === '@@') { - $part = substr($part, 1); - } - - $url[$key] = $part; - } - } else { - if (!$reset) { - $data += $this->_wildcardData; - } - $defaults = $this->getDefaults(); - foreach ($data as $var => $value) { - if ($value !== null && (!isset($defaults[$var]) || $value != $defaults[$var])) { - $url[$key++] = $var; - $url[$key++] = $value; - $flag = true; - } - } - } - } - - $return = ''; - - foreach (array_reverse($url, true) as $key => $value) { - $defaultValue = null; - - if (isset($this->_variables[$key])) { - $defaultValue = $this->getDefault($this->_variables[$key]); - - if ($this->_isTranslated && $defaultValue !== null - && isset($this->_translatable[$this->_variables[$key]]) - ) { - $defaultValue = $translator->translate($defaultValue, $locale); - } - } - - if ($flag || $value !== $defaultValue || $partial) { - if ($encode) { - $value = urlencode($value); - } - $return = $this->_urlDelimiter . $value . $return; - $flag = true; - } - } - - return trim($return, $this->_urlDelimiter); - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - if (isset($this->_defaults[$name])) { - return $this->_defaults[$name]; - } - - return null; - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - return $this->_defaults; - } - - /** - * Get all variables which are used by the route - * - * @return array - */ - public function getVariables() - { - return $this->_variables; - } - - /** - * Set a default translator - * - * @param Zend_Translate $translator - * @return void - */ - public static function setDefaultTranslator(Zend_Translate $translator = null) - { - self::$_defaultTranslator = $translator; - } - - /** - * Get the default translator - * - * @return Zend_Translate - */ - public static function getDefaultTranslator() - { - return self::$_defaultTranslator; - } - - /** - * Set a translator - * - * @param Zend_Translate $translator - * @return void - */ - public function setTranslator(Zend_Translate $translator) - { - $this->_translator = $translator; - } - - /** - * Get the translator - * - * @throws Zend_Controller_Router_Exception When no translator can be found - * @return Zend_Translate - */ - public function getTranslator() - { - if ($this->_translator !== null) { - return $this->_translator; - } else { - if (($translator = self::getDefaultTranslator()) !== null) { - return $translator; - } else { - try { - $translator = Zend_Registry::get('Zend_Translate'); - } catch (Zend_Exception $e) { - $translator = null; - } - - if ($translator instanceof Zend_Translate) { - return $translator; - } - } - } - - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception('Could not find a translator'); - } - - /** - * Set a default locale - * - * @param mixed $locale - * @return void - */ - public static function setDefaultLocale($locale = null) - { - self::$_defaultLocale = $locale; - } - - /** - * Get the default locale - * - * @return mixed - */ - public static function getDefaultLocale() - { - return self::$_defaultLocale; - } - - /** - * Set a locale - * - * @param mixed $locale - * @return void - */ - public function setLocale($locale) - { - $this->_locale = $locale; - } - - /** - * Get the locale - * - * @return mixed - */ - public function getLocale() - { - if ($this->_locale !== null) { - return $this->_locale; - } else { - if (($locale = self::getDefaultLocale()) !== null) { - return $locale; - } else { - try { - $locale = Zend_Registry::get('Zend_Locale'); - } catch (Zend_Exception $e) { - $locale = null; - } - - if ($locale !== null) { - return $locale; - } - } - } - - return null; - } -} diff --git a/lib/Zend/Controller/Router/Route/Abstract.php b/lib/Zend/Controller/Router/Route/Abstract.php deleted file mode 100644 index b549c0a1de8..00000000000 --- a/lib/Zend/Controller/Router/Route/Abstract.php +++ /dev/null @@ -1,121 +0,0 @@ -_matchedPath = $path; - } - - /** - * Get partially matched path - * - * @return string - */ - public function getMatchedPath() - { - return $this->_matchedPath; - } - - /** - * Check or set wether this is an abstract route or not - * - * @param boolean $flag - * @return boolean - */ - public function isAbstract($flag = null) - { - if ($flag !== null) { - $this->_isAbstract = $flag; - } - - return $this->_isAbstract; - } - - /** - * Create a new chain - * - * @param Zend_Controller_Router_Route_Abstract $route - * @param string $separator - * @return Zend_Controller_Router_Route_Chain - */ - public function chain(Zend_Controller_Router_Route_Abstract $route, $separator = '/') - { - #require_once 'Zend/Controller/Router/Route/Chain.php'; - - $chain = new Zend_Controller_Router_Route_Chain(); - $chain->chain($this)->chain($route, $separator); - - return $chain; - } -} diff --git a/lib/Zend/Controller/Router/Route/Chain.php b/lib/Zend/Controller/Router/Route/Chain.php deleted file mode 100644 index 19bf9f6065f..00000000000 --- a/lib/Zend/Controller/Router/Route/Chain.php +++ /dev/null @@ -1,229 +0,0 @@ -defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - - return new self($config->route, $defs); - } - - /** - * Add a route to this chain - * - * @param Zend_Controller_Router_Route_Abstract $route - * @param string $separator - * @return Zend_Controller_Router_Route_Chain - */ - public function chain(Zend_Controller_Router_Route_Abstract $route, $separator = self::URI_DELIMITER) - { - $this->_routes[] = $route; - $this->_separators[] = $separator; - - return $this; - } - - /** - * Matches a user submitted path with a previously defined route. - * Assigns and returns an array of defaults on a successful match. - * - * @param Zend_Controller_Request_Http $request Request to get the path info from - * @param null $partial - * @return array|false An array of assigned values or a false on a mismatch - */ - public function match($request, $partial = null) - { - $rawPath = $request->getPathInfo(); - $path = trim($request->getPathInfo(), self::URI_DELIMITER); - $subPath = $path; - $values = array(); - $matchedPath = null; - - foreach ($this->_routes as $key => $route) { - if ($key > 0 - && $matchedPath !== null - && $subPath !== '' - && $subPath !== false - ) { - $separator = substr($subPath, 0, strlen($this->_separators[$key])); - - if ($separator !== $this->_separators[$key]) { - $request->setPathInfo($rawPath); - return false; - } - - $subPath = substr($subPath, strlen($separator)); - } - // TODO: Should be an interface method. Hack for 1.0 BC - if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) { - $match = $subPath; - } else { - $request->setPathInfo($subPath); - $match = $request; - } - - $res = $route->match($match, true); - - if ($res === false) { - $request->setPathInfo($rawPath); - return false; - } - - $matchedPath = $route->getMatchedPath(); - - if ($matchedPath !== null) { - $subPath = substr($subPath, strlen($matchedPath)); - } - - $values = $res + $values; - } - - $request->setPathInfo($path); - - if ($subPath !== '' && $subPath !== false) { - return false; - } - - return $values; - } - - /** - * Assembles a URL path defined by this route - * - * @param array $data An array of variable and value pairs used as parameters - * @param bool $reset - * @param bool $encode - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = false) - { - $value = ''; - $numRoutes = count($this->_routes); - - foreach ($this->_routes as $key => $route) { - if ($key > 0) { - $value .= $this->_separators[$key]; - } - - $value .= $route->assemble($data, $reset, $encode, (($numRoutes - 1) > $key)); - - if (method_exists($route, 'getVariables')) { - $variables = $route->getVariables(); - - foreach ($variables as $variable) { - $data[$variable] = null; - } - } - } - - return $value; - } - - /** - * Set the request object for this and the child routes - * - * @param Zend_Controller_Request_Abstract|null $request - * @return void - */ - public function setRequest(Zend_Controller_Request_Abstract $request = null) - { - $this->_request = $request; - - foreach ($this->_routes as $route) { - if (method_exists($route, 'setRequest')) { - $route->setRequest($request); - } - } - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - $default = null; - foreach ($this->_routes as $route) { - if (method_exists($route, 'getDefault')) { - $current = $route->getDefault($name); - if (null !== $current) { - $default = $current; - } - } - } - - return $default; - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - $defaults = array(); - foreach ($this->_routes as $route) { - if (method_exists($route, 'getDefaults')) { - $defaults = array_merge($defaults, $route->getDefaults()); - } - } - - return $defaults; - } -} diff --git a/lib/Zend/Controller/Router/Route/Hostname.php b/lib/Zend/Controller/Router/Route/Hostname.php deleted file mode 100644 index 214d19f3eb5..00000000000 --- a/lib/Zend/Controller/Router/Route/Hostname.php +++ /dev/null @@ -1,380 +0,0 @@ -_request = $request; - } - - /** - * Get the request object - * - * @return Zend_Controller_Request_Abstract $request - */ - public function getRequest() - { - if ($this->_request === null) { - #require_once 'Zend/Controller/Front.php'; - $this->_request = Zend_Controller_Front::getInstance()->getRequest(); - } - - return $this->_request; - } - - /** - * Instantiates route based on passed Zend_Config structure - * - * @param Zend_Config $config Configuration object - * @return Zend_Controller_Router_Route_Hostname - */ - public static function getInstance(Zend_Config $config) - { - $reqs = ($config->reqs instanceof Zend_Config) ? $config->reqs->toArray() : array(); - $defs = ($config->defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - $scheme = (isset($config->scheme)) ? $config->scheme : null; - - return new self($config->route, $defs, $reqs, $scheme); - } - - /** - * Prepares the route for mapping by splitting (exploding) it - * to a corresponding atomic parts. These parts are assigned - * a position which is later used for matching and preparing values. - * - * @param string $route Map used to match with later submitted hostname - * @param array $defaults Defaults for map variables with keys as variable names - * @param array $reqs Regular expression requirements for variables (keys as variable names) - * @param string $scheme - */ - public function __construct($route, $defaults = array(), $reqs = array(), $scheme = null) - { - $route = trim($route, '.'); - $this->_defaults = (array) $defaults; - $this->_requirements = (array) $reqs; - $this->_scheme = $scheme; - - if ($route != '') { - foreach (explode('.', $route) as $pos => $part) { - if (substr($part, 0, 1) == $this->_hostVariable) { - $name = substr($part, 1); - $this->_parts[$pos] = (isset($reqs[$name]) ? $reqs[$name] : $this->_defaultRegex); - $this->_variables[$pos] = $name; - } else { - $this->_parts[$pos] = $part; - $this->_staticCount++; - } - } - } - } - - /** - * Matches a user submitted path with parts defined by a map. Assigns and - * returns an array of variables on a successful match. - * - * @param Zend_Controller_Request_Http $request Request to get the host from - * @return array|false An array of assigned values or a false on a mismatch - */ - public function match($request) - { - // Check the scheme if required - if ($this->_scheme !== null) { - $scheme = $request->getScheme(); - - if ($scheme !== $this->_scheme) { - return false; - } - } - - // Get the host and remove unnecessary port information - $host = $request->getHttpHost(); - if (preg_match('#:\d+$#', $host, $result) === 1) { - $host = substr($host, 0, -strlen($result[0])); - } - - $hostStaticCount = 0; - $values = array(); - - $host = trim($host, '.'); - - if ($host != '') { - $host = explode('.', $host); - - foreach ($host as $pos => $hostPart) { - // Host is longer than a route, it's not a match - if (!array_key_exists($pos, $this->_parts)) { - return false; - } - - $name = isset($this->_variables[$pos]) ? $this->_variables[$pos] : null; - $hostPart = urldecode($hostPart); - - // If it's a static part, match directly - if ($name === null && $this->_parts[$pos] != $hostPart) { - return false; - } - - // If it's a variable with requirement, match a regex. If not - everything matches - if ($this->_parts[$pos] !== null - && !preg_match( - $this->_regexDelimiter . '^' . $this->_parts[$pos] . '$' . $this->_regexDelimiter . 'iu', - $hostPart - ) - ) { - return false; - } - - // If it's a variable store it's value for later - if ($name !== null) { - $values[$name] = $hostPart; - } else { - $hostStaticCount++; - } - } - } - - // Check if all static mappings have been matched - if ($this->_staticCount != $hostStaticCount) { - return false; - } - - $return = $values + $this->_defaults; - - // Check if all map variables have been initialized - foreach ($this->_variables as $var) { - if (!array_key_exists($var, $return)) { - return false; - } - } - - $this->_values = $values; - - return $return; - } - - /** - * Assembles user submitted parameters forming a hostname defined by this route - * - * @param array $data An array of variable and value pairs used as parameters - * @param boolean $reset Whether or not to set route defaults with those provided in $data - * @param boolean $encode - * @param boolean $partial - * @throws Zend_Controller_Router_Exception - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = false, $partial = false) - { - $host = array(); - $flag = false; - - foreach ($this->_parts as $key => $part) { - $name = isset($this->_variables[$key]) ? $this->_variables[$key] : null; - - $useDefault = false; - if (isset($name) && array_key_exists($name, $data) && $data[$name] === null) { - $useDefault = true; - } - - if (isset($name)) { - if (isset($data[$name]) && !$useDefault) { - $host[$key] = $data[$name]; - unset($data[$name]); - } elseif (!$reset && !$useDefault && isset($this->_values[$name])) { - $host[$key] = $this->_values[$name]; - } elseif (isset($this->_defaults[$name])) { - $host[$key] = $this->_defaults[$name]; - } else { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception($name . ' is not specified'); - } - } else { - $host[$key] = $part; - } - } - - $return = ''; - - foreach (array_reverse($host, true) as $key => $value) { - if ($flag || !isset($this->_variables[$key]) || $value !== $this->getDefault($this->_variables[$key]) - || $partial - ) { - if ($encode) { - $value = urlencode($value); - } - $return = '.' . $value . $return; - $flag = true; - } - } - - $url = trim($return, '.'); - - if ($this->_scheme !== null) { - $scheme = $this->_scheme; - } else { - $request = $this->getRequest(); - if ($request instanceof Zend_Controller_Request_Http) { - $scheme = $request->getScheme(); - } else { - $scheme = 'http'; - } - } - - $url = $scheme . '://' . $url; - - return $url; - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - if (isset($this->_defaults[$name])) { - return $this->_defaults[$name]; - } - - return null; - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - return $this->_defaults; - } - - /** - * Get all variables which are used by the route - * - * @return array - */ - public function getVariables() - { - return $this->_variables; - } -} diff --git a/lib/Zend/Controller/Router/Route/Interface.php b/lib/Zend/Controller/Router/Route/Interface.php deleted file mode 100644 index 12858772ed5..00000000000 --- a/lib/Zend/Controller/Router/Route/Interface.php +++ /dev/null @@ -1,39 +0,0 @@ -defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - $dispatcher = $frontController->getDispatcher(); - $request = $frontController->getRequest(); - - return new self($defs, $dispatcher, $request); - } - - /** - * Constructor - * - * @param array $defaults Defaults for map variables with keys as variable names - * @param Zend_Controller_Dispatcher_Interface $dispatcher Dispatcher object - * @param Zend_Controller_Request_Abstract $request Request object - */ - public function __construct( - array $defaults = array(), - Zend_Controller_Dispatcher_Interface $dispatcher = null, - Zend_Controller_Request_Abstract $request = null - ) - { - $this->_defaults = $defaults; - - if (isset($request)) { - $this->_request = $request; - } - - if (isset($dispatcher)) { - $this->_dispatcher = $dispatcher; - } - } - - /** - * Set request keys based on values in request object - * - * @return void - */ - protected function _setRequestKeys() - { - if (null !== $this->_request) { - $this->_moduleKey = $this->_request->getModuleKey(); - $this->_controllerKey = $this->_request->getControllerKey(); - $this->_actionKey = $this->_request->getActionKey(); - } - - if (null !== $this->_dispatcher) { - $this->_defaults += array( - $this->_controllerKey => $this->_dispatcher->getDefaultControllerName(), - $this->_actionKey => $this->_dispatcher->getDefaultAction(), - $this->_moduleKey => $this->_dispatcher->getDefaultModule() - ); - } - - $this->_keysSet = true; - } - - /** - * Matches a user submitted path. Assigns and returns an array of variables - * on a successful match. - * - * If a request object is registered, it uses its setModuleName(), - * setControllerName(), and setActionName() accessors to set those values. - * Always returns the values as an array. - * - * @param string $path Path used to match against this routing map - * @param boolean $partial - * @return array An array of assigned values or a false on a mismatch - */ - public function match($path, $partial = false) - { - $this->_setRequestKeys(); - - $values = array(); - $params = array(); - - if (!$partial) { - $path = trim($path, self::URI_DELIMITER); - } else { - $matchedPath = $path; - } - - if ($path != '') { - $path = explode(self::URI_DELIMITER, $path); - - if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) { - $values[$this->_moduleKey] = array_shift($path); - $this->_moduleValid = true; - } - - if (count($path) && !empty($path[0])) { - $values[$this->_controllerKey] = array_shift($path); - } - - if (count($path) && !empty($path[0])) { - $values[$this->_actionKey] = array_shift($path); - } - - if ($numSegs = count($path)) { - for ($i = 0; $i < $numSegs; $i = $i + 2) { - $key = urldecode($path[$i]); - $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null; - $params[$key] = (isset($params[$key]) ? (array_merge((array)$params[$key], array($val))) : $val); - } - } - } - - if ($partial) { - $this->setMatchedPath($matchedPath); - } - - $this->_values = $values + $params; - - return $this->_values + $this->_defaults; - } - - /** - * Assembles user submitted parameters forming a URL path defined by this route - * - * @param array $data An array of variable and value pairs used as parameters - * @param boolean $reset Weither to reset the current params - * @param boolean $encode - * @param boolean $partial - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = true, $partial = false) - { - if (!$this->_keysSet) { - $this->_setRequestKeys(); - } - - $params = (!$reset) ? $this->_values : array(); - - foreach ($data as $key => $value) { - if ($value !== null) { - $params[$key] = $value; - } elseif (isset($params[$key])) { - unset($params[$key]); - } - } - - $params += $this->_defaults; - - $url = ''; - - if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) { - if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) { - $module = $params[$this->_moduleKey]; - } - } - unset($params[$this->_moduleKey]); - - $controller = $params[$this->_controllerKey]; - unset($params[$this->_controllerKey]); - - $action = $params[$this->_actionKey]; - unset($params[$this->_actionKey]); - - foreach ($params as $key => $value) { - $key = ($encode) ? urlencode($key) : $key; - if (is_array($value)) { - foreach ($value as $arrayValue) { - $arrayValue = ($encode) ? urlencode($arrayValue) : $arrayValue; - $url .= self::URI_DELIMITER . $key; - $url .= self::URI_DELIMITER . $arrayValue; - } - } else { - if ($encode) { - $value = urlencode($value); - } - $url .= self::URI_DELIMITER . $key; - $url .= self::URI_DELIMITER . $value; - } - } - - if (!empty($url) || $action !== $this->_defaults[$this->_actionKey]) { - if ($encode) { - $action = urlencode($action); - } - $url = self::URI_DELIMITER . $action . $url; - } - - if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) { - if ($encode) { - $controller = urlencode($controller); - } - $url = self::URI_DELIMITER . $controller . $url; - } - - if (isset($module)) { - if ($encode) { - $module = urlencode($module); - } - $url = self::URI_DELIMITER . $module . $url; - } - - return ltrim($url, self::URI_DELIMITER); - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - if (isset($this->_defaults[$name])) { - return $this->_defaults[$name]; - } - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - return $this->_defaults; - } -} diff --git a/lib/Zend/Controller/Router/Route/Regex.php b/lib/Zend/Controller/Router/Route/Regex.php deleted file mode 100644 index e328c7260b3..00000000000 --- a/lib/Zend/Controller/Router/Route/Regex.php +++ /dev/null @@ -1,319 +0,0 @@ -defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - $map = ($config->map instanceof Zend_Config) ? $config->map->toArray() : array(); - $reverse = (isset($config->reverse)) ? $config->reverse : null; - - return new self($config->route, $defs, $map, $reverse); - } - - /** - * Constructor - * - * @param $route - * @param array $defaults - * @param array $map - * @param null $reverse - */ - public function __construct($route, $defaults = array(), $map = array(), $reverse = null) - { - $this->_regex = $route; - $this->_defaults = (array) $defaults; - $this->_map = (array) $map; - $this->_reverse = $reverse; - } - - /** - * Get the version of the route - * - * @return int - */ - public function getVersion() - { - return 1; - } - - /** - * Matches a user submitted path with a previously defined route. - * Assigns and returns an array of defaults on a successful match. - * - * @param string $path Path used to match against this routing map - * @return array|false An array of assigned values or a false on a mismatch - */ - public function match($path, $partial = false) - { - if (!$partial) { - $path = trim(urldecode($path), self::URI_DELIMITER); - $regex = '#^' . $this->_regex . '$#i'; - } else { - $regex = '#^' . $this->_regex . '#i'; - } - - $res = preg_match($regex, $path, $values); - - if ($res === 0) { - return false; - } - - if ($partial) { - $this->setMatchedPath($values[0]); - } - - // array_filter_key()? Why isn't this in a standard PHP function set yet? :) - foreach ($values as $i => $value) { - if (!is_int($i) || $i === 0) { - unset($values[$i]); - } - } - - $this->_values = $values; - - $values = $this->_getMappedValues($values); - $defaults = $this->_getMappedValues($this->_defaults, false, true); - $return = $values + $defaults; - - return $return; - } - - /** - * Maps numerically indexed array values to it's associative mapped counterpart. - * Or vice versa. Uses user provided map array which consists of index => name - * parameter mapping. If map is not found, it returns original array. - * - * Method strips destination type of keys form source array. Ie. if source array is - * indexed numerically then every associative key will be stripped. Vice versa if reversed - * is set to true. - * - * @param array $values Indexed or associative array of values to map - * @param boolean $reversed False means translation of index to association. True means reverse. - * @param boolean $preserve Should wrong type of keys be preserved or stripped. - * @return array An array of mapped values - */ - protected function _getMappedValues($values, $reversed = false, $preserve = false) - { - if (count($this->_map) == 0) { - return $values; - } - - $return = array(); - - foreach ($values as $key => $value) { - if (is_int($key) && !$reversed) { - if (array_key_exists($key, $this->_map)) { - $index = $this->_map[$key]; - } elseif (false === ($index = array_search($key, $this->_map))) { - $index = $key; - } - $return[$index] = $values[$key]; - } elseif ($reversed) { - $index = $key; - if (!is_int($key)) { - if (array_key_exists($key, $this->_map)) { - $index = $this->_map[$key]; - } else { - $index = array_search($key, $this->_map, true); - } - } - if (false !== $index) { - $return[$index] = $values[$key]; - } - } elseif ($preserve) { - $return[$key] = $value; - } - } - - return $return; - } - - /** - * Assembles a URL path defined by this route - * - * @param array $data An array of name (or index) and value pairs used as parameters - * @param boolean $reset - * @param boolean $encode - * @param boolean $partial - * @throws Zend_Controller_Router_Exception - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = false, $partial = false) - { - if ($this->_reverse === null) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception('Cannot assemble. Reversed route is not specified.'); - } - - $defaultValuesMapped = $this->_getMappedValues($this->_defaults, true, false); - $matchedValuesMapped = $this->_getMappedValues($this->_values, true, false); - $dataValuesMapped = $this->_getMappedValues($data, true, false); - - // handle resets, if so requested (By null value) to do so - if (($resetKeys = array_search(null, $dataValuesMapped, true)) !== false) { - foreach ((array)$resetKeys as $resetKey) { - if (isset($matchedValuesMapped[$resetKey])) { - unset($matchedValuesMapped[$resetKey]); - unset($dataValuesMapped[$resetKey]); - } - } - } - - // merge all the data together, first defaults, then values matched, then supplied - $mergedData = $defaultValuesMapped; - $mergedData = $this->_arrayMergeNumericKeys($mergedData, $matchedValuesMapped); - $mergedData = $this->_arrayMergeNumericKeys($mergedData, $dataValuesMapped); - - if ($encode) { - foreach ($mergedData as $key => &$value) { - $value = urlencode($value); - } - } - - ksort($mergedData); - - $return = @vsprintf($this->_reverse, $mergedData); - - if ($return === false) { - #require_once 'Zend/Controller/Router/Exception.php'; - throw new Zend_Controller_Router_Exception('Cannot assemble. Too few arguments?'); - } - - return $return; - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - if (isset($this->_defaults[$name])) { - return $this->_defaults[$name]; - } - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - return $this->_defaults; - } - - /** - * Get all variables which are used by the route - * - * @return array - */ - public function getVariables() - { - $variables = array(); - - foreach ($this->_map as $key => $value) { - if (is_numeric($key)) { - $variables[] = $value; - } else { - $variables[] = $key; - } - } - - return $variables; - } - - /** - * _arrayMergeNumericKeys() - allows for a strict key (numeric's included) array_merge. - * php's array_merge() lacks the ability to merge with numeric keys. - * - * @param array $array1 - * @param array $array2 - * @return array - */ - protected function _arrayMergeNumericKeys(Array $array1, Array $array2) - { - $returnArray = $array1; - foreach ($array2 as $array2Index => $array2Value) { - $returnArray[$array2Index] = $array2Value; - } - - return $returnArray; - } -} diff --git a/lib/Zend/Controller/Router/Route/Static.php b/lib/Zend/Controller/Router/Route/Static.php deleted file mode 100644 index a544cceba31..00000000000 --- a/lib/Zend/Controller/Router/Route/Static.php +++ /dev/null @@ -1,149 +0,0 @@ -defaults instanceof Zend_Config) ? $config->defaults->toArray() : array(); - - return new self($config->route, $defs); - } - - /** - * Prepares the route for mapping. - * - * @param string $route Map used to match with later submitted URL path - * @param array $defaults Defaults for map variables with keys as variable names - */ - public function __construct($route, $defaults = array()) - { - $this->_route = trim($route, self::URI_DELIMITER); - $this->_defaults = (array) $defaults; - } - - /** - * Matches a user submitted path with a previously defined route. - * Assigns and returns an array of defaults on a successful match. - * - * @param string $path Path used to match against this routing map - * @return array|false An array of assigned values or a false on a mismatch - */ - public function match($path, $partial = false) - { - if ($partial) { - if ((empty($path) && empty($this->_route)) - || (substr($path, 0, strlen($this->_route)) === $this->_route) - ) { - $this->setMatchedPath($this->_route); - - return $this->_defaults; - } - } else { - if (trim($path, self::URI_DELIMITER) == $this->_route) { - return $this->_defaults; - } - } - - return false; - } - - /** - * Assembles a URL path defined by this route - * - * @param array $data An array of variable and value pairs used as parameters - * @return string Route path with user submitted parameters - */ - public function assemble($data = array(), $reset = false, $encode = false, $partial = false) - { - return $this->_route; - } - - /** - * Return a single parameter of route's defaults - * - * @param string $name Array key of the parameter - * @return string Previously set default - */ - public function getDefault($name) - { - if (isset($this->_defaults[$name])) { - return $this->_defaults[$name]; - } - - return null; - } - - /** - * Return an array of defaults - * - * @return array Route defaults - */ - public function getDefaults() - { - return $this->_defaults; - } -} diff --git a/lib/Zend/Crypt.php b/lib/Zend/Crypt.php deleted file mode 100644 index 2216ad8d226..00000000000 --- a/lib/Zend/Crypt.php +++ /dev/null @@ -1,168 +0,0 @@ -setPrime($prime); - $this->setGenerator($generator); - if ($privateKey !== null) { - $this->setPrivateKey($privateKey, $privateKeyType); - } - $this->setBigIntegerMath(); - } - - /** - * Generate own public key. If a private number has not already been - * set, one will be generated at this stage. - * - * @return Zend_Crypt_DiffieHellman - */ - public function generateKeys() - { - if (function_exists('openssl_dh_compute_key') && self::$useOpenssl !== false) { - $details = array(); - $details['p'] = $this->getPrime(); - $details['g'] = $this->getGenerator(); - if ($this->hasPrivateKey()) { - $details['priv_key'] = $this->getPrivateKey(); - } - $opensslKeyResource = openssl_pkey_new( array('dh' => $details) ); - $data = openssl_pkey_get_details($opensslKeyResource); - $this->setPrivateKey($data['dh']['priv_key'], self::BINARY); - $this->setPublicKey($data['dh']['pub_key'], self::BINARY); - } else { - // Private key is lazy generated in the absence of PHP 5.3's ext/openssl - $publicKey = $this->_math->powmod($this->getGenerator(), $this->getPrivateKey(), $this->getPrime()); - $this->setPublicKey($publicKey); - } - return $this; - } - - /** - * Setter for the value of the public number - * - * @param string $number - * @param string $type - * @throws Zend_Crypt_DiffieHellman_Exception - * @return Zend_Crypt_DiffieHellman - */ - public function setPublicKey($number, $type = self::NUMBER) - { - if ($type == self::BINARY) { - $number = $this->_math->fromBinary($number); - } - if (!preg_match("/^\d+$/", $number)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number'); - } - $this->_publicKey = (string) $number; - return $this; - } - - /** - * Returns own public key for communication to the second party to this - * transaction. - * - * @param string $type - * @throws Zend_Crypt_DiffieHellman_Exception - * @return string - */ - public function getPublicKey($type = self::NUMBER) - { - if ($this->_publicKey === null) { - #require_once 'Zend/Crypt/DiffieHellman/Exception.php'; - throw new Zend_Crypt_DiffieHellman_Exception('A public key has not yet been generated using a prior call to generateKeys()'); - } - if ($type == self::BINARY) { - return $this->_math->toBinary($this->_publicKey); - } elseif ($type == self::BTWOC) { - return $this->_math->btwoc($this->_math->toBinary($this->_publicKey)); - } - return $this->_publicKey; - } - - /** - * Compute the shared secret key based on the public key received from the - * the second party to this transaction. This should agree to the secret - * key the second party computes on our own public key. - * Once in agreement, the key is known to only to both parties. - * By default, the function expects the public key to be in binary form - * which is the typical format when being transmitted. - * - * If you need the binary form of the shared secret key, call - * getSharedSecretKey() with the optional parameter for Binary output. - * - * @param string $publicKey - * @param string $type - * @param string $output - * @throws Zend_Crypt_DiffieHellman_Exception - * @return mixed - */ - public function computeSecretKey($publicKey, $type = self::NUMBER, $output = self::NUMBER) - { - if ($type == self::BINARY) { - $publicKey = $this->_math->fromBinary($publicKey); - } - if (!preg_match("/^\d+$/", $publicKey)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number'); - } - if (function_exists('openssl_dh_compute_key') && self::$useOpenssl !== false) { - $this->_secretKey = openssl_dh_compute_key($publicKey, $this->getPublicKey()); - } else { - $this->_secretKey = $this->_math->powmod($publicKey, $this->getPrivateKey(), $this->getPrime()); - } - return $this->getSharedSecretKey($output); - } - - /** - * Return the computed shared secret key from the DiffieHellman transaction - * - * @param string $type - * @throws Zend_Crypt_DiffieHellman_Exception - * @return string - */ - public function getSharedSecretKey($type = self::NUMBER) - { - if (!isset($this->_secretKey)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('A secret key has not yet been computed; call computeSecretKey()'); - } - if ($type == self::BINARY) { - return $this->_math->toBinary($this->_secretKey); - } elseif ($type == self::BTWOC) { - return $this->_math->btwoc($this->_math->toBinary($this->_secretKey)); - } - return $this->_secretKey; - } - - /** - * Setter for the value of the prime number - * - * @param string $number - * @throws Zend_Crypt_DiffieHellman_Exception - * @return Zend_Crypt_DiffieHellman - */ - public function setPrime($number) - { - if (!preg_match("/^\d+$/", $number) || $number < 11) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number or too small: should be a large natural number prime'); - } - $this->_prime = (string) $number; - return $this; - } - - /** - * Getter for the value of the prime number - * - * @throws Zend_Crypt_DiffieHellman_Exception - * @return string - */ - public function getPrime() - { - if (!isset($this->_prime)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('No prime number has been set'); - } - return $this->_prime; - } - - /** - * Setter for the value of the generator number - * - * @param string $number - * @throws Zend_Crypt_DiffieHellman_Exception - * @return Zend_Crypt_DiffieHellman - */ - public function setGenerator($number) - { - if (!preg_match("/^\d+$/", $number) || $number < 2) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number greater than 1'); - } - $this->_generator = (string) $number; - return $this; - } - - /** - * Getter for the value of the generator number - * - * @throws Zend_Crypt_DiffieHellman_Exception - * @return string - */ - public function getGenerator() - { - if (!isset($this->_generator)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('No generator number has been set'); - } - return $this->_generator; - } - - /** - * Setter for the value of the private number - * - * @param string $number - * @param string $type - * @throws Zend_Crypt_DiffieHellman_Exception - * @return Zend_Crypt_DiffieHellman - */ - public function setPrivateKey($number, $type = self::NUMBER) - { - if ($type == self::BINARY) { - $number = $this->_math->fromBinary($number); - } - if (!preg_match("/^\d+$/", $number)) { - #require_once('Zend/Crypt/DiffieHellman/Exception.php'); - throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number'); - } - $this->_privateKey = (string) $number; - return $this; - } - - /** - * Getter for the value of the private number - * - * @param string $type - * @return string - */ - public function getPrivateKey($type = self::NUMBER) - { - if (!$this->hasPrivateKey()) { - $this->setPrivateKey($this->_generatePrivateKey(), self::BINARY); - } - if ($type == self::BINARY) { - return $this->_math->toBinary($this->_privateKey); - } elseif ($type == self::BTWOC) { - return $this->_math->btwoc($this->_math->toBinary($this->_privateKey)); - } - return $this->_privateKey; - } - - /** - * Check whether a private key currently exists. - * - * @return boolean - */ - public function hasPrivateKey() - { - return isset($this->_privateKey); - } - - /** - * Setter to pass an extension parameter which is used to create - * a specific BigInteger instance for a specific extension type. - * Allows manual setting of the class in case of an extension - * problem or bug. - * - * @param string $extension - * @return void - */ - public function setBigIntegerMath($extension = null) - { - /** - * @see Zend_Crypt_Math - */ - #require_once 'Zend/Crypt/Math.php'; - $this->_math = new Zend_Crypt_Math($extension); - } - - /** - * In the event a private number/key has not been set by the user, - * or generated by ext/openssl, a best attempt will be made to - * generate a random key. Having a random number generator installed - * on linux/bsd is highly recommended! The alternative is not recommended - * for production unless without any other option. - * - * @return string - */ - protected function _generatePrivateKey() - { - $rand = $this->_math->rand($this->getGenerator(), $this->getPrime()); - return $rand; - } - -} diff --git a/lib/Zend/Crypt/DiffieHellman/Exception.php b/lib/Zend/Crypt/DiffieHellman/Exception.php deleted file mode 100644 index 1a3a54cff61..00000000000 --- a/lib/Zend/Crypt/DiffieHellman/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -80 using internal algo) - * @todo Check if mhash() is a required alternative (will be PECL-only soon) - * @category Zend - * @package Zend_Crypt - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Crypt_Hmac extends Zend_Crypt -{ - - /** - * The key to use for the hash - * - * @var string - */ - protected static $_key = null; - - /** - * pack() format to be used for current hashing method - * - * @var string - */ - protected static $_packFormat = null; - - /** - * Hashing algorithm; can be the md5/sha1 functions or any algorithm name - * listed in the output of PHP 5.1.2+ hash_algos(). - * - * @var string - */ - protected static $_hashAlgorithm = 'md5'; - - /** - * List of algorithms supported my mhash() - * - * @var array - */ - protected static $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost', - 'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160', - 'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160'); - - /** - * Constants representing the output mode of the hash algorithm - */ - const STRING = 'string'; - const BINARY = 'binary'; - - /** - * Performs a HMAC computation given relevant details such as Key, Hashing - * algorithm, the data to compute MAC of, and an output format of String, - * Binary notation or BTWOC. - * - * @param string $key - * @param string $hash - * @param string $data - * @param string $output - * @throws Zend_Crypt_Hmac_Exception - * @return string - */ - public static function compute($key, $hash, $data, $output = self::STRING) - { - // set the key - if (!isset($key) || empty($key)) { - #require_once 'Zend/Crypt/Hmac/Exception.php'; - throw new Zend_Crypt_Hmac_Exception('provided key is null or empty'); - } - self::$_key = $key; - - // set the hash - self::_setHashAlgorithm($hash); - - // perform hashing and return - return self::_hash($data, $output); - } - - /** - * Setter for the hash method. - * - * @param string $hash - * @throws Zend_Crypt_Hmac_Exception - * @return Zend_Crypt_Hmac - */ - protected static function _setHashAlgorithm($hash) - { - if (!isset($hash) || empty($hash)) { - #require_once 'Zend/Crypt/Hmac/Exception.php'; - throw new Zend_Crypt_Hmac_Exception('provided hash string is null or empty'); - } - - $hash = strtolower($hash); - $hashSupported = false; - - if (function_exists('hash_algos') && in_array($hash, hash_algos())) { - $hashSupported = true; - } - - if ($hashSupported === false && function_exists('mhash') && in_array($hash, self::$_supportedAlgosMhash)) { - $hashSupported = true; - } - - if ($hashSupported === false) { - #require_once 'Zend/Crypt/Hmac/Exception.php'; - throw new Zend_Crypt_Hmac_Exception('hash algorithm provided is not supported on this PHP installation; please enable the hash or mhash extensions'); - } - self::$_hashAlgorithm = $hash; - } - - /** - * Perform HMAC and return the keyed data - * - * @param string $data - * @param string $output - * @param bool $internal Option to not use hash() functions for testing - * @return string - */ - protected static function _hash($data, $output = self::STRING, $internal = false) - { - if (function_exists('hash_hmac')) { - if ($output == self::BINARY) { - return hash_hmac(self::$_hashAlgorithm, $data, self::$_key, true); - } - return hash_hmac(self::$_hashAlgorithm, $data, self::$_key); - } - - if (function_exists('mhash')) { - if ($output == self::BINARY) { - return mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); - } - $bin = mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); - return bin2hex($bin); - } - } - - /** - * Since MHASH accepts an integer constant representing the hash algorithm - * we need to make a small detour to get the correct integer matching our - * algorithm's name. - * - * @param string $hashAlgorithm - * @return integer - */ - protected static function _getMhashDefinition($hashAlgorithm) - { - for ($i = 0; $i <= mhash_count(); $i++) - { - $types[mhash_get_hash_name($i)] = $i; - } - return $types[strtoupper($hashAlgorithm)]; - } - -} diff --git a/lib/Zend/Crypt/Hmac/Exception.php b/lib/Zend/Crypt/Hmac/Exception.php deleted file mode 100644 index 5dae3edd9e1..00000000000 --- a/lib/Zend/Crypt/Hmac/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ - 127) { - return "\x00" . $long; - } - return $long; - } - - /** - * Translate a binary form into a big integer string - * - * @param string $binary - * @return string - */ - public function fromBinary($binary) { - return $this->_math->binaryToInteger($binary); - } - - /** - * Translate a big integer string into a binary form - * - * @param string $integer - * @return string - */ - public function toBinary($integer) - { - return $this->_math->integerToBinary($integer); - } - -} diff --git a/lib/Zend/Crypt/Math/BigInteger.php b/lib/Zend/Crypt/Math/BigInteger.php deleted file mode 100644 index 6ca7ae5316d..00000000000 --- a/lib/Zend/Crypt/Math/BigInteger.php +++ /dev/null @@ -1,118 +0,0 @@ -_loadAdapter($extension); - } - - /** - * Redirect all public method calls to the wrapped extension object. - * - * @param string $methodName - * @param array $args - * @return mixed - * @throws Zend_Crypt_Math_BigInteger_Exception - */ - public function __call($methodName, $args) - { - if(!method_exists($this->_math, $methodName)) { - #require_once 'Zend/Crypt/Math/BigInteger/Exception.php'; - throw new Zend_Crypt_Math_BigInteger_Exception('invalid method call: ' . get_class($this->_math) . '::' . $methodName . '() does not exist'); - } - return call_user_func_array(array($this->_math, $methodName), $args); - } - - /** - * @param string $extension - * @throws Zend_Crypt_Math_BigInteger_Exception - */ - protected function _loadAdapter($extension = null) - { - if ($extension === null) { - if (extension_loaded('gmp')) { - $extension = 'gmp'; - //} elseif (extension_loaded('big_int')) { - // $extension = 'big_int'; - } else { - $extension = 'bcmath'; - } - } - if($extension == 'gmp' && extension_loaded('gmp')) { - #require_once 'Zend/Crypt/Math/BigInteger/Gmp.php'; - $this->_math = new Zend_Crypt_Math_BigInteger_Gmp(); - //} elseif($extension == 'bigint' && extension_loaded('big_int')) { - // #require_once 'Zend/Crypt_Math/BigInteger/Bigint.php'; - // $this->_math = new Zend_Crypt_Math_BigInteger_Bigint(); - } elseif ($extension == 'bcmath' && extension_loaded('bcmath')) { - #require_once 'Zend/Crypt/Math/BigInteger/Bcmath.php'; - $this->_math = new Zend_Crypt_Math_BigInteger_Bcmath(); - } else { - #require_once 'Zend/Crypt/Math/BigInteger/Exception.php'; - throw new Zend_Crypt_Math_BigInteger_Exception($extension . ' big integer precision math support not detected'); - } - } - -} diff --git a/lib/Zend/Crypt/Math/BigInteger/Bcmath.php b/lib/Zend/Crypt/Math/BigInteger/Bcmath.php deleted file mode 100644 index 65677a9d883..00000000000 --- a/lib/Zend/Crypt/Math/BigInteger/Bcmath.php +++ /dev/null @@ -1,227 +0,0 @@ - 0) { - $return = chr(bcmod($operand, 256)) . $return; - $operand = bcdiv($operand, 256); - } - if (ord($return[0]) > 127) { - $return = "\0" . $return; - } - return $return; - } - - /**public function integerToBinary($operand) - { - $return = ''; - while(bccomp($operand, '0')) { - $return .= chr(bcmod($operand, '256')); - $operand = bcdiv($operand, '256'); - } - return $return; - }**/ // Prior version for referenced offset - - /** - * @param string $operand - * @return string - */ - public function hexToDecimal($operand) - { - $return = '0'; - while(strlen($hex)) { - $hex = hexdec(substr($operand, 0, 4)); - $dec = bcadd(bcmul($return, 65536), $hex); - $operand = substr($operand, 4); - } - return $return; - } -} diff --git a/lib/Zend/Crypt/Math/BigInteger/Exception.php b/lib/Zend/Crypt/Math/BigInteger/Exception.php deleted file mode 100644 index dec28d15447..00000000000 --- a/lib/Zend/Crypt/Math/BigInteger/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ - '7') { - $bigInt = '00' . $bigInt; - } - $return = pack("H*", $bigInt); - return $return; - } - - /** - * @param string $operand - * @return string - */ - public function hexToDecimal($operand) - { - $return = '0'; - while(strlen($hex)) { - $hex = hexdec(substr($operand, 0, 4)); - $dec = gmp_add(gmp_mul($return, 65536), $hex); - $operand = substr($operand, 4); - } - return $return; - } - -} diff --git a/lib/Zend/Crypt/Math/BigInteger/Interface.php b/lib/Zend/Crypt/Math/BigInteger/Interface.php deleted file mode 100644 index 9fa92815e30..00000000000 --- a/lib/Zend/Crypt/Math/BigInteger/Interface.php +++ /dev/null @@ -1,51 +0,0 @@ -_hashAlgorithm = OPENSSL_ALGO_SHA1; - - if (isset($options)) { - $this->setOptions($options); - } - } - - public function setOptions(array $options) - { - if (isset($options['passPhrase'])) { - $this->_passPhrase = $options['passPhrase']; - } - foreach ($options as $option=>$value) { - switch ($option) { - case 'pemString': - $this->setPemString($value); - break; - case 'pemPath': - $this->setPemPath($value); - break; - case 'certificateString': - $this->setCertificateString($value); - break; - case 'certificatePath': - $this->setCertificatePath($value); - break; - case 'hashAlgorithm': - $this->setHashAlgorithm($value); - break; - } - } - } - - public function getPrivateKey() - { - return $this->_privateKey; - } - - public function getPublicKey() - { - return $this->_publicKey; - } - - /** - * @param string $data - * @param Zend_Crypt_Rsa_Key_Private $privateKey - * @param string $format - * @return string - */ - public function sign($data, Zend_Crypt_Rsa_Key_Private $privateKey = null, $format = null) - { - $signature = ''; - if (isset($privateKey)) { - $opensslKeyResource = $privateKey->getOpensslKeyResource(); - } else { - $opensslKeyResource = $this->_privateKey->getOpensslKeyResource(); - } - $result = openssl_sign( - $data, $signature, - $opensslKeyResource, - $this->getHashAlgorithm() - ); - if ($format == self::BASE64) { - return base64_encode($signature); - } - return $signature; - } - - /** - * @param string $data - * @param string $signature - * @param string $format - * @return string - */ - public function verifySignature($data, $signature, $format = null) - { - if ($format == self::BASE64) { - $signature = base64_decode($signature); - } - $result = openssl_verify($data, $signature, - $this->getPublicKey()->getOpensslKeyResource(), - $this->getHashAlgorithm()); - return $result; - } - - /** - * @param string $data - * @param Zend_Crypt_Rsa_Key $key - * @param string $format - * @return string - */ - public function encrypt($data, Zend_Crypt_Rsa_Key $key, $format = null) - { - $encrypted = ''; - $function = 'openssl_public_encrypt'; - if ($key instanceof Zend_Crypt_Rsa_Key_Private) { - $function = 'openssl_private_encrypt'; - } - $function($data, $encrypted, $key->getOpensslKeyResource()); - if ($format == self::BASE64) { - return base64_encode($encrypted); - } - return $encrypted; - } - - /** - * @param string $data - * @param Zend_Crypt_Rsa_Key $key - * @param string $format - * @return string - */ - public function decrypt($data, Zend_Crypt_Rsa_Key $key, $format = null) - { - $decrypted = ''; - if ($format == self::BASE64) { - $data = base64_decode($data); - } - $function = 'openssl_private_decrypt'; - if ($key instanceof Zend_Crypt_Rsa_Key_Public) { - $function = 'openssl_public_decrypt'; - } - $function($data, $decrypted, $key->getOpensslKeyResource()); - return $decrypted; - } - - /** - * @param array $configargs - * - * @throws Zend_Crypt_Rsa_Exception - * - * @return ArrayObject - */ - public function generateKeys(array $configargs = null) - { - $config = null; - $passPhrase = null; - if ($configargs !== null) { - if (isset($configargs['passPhrase'])) { - $passPhrase = $configargs['passPhrase']; - unset($configargs['passPhrase']); - } - $config = $this->_parseConfigArgs($configargs); - } - $privateKey = null; - $publicKey = null; - $resource = openssl_pkey_new($config); - if (!$resource) { - #require_once 'Zend/Crypt/Rsa/Exception.php'; - throw new Zend_Crypt_Rsa_Exception('Failed to generate a new private key'); - } - // above fails on PHP 5.3 - openssl_pkey_export($resource, $private, $passPhrase); - $privateKey = new Zend_Crypt_Rsa_Key_Private($private, $passPhrase); - $details = openssl_pkey_get_details($resource); - $publicKey = new Zend_Crypt_Rsa_Key_Public($details['key']); - $return = new ArrayObject(array( - 'privateKey'=>$privateKey, - 'publicKey'=>$publicKey - ), ArrayObject::ARRAY_AS_PROPS); - return $return; - } - - /** - * @param string $value - */ - public function setPemString($value) - { - $this->_pemString = $value; - try { - $this->_privateKey = new Zend_Crypt_Rsa_Key_Private($this->_pemString, $this->_passPhrase); - $this->_publicKey = $this->_privateKey->getPublicKey(); - } catch (Zend_Crypt_Exception $e) { - $this->_privateKey = null; - $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_pemString); - } - } - - public function setPemPath($value) - { - $this->_pemPath = $value; - $this->setPemString(file_get_contents($this->_pemPath)); - } - - public function setCertificateString($value) - { - $this->_certificateString = $value; - $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_certificateString, $this->_passPhrase); - } - - public function setCertificatePath($value) - { - $this->_certificatePath = $value; - $this->setCertificateString(file_get_contents($this->_certificatePath)); - } - - public function setHashAlgorithm($name) - { - switch (strtolower($name)) { - case 'md2': - $this->_hashAlgorithm = OPENSSL_ALGO_MD2; - break; - case 'md4': - $this->_hashAlgorithm = OPENSSL_ALGO_MD4; - break; - case 'md5': - $this->_hashAlgorithm = OPENSSL_ALGO_MD5; - break; - case 'sha1': - $this->_hashAlgorithm = OPENSSL_ALGO_SHA1; - break; - case 'dss1': - $this->_hashAlgorithm = OPENSSL_ALGO_DSS1; - break; - } - } - - /** - * @return string - */ - public function getPemString() - { - return $this->_pemString; - } - - public function getPemPath() - { - return $this->_pemPath; - } - - public function getCertificateString() - { - return $this->_certificateString; - } - - public function getCertificatePath() - { - return $this->_certificatePath; - } - - public function getHashAlgorithm() - { - return $this->_hashAlgorithm; - } - - protected function _parseConfigArgs(array $config = null) - { - $configs = array(); - if (isset($config['private_key_bits'])) { - $configs['private_key_bits'] = $config['private_key_bits']; - } - if (isset($config['privateKeyBits'])) { - $configs['private_key_bits'] = $config['privateKeyBits']; - } - if (!empty($configs)) { - return $configs; - } - return null; - } - -} diff --git a/lib/Zend/Crypt/Rsa/Exception.php b/lib/Zend/Crypt/Rsa/Exception.php deleted file mode 100644 index 4775f2a7f31..00000000000 --- a/lib/Zend/Crypt/Rsa/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -_opensslKeyResource; - } - - /** - * @return string - * @throws Zend_Crypt_Exception - */ - public function toString() - { - if (!empty($this->_pemString)) { - return $this->_pemString; - } elseif (!empty($this->_certificateString)) { - return $this->_certificateString; - } - /** - * @see Zend_Crypt_Exception - */ - #require_once 'Zend/Crypt/Exception.php'; - throw new Zend_Crypt_Exception('No public key string representation is available'); - } - - /** - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - public function count() - { - return $this->_details['bits']; - } - - public function getType() - { - return $this->_details['type']; - } -} diff --git a/lib/Zend/Crypt/Rsa/Key/Private.php b/lib/Zend/Crypt/Rsa/Key/Private.php deleted file mode 100644 index 02dd19a7e67..00000000000 --- a/lib/Zend/Crypt/Rsa/Key/Private.php +++ /dev/null @@ -1,75 +0,0 @@ -_pemString = $pemString; - $this->_parse($passPhrase); - } - - /** - * @param string $passPhrase - * @throws Zend_Crypt_Exception - */ - protected function _parse($passPhrase) - { - $result = openssl_get_privatekey($this->_pemString, $passPhrase); - if (!$result) { - /** - * @see Zend_Crypt_Exception - */ - #require_once 'Zend/Crypt/Exception.php'; - throw new Zend_Crypt_Exception('Unable to load private key'); - } - $this->_opensslKeyResource = $result; - $this->_details = openssl_pkey_get_details($this->_opensslKeyResource); - } - - public function getPublicKey() - { - if ($this->_publicKey === null) { - /** - * @see Zend_Crypt_Rsa_Key_Public - */ - #require_once 'Zend/Crypt/Rsa/Key/Public.php'; - $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_details['key']); - } - return $this->_publicKey; - } - -} diff --git a/lib/Zend/Crypt/Rsa/Key/Public.php b/lib/Zend/Crypt/Rsa/Key/Public.php deleted file mode 100644 index 06f411052aa..00000000000 --- a/lib/Zend/Crypt/Rsa/Key/Public.php +++ /dev/null @@ -1,74 +0,0 @@ -_parse($string); - } - - /** - * @param string $string - * @throws Zend_Crypt_Exception - */ - protected function _parse($string) - { - if (preg_match("/^-----BEGIN CERTIFICATE-----/", $string)) { - $this->_certificateString = $string; - } else { - $this->_pemString = $string; - } - $result = openssl_get_publickey($string); - if (!$result) { - /** - * @see Zend_Crypt_Exception - */ - #require_once 'Zend/Crypt/Exception.php'; - throw new Zend_Crypt_Exception('Unable to load public key'); - } - //openssl_pkey_export($result, $public); - //$this->_pemString = $public; - $this->_opensslKeyResource = $result; - $this->_details = openssl_pkey_get_details($this->_opensslKeyResource); - } - - public function getCertificate() - { - return $this->_certificateString; - } - -} diff --git a/lib/Zend/Currency.php b/lib/Zend/Currency.php deleted file mode 100644 index 896d54674e4..00000000000 --- a/lib/Zend/Currency.php +++ /dev/null @@ -1,902 +0,0 @@ - Position for the currency sign - * 'script' => Script for the output - * 'format' => Locale for numeric output - * 'display' => Currency detail to show - * 'precision' => Precision for the currency - * 'name' => Name for this currency - * 'currency' => 3 lettered international abbreviation - * 'symbol' => Currency symbol - * 'locale' => Locale for this currency - * 'value' => Money value - * 'service' => Exchange service to use - * - * @var array - * @see Zend_Locale - */ - protected $_options = array( - 'position' => self::STANDARD, - 'script' => null, - 'format' => null, - 'display' => self::NO_SYMBOL, - 'precision' => 2, - 'name' => null, - 'currency' => null, - 'symbol' => null, - 'locale' => null, - 'value' => 0, - 'service' => null, - 'tag' => 'Zend_Locale' - ); - - /** - * Creates a currency instance. Every supressed parameter is used from the actual or the given locale. - * - * @param string|array $options OPTIONAL Options array or currency short name - * when string is given - * @param string|Zend_Locale $locale OPTIONAL locale name - * @throws Zend_Currency_Exception When currency is invalid - */ - public function __construct($options = null, $locale = null) - { - $calloptions = $options; - if (is_array($options) && isset($options['display'])) { - $this->_options['display'] = $options['display']; - } - - if (is_array($options)) { - $this->setLocale($locale); - $this->setFormat($options); - } else if (Zend_Locale::isLocale($options, false, false)) { - $this->setLocale($options); - $options = $locale; - } else { - $this->setLocale($locale); - } - - // Get currency details - if (!isset($this->_options['currency']) || !is_array($options)) { - $this->_options['currency'] = self::getShortName($options, $this->_options['locale']); - } - - if (!isset($this->_options['name']) || !is_array($options)) { - $this->_options['name'] = self::getName($options, $this->_options['locale']); - } - - if (!isset($this->_options['symbol']) || !is_array($options)) { - $this->_options['symbol'] = self::getSymbol($options, $this->_options['locale']); - } - - if (($this->_options['currency'] === null) and ($this->_options['name'] === null)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("Currency '$options' not found"); - } - - // Get the format - if ((is_array($calloptions) && !isset($calloptions['display'])) - || (!is_array($calloptions) && $this->_options['display'] == self::NO_SYMBOL)) { - if (!empty($this->_options['symbol'])) { - $this->_options['display'] = self::USE_SYMBOL; - } else if (!empty($this->_options['currency'])) { - $this->_options['display'] = self::USE_SHORTNAME; - } - } - } - - /** - * Returns a localized currency string - * - * @param integer|float $value OPTIONAL Currency value - * @param array $options OPTIONAL options to set temporary - * @throws Zend_Currency_Exception When the value is not a number - * @return string - */ - public function toCurrency($value = null, array $options = array()) - { - if ($value === null) { - if (is_array($options) && isset($options['value'])) { - $value = $options['value']; - } else { - $value = $this->_options['value']; - } - } - - if (is_array($value)) { - $options += $value; - if (isset($options['value'])) { - $value = $options['value']; - } - } - - // Validate the passed number - if (!(isset($value)) || (is_numeric($value) === false)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("Value '$value' has to be numeric"); - } - - if (isset($options['currency'])) { - if (!isset($options['locale'])) { - $options['locale'] = $this->_options['locale']; - } - - $options['currency'] = self::getShortName($options['currency'], $options['locale']); - $options['name'] = self::getName($options['currency'], $options['locale']); - $options['symbol'] = self::getSymbol($options['currency'], $options['locale']); - } - - $options = $this->_checkOptions($options) + $this->_options; - - // Format the number - $format = $options['format']; - $locale = $options['locale']; - if (empty($format)) { - $format = Zend_Locale_Data::getContent($locale, 'currencynumber'); - } else if (Zend_Locale::isLocale($format, true, false)) { - $locale = $format; - $format = Zend_Locale_Data::getContent($format, 'currencynumber'); - } - - $original = $value; - $value = Zend_Locale_Format::toNumber($value, array('locale' => $locale, - 'number_format' => $format, - 'precision' => $options['precision'])); - - if ($options['position'] !== self::STANDARD) { - $value = str_replace('¤', '', $value); - $space = ''; - if (iconv_strpos($value, ' ') !== false) { - $value = str_replace(' ', '', $value); - $space = ' '; - } - - if ($options['position'] == self::LEFT) { - $value = '¤' . $space . $value; - } else { - $value = $value . $space . '¤'; - } - } - - // Localize the number digits - if (empty($options['script']) === false) { - $value = Zend_Locale_Format::convertNumerals($value, 'Latn', $options['script']); - } - - // Get the sign to be placed next to the number - if (is_numeric($options['display']) === false) { - $sign = $options['display']; - } else { - switch($options['display']) { - case self::USE_SYMBOL: - $sign = $this->_extractPattern($options['symbol'], $original); - break; - - case self::USE_SHORTNAME: - $sign = $options['currency']; - break; - - case self::USE_NAME: - $sign = $options['name']; - break; - - default: - $sign = ''; - $value = str_replace(' ', '', $value); - break; - } - } - - $value = str_replace('¤', $sign, $value); - return $value; - } - - /** - * Internal method to extract the currency pattern - * when a choice is given based on the given value - * - * @param string $pattern - * @param float|integer $value - * @return string - */ - private function _extractPattern($pattern, $value) - { - if (strpos($pattern, '|') === false) { - return $pattern; - } - - $patterns = explode('|', $pattern); - $token = $pattern; - $value = trim(str_replace('¤', '', $value)); - krsort($patterns); - foreach($patterns as $content) { - if (strpos($content, '<') !== false) { - $check = iconv_substr($content, 0, iconv_strpos($content, '<')); - $token = iconv_substr($content, iconv_strpos($content, '<') + 1); - if ($check < $value) { - return $token; - } - } else { - $check = iconv_substr($content, 0, iconv_strpos($content, '≤')); - $token = iconv_substr($content, iconv_strpos($content, '≤') + 1); - if ($check <= $value) { - return $token; - } - } - - } - - return $token; - } - - /** - * Sets the formating options of the localized currency string - * If no parameter is passed, the standard setting of the - * actual set locale will be used - * - * @param array $options (Optional) Options to set - * @return Zend_Currency - */ - public function setFormat(array $options = array()) - { - $this->_options = $this->_checkOptions($options) + $this->_options; - return $this; - } - - /** - * Internal function for checking static given locale parameter - * - * @param string $currency (Optional) Currency name - * @param string|Zend_Locale $locale (Optional) Locale to display informations - * @throws Zend_Currency_Exception When locale contains no region - * @return string The extracted locale representation as string - */ - private function _checkParams($currency = null, $locale = null) - { - // Manage the params - if ((empty($locale)) and (!empty($currency)) and - (Zend_Locale::isLocale($currency, true, false))) { - $locale = $currency; - $currency = null; - } - - // Validate the locale and get the country short name - $country = null; - if ((Zend_Locale::isLocale($locale, true, false)) and (strlen($locale) > 4)) { - $country = substr($locale, (strpos($locale, '_') + 1)); - } else { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("No region found within the locale '" . (string) $locale . "'"); - } - - // Get the available currencies for this country - $data = Zend_Locale_Data::getContent($locale, 'currencytoregion', $country); - if ((empty($currency) === false) and (empty($data) === false)) { - $abbreviation = $currency; - } else { - $abbreviation = $data; - } - - return array('locale' => $locale, 'currency' => $currency, 'name' => $abbreviation, 'country' => $country); - } - - /** - * Returns the actual or details of other currency symbols, - * when no symbol is available it returns the currency shortname (f.e. FIM for Finnian Mark) - * - * @param string $currency (Optional) Currency name - * @param string|Zend_Locale $locale (Optional) Locale to display informations - * @return string - */ - public function getSymbol($currency = null, $locale = null) - { - if (($currency === null) and ($locale === null)) { - return $this->_options['symbol']; - } - - $params = self::_checkParams($currency, $locale); - - // Get the symbol - $symbol = Zend_Locale_Data::getContent($params['locale'], 'currencysymbol', $params['currency']); - if (empty($symbol) === true) { - $symbol = Zend_Locale_Data::getContent($params['locale'], 'currencysymbol', $params['name']); - } - - if (empty($symbol) === true) { - return null; - } - - return $symbol; - } - - /** - * Returns the actual or details of other currency shortnames - * - * @param string $currency OPTIONAL Currency's name - * @param string|Zend_Locale $locale OPTIONAL The locale - * @return string - */ - public function getShortName($currency = null, $locale = null) - { - if (($currency === null) and ($locale === null)) { - return $this->_options['currency']; - } - - $params = self::_checkParams($currency, $locale); - - // Get the shortname - if (empty($params['currency']) === true) { - return $params['name']; - } - - $list = Zend_Locale_Data::getContent($params['locale'], 'currencytoname', $params['currency']); - if (empty($list) === true) { - $list = Zend_Locale_Data::getContent($params['locale'], 'nametocurrency', $params['currency']); - if (empty($list) === false) { - $list = $params['currency']; - } - } - - if (empty($list) === true) { - return null; - } - - return $list; - } - - /** - * Returns the actual or details of other currency names - * - * @param string $currency (Optional) Currency's short name - * @param string|Zend_Locale $locale (Optional) The locale - * @return string - */ - public function getName($currency = null, $locale = null) - { - if (($currency === null) and ($locale === null)) { - return $this->_options['name']; - } - - $params = self::_checkParams($currency, $locale); - - // Get the name - $name = Zend_Locale_Data::getContent($params['locale'], 'nametocurrency', $params['currency']); - if (empty($name) === true) { - $name = Zend_Locale_Data::getContent($params['locale'], 'nametocurrency', $params['name']); - } - - if (empty($name) === true) { - return null; - } - - return $name; - } - - /** - * Returns a list of regions where this currency is or was known - * - * @param string $currency OPTIONAL Currency's short name - * @throws Zend_Currency_Exception When no currency was defined - * @return array List of regions - */ - public function getRegionList($currency = null) - { - if ($currency === null) { - $currency = $this->_options['currency']; - } - - if (empty($currency) === true) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception('No currency defined'); - } - - $data = Zend_Locale_Data::getContent($this->_options['locale'], 'regiontocurrency', $currency); - - $result = explode(' ', $data); - return $result; - } - - /** - * Returns a list of currencies which are used in this region - * a region name should be 2 charachters only (f.e. EG, DE, US) - * If no region is given, the actual region is used - * - * @param string $region OPTIONAL Region to return the currencies for - * @return array List of currencies - */ - public function getCurrencyList($region = null) - { - if (empty($region) === true) { - if (strlen($this->_options['locale']) > 4) { - $region = substr($this->_options['locale'], (strpos($this->_options['locale'], '_') + 1)); - } - } - - $data = Zend_Locale_Data::getContent($this->_options['locale'], 'currencytoregion', $region); - - $result = explode(' ', $data); - return $result; - } - - /** - * Returns the actual currency name - * - * @return string - */ - public function toString() - { - return $this->toCurrency(); - } - - /** - * Returns the currency name - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Returns the set cache - * - * @return Zend_Cache_Core The set cache - */ - public static function getCache() - { - return Zend_Locale_Data::getCache(); - } - - /** - * Sets a cache for Zend_Currency - * - * @param Zend_Cache_Core $cache Cache to set - * @return void - */ - public static function setCache(Zend_Cache_Core $cache) - { - Zend_Locale_Data::setCache($cache); - } - - /** - * Returns true when a cache is set - * - * @return boolean - */ - public static function hasCache() - { - return Zend_Locale_Data::hasCache(); - } - - /** - * Removes any set cache - * - * @return void - */ - public static function removeCache() - { - Zend_Locale_Data::removeCache(); - } - - /** - * Clears all set cache data - * - * @param string $tag Tag to clear when the default tag name is not used - * @return void - */ - public static function clearCache($tag = null) - { - Zend_Locale_Data::clearCache($tag); - } - - /** - * Sets a new locale for data retreivement - * Example: 'de_XX' will be set to 'de' because 'de_XX' does not exist - * 'xx_YY' will be set to 'root' because 'xx' does not exist - * - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @throws Zend_Currency_Exception When the given locale does not exist - * @return Zend_Currency Provides fluent interface - */ - public function setLocale($locale = null) - { - #require_once 'Zend/Locale.php'; - try { - $locale = Zend_Locale::findLocale($locale); - if (strlen($locale) > 4) { - $this->_options['locale'] = $locale; - } else { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("No region found within the locale '" . (string) $locale . "'"); - } - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception($e->getMessage()); - } - - // Get currency details - $this->_options['currency'] = $this->getShortName(null, $this->_options['locale']); - $this->_options['name'] = $this->getName(null, $this->_options['locale']); - $this->_options['symbol'] = $this->getSymbol(null, $this->_options['locale']); - - return $this; - } - - /** - * Returns the actual set locale - * - * @return string - */ - public function getLocale() - { - return $this->_options['locale']; - } - - /** - * Returns the value - * - * @return float - */ - public function getValue() - { - return $this->_options['value']; - } - - /** - * Adds a currency - * - * @param float|integer|Zend_Currency $value Add this value to currency - * @param string|Zend_Currency $currency The currency to add - * @return Zend_Currency - */ - public function setValue($value, $currency = null) - { - $this->_options['value'] = $this->_exchangeCurrency($value, $currency); - return $this; - } - - /** - * Adds a currency - * - * @param float|integer|Zend_Currency $value Add this value to currency - * @param string|Zend_Currency $currency The currency to add - * @return Zend_Currency - */ - public function add($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $this->_options['value'] += (float) $value; - return $this; - } - - /** - * Substracts a currency - * - * @param float|integer|Zend_Currency $value Substracts this value from currency - * @param string|Zend_Currency $currency The currency to substract - * @return Zend_Currency - */ - public function sub($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $this->_options['value'] -= (float) $value; - return $this; - } - - /** - * Divides a currency - * - * @param float|integer|Zend_Currency $value Divides this value from currency - * @param string|Zend_Currency $currency The currency to divide - * @return Zend_Currency - */ - public function div($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $this->_options['value'] /= (float) $value; - return $this; - } - - /** - * Multiplies a currency - * - * @param float|integer|Zend_Currency $value Multiplies this value from currency - * @param string|Zend_Currency $currency The currency to multiply - * @return Zend_Currency - */ - public function mul($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $this->_options['value'] *= (float) $value; - return $this; - } - - /** - * Calculates the modulo from a currency - * - * @param float|integer|Zend_Currency $value Calculate modulo from this value - * @param string|Zend_Currency $currency The currency to calculate the modulo - * @return Zend_Currency - */ - public function mod($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $this->_options['value'] %= (float) $value; - return $this; - } - - /** - * Compares two currencies - * - * @param float|integer|Zend_Currency $value Compares the currency with this value - * @param string|Zend_Currency $currency The currency to compare this value from - * @return Zend_Currency - */ - public function compare($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - $value = $this->_options['value'] - $value; - if ($value < 0) { - return -1; - } else if ($value > 0) { - return 1; - } - - return 0; - } - - /** - * Returns true when the two currencies are equal - * - * @param float|integer|Zend_Currency $value Compares the currency with this value - * @param string|Zend_Currency $currency The currency to compare this value from - * @return boolean - */ - public function equals($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - if ($this->_options['value'] == $value) { - return true; - } - - return false; - } - - /** - * Returns true when the currency is more than the given value - * - * @param float|integer|Zend_Currency $value Compares the currency with this value - * @param string|Zend_Currency $currency The currency to compare this value from - * @return boolean - */ - public function isMore($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - if ($this->_options['value'] > $value) { - return true; - } - - return false; - } - - /** - * Returns true when the currency is less than the given value - * - * @param float|integer|Zend_Currency $value Compares the currency with this value - * @param string|Zend_Currency $currency The currency to compare this value from - * @return boolean - */ - public function isLess($value, $currency = null) - { - $value = $this->_exchangeCurrency($value, $currency); - if ($this->_options['value'] < $value) { - return true; - } - - return false; - - } - - /** - * Internal method which calculates the exchanges currency - * - * @param float|integer|Zend_Currency $value Compares the currency with this value - * @param string|Zend_Currency $currency The currency to compare this value from - * @return unknown - */ - protected function _exchangeCurrency($value, $currency) - { - if ($value instanceof Zend_Currency) { - $currency = $value->getShortName(); - $value = $value->getValue(); - } else { - $currency = $this->getShortName($currency, $this->getLocale()); - } - - $rate = 1; - if ($currency !== $this->getShortName()) { - $service = $this->getService(); - if (!($service instanceof Zend_Currency_CurrencyInterface)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception('No exchange service applied'); - } - - $rate = $service->getRate($currency, $this->getShortName()); - } - - $value *= $rate; - return $value; - } - - /** - * Returns the set service class - * - * @return Zend_Service - */ - public function getService() - { - return $this->_options['service']; - } - - /** - * Sets a new exchange service - * - * @param string|Zend_Currency_CurrencyInterface $service Service class - * @return Zend_Currency - */ - public function setService($service) - { - if (is_string($service)) { - #require_once 'Zend/Loader.php'; - if (!class_exists($service)) { - $file = str_replace('_', DIRECTORY_SEPARATOR, $service) . '.php'; - if (Zend_Loader::isReadable($file)) { - Zend_Loader::loadClass($service); - } - } - - $service = new $service; - } - - if (!($service instanceof Zend_Currency_CurrencyInterface)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception('A currency service must implement Zend_Currency_CurrencyInterface'); - } - - $this->_options['service'] = $service; - return $this; - } - - /** - * Internal method for checking the options array - * - * @param array $options Options to check - * @throws Zend_Currency_Exception On unknown position - * @throws Zend_Currency_Exception On unknown locale - * @throws Zend_Currency_Exception On unknown display - * @throws Zend_Currency_Exception On precision not between -1 and 30 - * @throws Zend_Currency_Exception On problem with script conversion - * @throws Zend_Currency_Exception On unknown options - * @return array - */ - protected function _checkOptions(array $options = array()) - { - if (count($options) === 0) { - return $this->_options; - } - - foreach ($options as $name => $value) { - $name = strtolower($name); - if ($name !== 'format') { - if (gettype($value) === 'string') { - $value = strtolower($value); - } - } - - switch($name) { - case 'position': - if (($value !== self::STANDARD) and ($value !== self::RIGHT) and ($value !== self::LEFT)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("Unknown position '" . $value . "'"); - } - - break; - - case 'format': - if ((empty($value) === false) and (Zend_Locale::isLocale($value, null, false) === false)) { - if (!is_string($value) || (strpos($value, '0') === false)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("'" . - ((gettype($value) === 'object') ? get_class($value) : $value) - . "' is no format token"); - } - } - break; - - case 'display': - if (is_numeric($value) and ($value !== self::NO_SYMBOL) and ($value !== self::USE_SYMBOL) and - ($value !== self::USE_SHORTNAME) and ($value !== self::USE_NAME)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("Unknown display '$value'"); - } - break; - - case 'precision': - if ($value === null) { - $value = -1; - } - - if (($value < -1) || ($value > 30)) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception("'$value' precision has to be between -1 and 30."); - } - break; - - case 'script': - try { - Zend_Locale_Format::convertNumerals(0, $options['script']); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Currency/Exception.php'; - throw new Zend_Currency_Exception($e->getMessage()); - } - break; - - default: - break; - } - } - - return $options; - } -} diff --git a/lib/Zend/Currency/CurrencyInterface.php b/lib/Zend/Currency/CurrencyInterface.php deleted file mode 100644 index 8e828864b8c..00000000000 --- a/lib/Zend/Currency/CurrencyInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - 'iso', // format for date strings 'iso' or 'php' - 'fix_dst' => true, // fix dst on summer/winter time change - 'extend_month' => false, // false - addMonth like SQL, true like excel - 'cache' => null, // cache to set - 'timesync' => null // timesync server to set - ); - - // Class wide Date Constants - const DAY = 'dd'; - const DAY_SHORT = 'd'; - const DAY_SUFFIX = 'SS'; - const DAY_OF_YEAR = 'D'; - const WEEKDAY = 'EEEE'; - const WEEKDAY_SHORT = 'EEE'; - const WEEKDAY_NARROW = 'E'; - const WEEKDAY_NAME = 'EE'; - const WEEKDAY_8601 = 'eee'; - const WEEKDAY_DIGIT = 'e'; - const WEEK = 'ww'; - const MONTH = 'MM'; - const MONTH_SHORT = 'M'; - const MONTH_DAYS = 'ddd'; - const MONTH_NAME = 'MMMM'; - const MONTH_NAME_SHORT = 'MMM'; - const MONTH_NAME_NARROW = 'MMMMM'; - const YEAR = 'y'; - const YEAR_SHORT = 'yy'; - const YEAR_8601 = 'Y'; - const YEAR_SHORT_8601 = 'YY'; - const LEAPYEAR = 'l'; - const MERIDIEM = 'a'; - const SWATCH = 'B'; - const HOUR = 'HH'; - const HOUR_SHORT = 'H'; - const HOUR_AM = 'hh'; - const HOUR_SHORT_AM = 'h'; - const MINUTE = 'mm'; - const MINUTE_SHORT = 'm'; - const SECOND = 'ss'; - const SECOND_SHORT = 's'; - const MILLISECOND = 'S'; - const TIMEZONE_NAME = 'zzzz'; - const DAYLIGHT = 'I'; - const GMT_DIFF = 'Z'; - const GMT_DIFF_SEP = 'ZZZZ'; - const TIMEZONE = 'z'; - const TIMEZONE_SECS = 'X'; - const ISO_8601 = 'c'; - const RFC_2822 = 'r'; - const TIMESTAMP = 'U'; - const ERA = 'G'; - const ERA_NAME = 'GGGG'; - const ERA_NARROW = 'GGGGG'; - const DATES = 'F'; - const DATE_FULL = 'FFFFF'; - const DATE_LONG = 'FFFF'; - const DATE_MEDIUM = 'FFF'; - const DATE_SHORT = 'FF'; - const TIMES = 'WW'; - const TIME_FULL = 'TTTTT'; - const TIME_LONG = 'TTTT'; - const TIME_MEDIUM = 'TTT'; - const TIME_SHORT = 'TT'; - const DATETIME = 'K'; - const DATETIME_FULL = 'KKKKK'; - const DATETIME_LONG = 'KKKK'; - const DATETIME_MEDIUM = 'KKK'; - const DATETIME_SHORT = 'KK'; - const ATOM = 'OOO'; - const COOKIE = 'CCC'; - const RFC_822 = 'R'; - const RFC_850 = 'RR'; - const RFC_1036 = 'RRR'; - const RFC_1123 = 'RRRR'; - const RFC_3339 = 'RRRRR'; - const RSS = 'SSS'; - const W3C = 'WWW'; - - /** - * Generates the standard date object, could be a unix timestamp, localized date, - * string, integer, array and so on. Also parts of dates or time are supported - * Always set the default timezone: http://php.net/date_default_timezone_set - * For example, in your bootstrap: date_default_timezone_set('America/Los_Angeles'); - * For detailed instructions please look in the docu. - * - * @param string|integer|Zend_Date|array $date OPTIONAL Date value or value of date part to set - * ,depending on $part. If null the actual time is set - * @param string $part OPTIONAL Defines the input format of $date - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - * @throws Zend_Date_Exception - */ - public function __construct($date = null, $part = null, $locale = null) - { - if (is_object($date) and !($date instanceof Zend_TimeSync_Protocol) and - !($date instanceof Zend_Date)) { - if ($locale instanceof Zend_Locale) { - $locale = $date; - $date = null; - $part = null; - } else { - $date = (string) $date; - } - } - - if (($date !== null) and !is_array($date) and !($date instanceof Zend_TimeSync_Protocol) and - !($date instanceof Zend_Date) and !defined($date) and Zend_Locale::isLocale($date, true, false)) { - $locale = $date; - $date = null; - $part = null; - } else if (($part !== null) and !defined($part) and Zend_Locale::isLocale($part, true, false)) { - $locale = $part; - $part = null; - } - - $this->setLocale($locale); - if (is_string($date) && ($part === null) && (strlen($date) <= 5)) { - $part = $date; - $date = null; - } - - if ($date === null) { - if ($part === null) { - $date = time(); - } else if ($part !== self::TIMESTAMP) { - $date = self::now($locale); - $date = $date->get($part); - } - } - - if ($date instanceof Zend_TimeSync_Protocol) { - $date = $date->getInfo(); - $date = $this->_getTime($date['offset']); - $part = null; - } else if (parent::$_defaultOffset != 0) { - $date = $this->_getTime(parent::$_defaultOffset); - } - - // set the timezone and offset for $this - $zone = @date_default_timezone_get(); - $this->setTimezone($zone); - - // try to get timezone from date-string - if (!is_int($date)) { - $zone = $this->getTimezoneFromString($date); - $this->setTimezone($zone); - } - - // set datepart - if (($part !== null && $part !== self::TIMESTAMP) || (!is_numeric($date))) { - // switch off dst handling for value setting - $this->setUnixTimestamp($this->getGmtOffset()); - $this->set($date, $part, $this->_locale); - - // DST fix - if (is_array($date) === true) { - if (!isset($date['hour'])) { - $date['hour'] = 0; - } - - $hour = $this->toString('H', 'iso', true); - $hour = $date['hour'] - $hour; - switch ($hour) { - case 1 : - case -23 : - $this->addTimestamp(3600); - break; - case -1 : - case 23 : - $this->subTimestamp(3600); - break; - case 2 : - case -22 : - $this->addTimestamp(7200); - break; - case -2 : - case 22 : - $this->subTimestamp(7200); - break; - } - } - } else { - $this->setUnixTimestamp($date); - } - } - - /** - * Sets class wide options, if no option was given, the actual set options will be returned - * - * @param array $options Options to set - * @throws Zend_Date_Exception - * @return Options array if no option was given - */ - public static function setOptions(array $options = array()) - { - if (empty($options)) { - return self::$_options; - } - - foreach ($options as $name => $value) { - $name = strtolower($name); - - if (array_key_exists($name, self::$_options)) { - switch($name) { - case 'format_type' : - if ((strtolower($value) != 'php') && (strtolower($value) != 'iso')) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("Unknown format type ($value) for dates, only 'iso' and 'php' supported", 0, null, $value); - } - break; - case 'fix_dst' : - if (!is_bool($value)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("'fix_dst' has to be boolean", 0, null, $value); - } - break; - case 'extend_month' : - if (!is_bool($value)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("'extend_month' has to be boolean", 0, null, $value); - } - break; - case 'cache' : - if ($value === null) { - parent::$_cache = null; - } else { - if (!$value instanceof Zend_Cache_Core) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("Instance of Zend_Cache expected"); - } - - parent::$_cache = $value; - parent::$_cacheTags = Zend_Date_DateObject::_getTagSupportForCache(); - Zend_Locale_Data::setCache($value); - } - break; - case 'timesync' : - if ($value === null) { - parent::$_defaultOffset = 0; - } else { - if (!$value instanceof Zend_TimeSync_Protocol) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("Instance of Zend_TimeSync expected"); - } - - $date = $value->getInfo(); - parent::$_defaultOffset = $date['offset']; - } - break; - } - self::$_options[$name] = $value; - } - else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("Unknown option: $name = $value"); - } - } - } - - /** - * Returns this object's internal UNIX timestamp (equivalent to Zend_Date::TIMESTAMP). - * If the timestamp is too large for integers, then the return value will be a string. - * This function does not return the timestamp as an object. - * Use clone() or copyPart() instead. - * - * @return integer|string UNIX timestamp - */ - public function getTimestamp() - { - return $this->getUnixTimestamp(); - } - - /** - * Returns the calculated timestamp - * HINT: timestamps are always GMT - * - * @param string $calc Type of calculation to make - * @param string|integer|array|Zend_Date $stamp Timestamp to calculate, when null the actual timestamp is calculated - * @return Zend_Date|integer - * @throws Zend_Date_Exception - */ - private function _timestamp($calc, $stamp) - { - if ($stamp instanceof Zend_Date) { - // extract timestamp from object - $stamp = $stamp->getTimestamp(); - } - - if (is_array($stamp)) { - if (isset($stamp['timestamp']) === true) { - $stamp = $stamp['timestamp']; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('no timestamp given in array'); - } - } - - if ($calc === 'set') { - $return = $this->setUnixTimestamp($stamp); - } else { - $return = $this->_calcdetail($calc, $stamp, self::TIMESTAMP, null); - } - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - /** - * Sets a new timestamp - * - * @param integer|string|array|Zend_Date $timestamp Timestamp to set - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setTimestamp($timestamp) - { - return $this->_timestamp('set', $timestamp); - } - - /** - * Adds a timestamp - * - * @param integer|string|array|Zend_Date $timestamp Timestamp to add - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addTimestamp($timestamp) - { - return $this->_timestamp('add', $timestamp); - } - - /** - * Subtracts a timestamp - * - * @param integer|string|array|Zend_Date $timestamp Timestamp to sub - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subTimestamp($timestamp) - { - return $this->_timestamp('sub', $timestamp); - } - - /** - * Compares two timestamps, returning the difference as integer - * - * @param integer|string|array|Zend_Date $timestamp Timestamp to compare - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareTimestamp($timestamp) - { - return $this->_timestamp('cmp', $timestamp); - } - - /** - * Returns a string representation of the object - * Supported format tokens are: - * G - era, y - year, Y - ISO year, M - month, w - week of year, D - day of year, d - day of month - * E - day of week, e - number of weekday (1-7), h - hour 1-12, H - hour 0-23, m - minute, s - second - * A - milliseconds of day, z - timezone, Z - timezone offset, S - fractional second, a - period of day - * - * Additionally format tokens but non ISO conform are: - * SS - day suffix, eee - php number of weekday(0-6), ddd - number of days per month - * l - Leap year, B - swatch internet time, I - daylight saving time, X - timezone offset in seconds - * r - RFC2822 format, U - unix timestamp - * - * Not supported ISO tokens are - * u - extended year, Q - quarter, q - quarter, L - stand alone month, W - week of month - * F - day of week of month, g - modified julian, c - stand alone weekday, k - hour 0-11, K - hour 1-24 - * v - wall zone - * - * @param string $format OPTIONAL Rule for formatting output. If null the default date format is used - * @param string $type OPTIONAL Type for the format string which overrides the standard setting - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return string - */ - public function toString($format = null, $type = null, $locale = null) - { - if (is_object($format)) { - if ($format instanceof Zend_Locale) { - $locale = $format; - $format = null; - } else { - $format = (string) $format; - } - } - - if (is_object($type)) { - if ($type instanceof Zend_Locale) { - $locale = $type; - $type = null; - } else { - $type = (string) $type; - } - } - - if (($format !== null) && !defined($format) - && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') - && Zend_Locale::isLocale($format, null, false)) { - $locale = $format; - $format = null; - } - - if (($type !== null) and ($type != 'php') and ($type != 'iso') and - Zend_Locale::isLocale($type, null, false)) { - $locale = $type; - $type = null; - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if ($format === null) { - $format = Zend_Locale_Format::getDateFormat($locale) . ' ' . Zend_Locale_Format::getTimeFormat($locale); - } else if (((self::$_options['format_type'] == 'php') && ($type === null)) || ($type == 'php')) { - $format = Zend_Locale_Format::convertPhpToIsoFormat($format); - } - - return $this->date($this->_toToken($format, $locale), $this->getUnixTimestamp(), false); - } - - /** - * Returns a string representation of the date which is equal with the timestamp - * - * @return string - */ - public function __toString() - { - return $this->toString(null, $this->_locale); - } - - /** - * Returns a integer representation of the object - * But returns false when the given part is no value f.e. Month-Name - * - * @param string|integer|Zend_Date $part OPTIONAL Defines the date or datepart to return as integer - * @return integer|false - */ - public function toValue($part = null) - { - $result = $this->get($part); - if (is_numeric($result)) { - return intval("$result"); - } else { - return false; - } - } - - /** - * Returns an array representation of the object - * - * @return array - */ - public function toArray() - { - return array('day' => $this->toString(self::DAY_SHORT, 'iso'), - 'month' => $this->toString(self::MONTH_SHORT, 'iso'), - 'year' => $this->toString(self::YEAR, 'iso'), - 'hour' => $this->toString(self::HOUR_SHORT, 'iso'), - 'minute' => $this->toString(self::MINUTE_SHORT, 'iso'), - 'second' => $this->toString(self::SECOND_SHORT, 'iso'), - 'timezone' => $this->toString(self::TIMEZONE, 'iso'), - 'timestamp' => $this->toString(self::TIMESTAMP, 'iso'), - 'weekday' => $this->toString(self::WEEKDAY_8601, 'iso'), - 'dayofyear' => $this->toString(self::DAY_OF_YEAR, 'iso'), - 'week' => $this->toString(self::WEEK, 'iso'), - 'gmtsecs' => $this->toString(self::TIMEZONE_SECS, 'iso')); - } - - /** - * Returns a representation of a date or datepart - * This could be for example a localized monthname, the time without date, - * the era or only the fractional seconds. There are about 50 different supported date parts. - * For a complete list of supported datepart values look into the docu - * - * @param string $part OPTIONAL Part of the date to return, if null the timestamp is returned - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return string date or datepart - */ - public function get($part = null, $locale = null) - { - if ($locale === null) { - $locale = $this->getLocale(); - } - - if (($part !== null) && !defined($part) - && ($part != 'ee') && ($part != 'ss') && ($part != 'GG') && ($part != 'MM') && ($part != 'EE') && ($part != 'TT') - && Zend_Locale::isLocale($part, null, false)) { - $locale = $part; - $part = null; - } - - if ($part === null) { - $part = self::TIMESTAMP; - } else if (self::$_options['format_type'] == 'php') { - $part = Zend_Locale_Format::convertPhpToIsoFormat($part); - } - - return $this->date($this->_toToken($part, $locale), $this->getUnixTimestamp(), false); - } - - /** - * Internal method to apply tokens - * - * @param string $part - * @param string $locale - * @return string - */ - private function _toToken($part, $locale) { - // get format tokens - $comment = false; - $format = ''; - $orig = ''; - for ($i = 0; isset($part[$i]); ++$i) { - if ($part[$i] == "'") { - $comment = $comment ? false : true; - if (isset($part[$i+1]) && ($part[$i+1] == "'")) { - $comment = $comment ? false : true; - $format .= "\\'"; - ++$i; - } - - $orig = ''; - continue; - } - - if ($comment) { - $format .= '\\' . $part[$i]; - $orig = ''; - } else { - $orig .= $part[$i]; - if (!isset($part[$i+1]) || (isset($orig[0]) && ($orig[0] != $part[$i+1]))) { - $format .= $this->_parseIsoToDate($orig, $locale); - $orig = ''; - } - } - } - - return $format; - } - - /** - * Internal parsing method - * - * @param string $token - * @param string $locale - * @return string - */ - private function _parseIsoToDate($token, $locale) { - switch($token) { - case self::DAY : - return 'd'; - break; - - case self::WEEKDAY_SHORT : - $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); - $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday)); - return $this->_toComment(iconv_substr($day, 0, 3, 'UTF-8')); - break; - - case self::DAY_SHORT : - return 'j'; - break; - - case self::WEEKDAY : - $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday))); - break; - - case self::WEEKDAY_8601 : - return 'N'; - break; - - case 'ee' : - return $this->_toComment(str_pad($this->date('N', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); - break; - - case self::DAY_SUFFIX : - return 'S'; - break; - - case self::WEEKDAY_DIGIT : - return 'w'; - break; - - case self::DAY_OF_YEAR : - return 'z'; - break; - - case 'DDD' : - return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 3, '0', STR_PAD_LEFT)); - break; - - case 'DD' : - return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); - break; - - case self::WEEKDAY_NARROW : - case 'EEEEE' : - $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); - $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday)); - return $this->_toComment(iconv_substr($day, 0, 1, 'UTF-8')); - break; - - case self::WEEKDAY_NAME : - $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday))); - break; - - case 'w' : - $week = $this->date('W', $this->getUnixTimestamp(), false); - return $this->_toComment(($week[0] == '0') ? $week[1] : $week); - break; - - case self::WEEK : - return 'W'; - break; - - case self::MONTH_NAME : - $month = $this->date('n', $this->getUnixTimestamp(), false); - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'wide', $month))); - break; - - case self::MONTH : - return 'm'; - break; - - case self::MONTH_NAME_SHORT : - $month = $this->date('n', $this->getUnixTimestamp(), false); - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month))); - break; - - case self::MONTH_SHORT : - return 'n'; - break; - - case self::MONTH_DAYS : - return 't'; - break; - - case self::MONTH_NAME_NARROW : - $month = $this->date('n', $this->getUnixTimestamp(), false); - $mon = Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month)); - return $this->_toComment(iconv_substr($mon, 0, 1, 'UTF-8')); - break; - - case self::LEAPYEAR : - return 'L'; - break; - - case self::YEAR_8601 : - return 'o'; - break; - - case self::YEAR : - return 'Y'; - break; - - case self::YEAR_SHORT : - return 'y'; - break; - - case self::YEAR_SHORT_8601 : - return $this->_toComment(substr($this->date('o', $this->getUnixTimestamp(), false), -2, 2)); - break; - - case self::MERIDIEM : - $am = $this->date('a', $this->getUnixTimestamp(), false); - if ($am == 'am') { - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'am')); - } - - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'pm')); - break; - - case self::SWATCH : - return 'B'; - break; - - case self::HOUR_SHORT_AM : - return 'g'; - break; - - case self::HOUR_SHORT : - return 'G'; - break; - - case self::HOUR_AM : - return 'h'; - break; - - case self::HOUR : - return 'H'; - break; - - case self::MINUTE : - return $this->_toComment(str_pad($this->date('i', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); - break; - - case self::SECOND : - return $this->_toComment(str_pad($this->date('s', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); - break; - - case self::MINUTE_SHORT : - return 'i'; - break; - - case self::SECOND_SHORT : - return 's'; - break; - - case self::MILLISECOND : - return $this->_toComment($this->getMilliSecond()); - break; - - case self::TIMEZONE_NAME : - case 'vvvv' : - return 'e'; - break; - - case self::DAYLIGHT : - return 'I'; - break; - - case self::GMT_DIFF : - case 'ZZ' : - case 'ZZZ' : - return 'O'; - break; - - case self::GMT_DIFF_SEP : - return 'P'; - break; - - case self::TIMEZONE : - case 'v' : - case 'zz' : - case 'zzz' : - return 'T'; - break; - - case self::TIMEZONE_SECS : - return 'Z'; - break; - - case self::ISO_8601 : - return 'c'; - break; - - case self::RFC_2822 : - return 'r'; - break; - - case self::TIMESTAMP : - return 'U'; - break; - - case self::ERA : - case 'GG' : - case 'GGG' : - $year = $this->date('Y', $this->getUnixTimestamp(), false); - if ($year < 0) { - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0'))); - } - - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1'))); - break; - - case self::ERA_NARROW : - $year = $this->date('Y', $this->getUnixTimestamp(), false); - if ($year < 0) { - return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0')), 0, 1, 'UTF-8')) . '.'; - } - - return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1')), 0, 1, 'UTF-8')) . '.'; - break; - - case self::ERA_NAME : - $year = $this->date('Y', $this->getUnixTimestamp(), false); - if ($year < 0) { - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '0'))); - } - - return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '1'))); - break; - - case self::DATES : - return $this->_toToken(Zend_Locale_Format::getDateFormat($locale), $locale); - break; - - case self::DATE_FULL : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')), $locale); - break; - - case self::DATE_LONG : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')), $locale); - break; - - case self::DATE_MEDIUM : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')), $locale); - break; - - case self::DATE_SHORT : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')), $locale); - break; - - case self::TIMES : - return $this->_toToken(Zend_Locale_Format::getTimeFormat($locale), $locale); - break; - - case self::TIME_FULL : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'full'), $locale); - break; - - case self::TIME_LONG : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'long'), $locale); - break; - - case self::TIME_MEDIUM : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'medium'), $locale); - break; - - case self::TIME_SHORT : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'short'), $locale); - break; - - case self::DATETIME : - return $this->_toToken(Zend_Locale_Format::getDateTimeFormat($locale), $locale); - break; - - case self::DATETIME_FULL : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')), $locale); - break; - - case self::DATETIME_LONG : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')), $locale); - break; - - case self::DATETIME_MEDIUM : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')), $locale); - break; - - case self::DATETIME_SHORT : - return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')), $locale); - break; - - case self::ATOM : - return 'Y\-m\-d\TH\:i\:sP'; - break; - - case self::COOKIE : - return 'l\, d\-M\-y H\:i\:s e'; - break; - - case self::RFC_822 : - return 'D\, d M y H\:i\:s O'; - break; - - case self::RFC_850 : - return 'l\, d\-M\-y H\:i\:s e'; - break; - - case self::RFC_1036 : - return 'D\, d M y H\:i\:s O'; - break; - - case self::RFC_1123 : - return 'D\, d M Y H\:i\:s O'; - break; - - case self::RFC_3339 : - return 'Y\-m\-d\TH\:i\:sP'; - break; - - case self::RSS : - return 'D\, d M Y H\:i\:s O'; - break; - - case self::W3C : - return 'Y\-m\-d\TH\:i\:sP'; - break; - } - - if ($token == '') { - return ''; - } - - switch ($token[0]) { - case 'y' : - if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { - return 'Y'; - } - - $length = iconv_strlen($token, 'UTF-8'); - return $this->_toComment(str_pad($this->date('Y', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); - break; - - case 'Y' : - if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { - return 'o'; - } - - $length = iconv_strlen($token, 'UTF-8'); - return $this->_toComment(str_pad($this->date('o', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); - break; - - case 'A' : - $length = iconv_strlen($token, 'UTF-8'); - $result = substr($this->getMilliSecond(), 0, 3); - $result += $this->date('s', $this->getUnixTimestamp(), false) * 1000; - $result += $this->date('i', $this->getUnixTimestamp(), false) * 60000; - $result += $this->date('H', $this->getUnixTimestamp(), false) * 3600000; - - return $this->_toComment(str_pad($result, $length, '0', STR_PAD_LEFT)); - break; - } - - return $this->_toComment($token); - } - - /** - * Private function to make a comment of a token - * - * @param string $token - * @return string - */ - private function _toComment($token) - { - $token = str_split($token); - $result = ''; - foreach ($token as $tok) { - $result .= '\\' . $tok; - } - - return $result; - } - - /** - * Return digit from standard names (english) - * Faster implementation than locale aware searching - * - * @param string $name - * @return integer Number of this month - * @throws Zend_Date_Exception - */ - private function _getDigitFromName($name) - { - switch($name) { - case "Jan": - return 1; - - case "Feb": - return 2; - - case "Mar": - return 3; - - case "Apr": - return 4; - - case "May": - return 5; - - case "Jun": - return 6; - - case "Jul": - return 7; - - case "Aug": - return 8; - - case "Sep": - return 9; - - case "Oct": - return 10; - - case "Nov": - return 11; - - case "Dec": - return 12; - - default: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('Month ($name) is not a known month'); - } - } - - /** - * Counts the exact year number - * < 70 - 2000 added, >70 < 100 - 1900, others just returned - * - * @param integer $value year number - * @return integer Number of year - */ - public static function getFullYear($value) - { - if ($value >= 0) { - if ($value < 70) { - $value += 2000; - } else if ($value < 100) { - $value += 1900; - } - } - return $value; - } - - /** - * Sets the given date as new date or a given datepart as new datepart returning the new datepart - * This could be for example a localized dayname, the date without time, - * the month or only the seconds. There are about 50 different supported date parts. - * For a complete list of supported datepart values look into the docu - * - * @param string|integer|array|Zend_Date $date Date or datepart to set - * @param string $part OPTIONAL Part of the date to set, if null the timestamp is set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function set($date, $part = null, $locale = null) - { - if (self::$_options['format_type'] == 'php') { - $part = Zend_Locale_Format::convertPhpToIsoFormat($part); - } - - $zone = $this->getTimezoneFromString($date); - $this->setTimezone($zone); - - $this->_calculate('set', $date, $part, $locale); - return $this; - } - - /** - * Adds a date or datepart to the existing date, by extracting $part from $date, - * and modifying this object by adding that part. The $part is then extracted from - * this object and returned as an integer or numeric string (for large values, or $part's - * corresponding to pre-defined formatted date strings). - * This could be for example a ISO 8601 date, the hour the monthname or only the minute. - * There are about 50 different supported date parts. - * For a complete list of supported datepart values look into the docu. - * - * @param string|integer|array|Zend_Date $date Date or datepart to add - * @param string $part OPTIONAL Part of the date to add, if null the timestamp is added - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function add($date, $part = self::TIMESTAMP, $locale = null) - { - if (self::$_options['format_type'] == 'php') { - $part = Zend_Locale_Format::convertPhpToIsoFormat($part); - } - - $this->_calculate('add', $date, $part, $locale); - return $this; - } - - /** - * Subtracts a date from another date. - * This could be for example a RFC2822 date, the time, - * the year or only the timestamp. There are about 50 different supported date parts. - * For a complete list of supported datepart values look into the docu - * Be aware: Adding -2 Months is not equal to Subtracting 2 Months !!! - * - * @param string|integer|array|Zend_Date $date Date or datepart to subtract - * @param string $part OPTIONAL Part of the date to sub, if null the timestamp is subtracted - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function sub($date, $part = self::TIMESTAMP, $locale = null) - { - if (self::$_options['format_type'] == 'php') { - $part = Zend_Locale_Format::convertPhpToIsoFormat($part); - } - - $this->_calculate('sub', $date, $part, $locale); - return $this; - } - - /** - * Compares a date or datepart with the existing one. - * Returns -1 if earlier, 0 if equal and 1 if later. - * - * @param string|integer|array|Zend_Date $date Date or datepart to compare with the date object - * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is subtracted - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compare($date, $part = self::TIMESTAMP, $locale = null) - { - if (self::$_options['format_type'] == 'php') { - $part = Zend_Locale_Format::convertPhpToIsoFormat($part); - } - - $compare = $this->_calculate('cmp', $date, $part, $locale); - - if ($compare > 0) { - return 1; - } else if ($compare < 0) { - return -1; - } - return 0; - } - - /** - * Returns a new instance of Zend_Date with the selected part copied. - * To make an exact copy, use PHP's clone keyword. - * For a complete list of supported date part values look into the docu. - * If a date part is copied, all other date parts are set to standard values. - * For example: If only YEAR is copied, the returned date object is equal to - * 01-01-YEAR 00:00:00 (01-01-1970 00:00:00 is equal to timestamp 0) - * If only HOUR is copied, the returned date object is equal to - * 01-01-1970 HOUR:00:00 (so $this contains a timestamp equal to a timestamp of 0 plus HOUR). - * - * @param string $part Part of the date to compare, if null the timestamp is subtracted - * @param string|Zend_Locale $locale OPTIONAL New object's locale. No adjustments to timezone are made. - * @return Zend_Date New clone with requested part - */ - public function copyPart($part, $locale = null) - { - $clone = clone $this; // copy all instance variables - $clone->setUnixTimestamp(0); // except the timestamp - if ($locale != null) { - $clone->setLocale($locale); // set an other locale if selected - } - $clone->set($this, $part); - return $clone; - } - - /** - * Internal function, returns the offset of a given timezone - * - * @param string $zone - * @return integer - */ - public function getTimezoneFromString($zone) - { - if (is_array($zone)) { - return $this->getTimezone(); - } - - if ($zone instanceof Zend_Date) { - return $zone->getTimezone(); - } - - $match = array(); - preg_match('/\dZ$/', $zone, $match); - if (!empty($match)) { - return "Etc/UTC"; - } - - preg_match('/([+-]\d{2}):{0,1}\d{2}/', $zone, $match); - if (!empty($match) and ($match[count($match) - 1] <= 14) and ($match[count($match) - 1] >= -12)) { - $zone = "Etc/GMT"; - $zone .= ($match[count($match) - 1] < 0) ? "+" : "-"; - $zone .= (int) abs($match[count($match) - 1]); - return $zone; - } - - preg_match('/([[:alpha:]\/_]{3,30})(?!.*([[:alpha:]\/]{3,30}))/', $zone, $match); - try { - if (!empty($match) and (!is_int($match[count($match) - 1]))) { - $oldzone = $this->getTimezone(); - $this->setTimezone($match[count($match) - 1]); - $result = $this->getTimezone(); - $this->setTimezone($oldzone); - if ($result !== $oldzone) { - return $match[count($match) - 1]; - } - } - } catch (Exception $e) { - // fall through - } - - return $this->getTimezone(); - } - - /** - * Calculates the date or object - * - * @param string $calc Calculation to make - * @param string|integer $date Date for calculation - * @param string|integer $comp Second date for calculation - * @param boolean|integer $dst Use dst correction if option is set - * @return integer|string|Zend_Date new timestamp or Zend_Date depending on calculation - */ - private function _assign($calc, $date, $comp = 0, $dst = false) - { - switch ($calc) { - case 'set' : - if (!empty($comp)) { - $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $comp)); - } - $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); - $value = $this->getUnixTimestamp(); - break; - case 'add' : - $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); - $value = $this->getUnixTimestamp(); - break; - case 'sub' : - $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $date)); - $value = $this->getUnixTimestamp(); - break; - default : - // cmp - compare - return call_user_func(Zend_Locale_Math::$comp, $comp, $date); - break; - } - - // dst-correction if 'fix_dst' = true and dst !== false but only for non UTC and non GMT - if ((self::$_options['fix_dst'] === true) and ($dst !== false) and ($this->_dst === true)) { - $hour = $this->toString(self::HOUR, 'iso'); - if ($hour != $dst) { - if (($dst == ($hour + 1)) || ($dst == ($hour - 23))) { - $value += 3600; - } else if (($dst == ($hour - 1)) || ($dst == ($hour + 23))) { - $value -= 3600; - } - $this->setUnixTimestamp($value); - } - } - return $this->getUnixTimestamp(); - } - - - /** - * Calculates the date or object - * - * @param string $calc Calculation to make, one of: 'add'|'sub'|'cmp'|'copy'|'set' - * @param string|integer|array|Zend_Date $date Date or datepart to calculate with - * @param string $part Part of the date to calculate, if null the timestamp is used - * @param string|Zend_Locale $locale Locale for parsing input - * @return integer|string|Zend_Date new timestamp - * @throws Zend_Date_Exception - */ - private function _calculate($calc, $date, $part, $locale) - { - if ($date === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); - } - - if (($part !== null) && (strlen($part) !== 2) && (Zend_Locale::isLocale($part, null, false))) { - $locale = $part; - $part = null; - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - $locale = (string) $locale; - - // Create date parts - $year = $this->toString(self::YEAR, 'iso'); - $month = $this->toString(self::MONTH_SHORT, 'iso'); - $day = $this->toString(self::DAY_SHORT, 'iso'); - $hour = $this->toString(self::HOUR_SHORT, 'iso'); - $minute = $this->toString(self::MINUTE_SHORT, 'iso'); - $second = $this->toString(self::SECOND_SHORT, 'iso'); - // If object extract value - if ($date instanceof Zend_Date) { - $date = $date->toString($part, 'iso', $locale); - } - - if (is_array($date) === true) { - if (empty($part) === false) { - switch($part) { - // Fall through - case self::DAY: - case self::DAY_SHORT: - if (isset($date['day']) === true) { - $date = $date['day']; - } - break; - // Fall through - case self::WEEKDAY_SHORT: - case self::WEEKDAY: - case self::WEEKDAY_8601: - case self::WEEKDAY_DIGIT: - case self::WEEKDAY_NARROW: - case self::WEEKDAY_NAME: - if (isset($date['weekday']) === true) { - $date = $date['weekday']; - $part = self::WEEKDAY_DIGIT; - } - break; - case self::DAY_OF_YEAR: - if (isset($date['day_of_year']) === true) { - $date = $date['day_of_year']; - } - break; - // Fall through - case self::MONTH: - case self::MONTH_SHORT: - case self::MONTH_NAME: - case self::MONTH_NAME_SHORT: - case self::MONTH_NAME_NARROW: - if (isset($date['month']) === true) { - $date = $date['month']; - } - break; - // Fall through - case self::YEAR: - case self::YEAR_SHORT: - case self::YEAR_8601: - case self::YEAR_SHORT_8601: - if (isset($date['year']) === true) { - $date = $date['year']; - } - break; - // Fall through - case self::HOUR: - case self::HOUR_AM: - case self::HOUR_SHORT: - case self::HOUR_SHORT_AM: - if (isset($date['hour']) === true) { - $date = $date['hour']; - } - break; - // Fall through - case self::MINUTE: - case self::MINUTE_SHORT: - if (isset($date['minute']) === true) { - $date = $date['minute']; - } - break; - // Fall through - case self::SECOND: - case self::SECOND_SHORT: - if (isset($date['second']) === true) { - $date = $date['second']; - } - break; - // Fall through - case self::TIMEZONE: - case self::TIMEZONE_NAME: - if (isset($date['timezone']) === true) { - $date = $date['timezone']; - } - break; - case self::TIMESTAMP: - if (isset($date['timestamp']) === true) { - $date = $date['timestamp']; - } - break; - case self::WEEK: - if (isset($date['week']) === true) { - $date = $date['week']; - } - break; - case self::TIMEZONE_SECS: - if (isset($date['gmtsecs']) === true) { - $date = $date['gmtsecs']; - } - break; - default: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("datepart for part ($part) not found in array"); - break; - } - } else { - $hours = 0; - if (isset($date['hour']) === true) { - $hours = $date['hour']; - } - $minutes = 0; - if (isset($date['minute']) === true) { - $minutes = $date['minute']; - } - $seconds = 0; - if (isset($date['second']) === true) { - $seconds = $date['second']; - } - $months = 0; - if (isset($date['month']) === true) { - $months = $date['month']; - } - $days = 0; - if (isset($date['day']) === true) { - $days = $date['day']; - } - $years = 0; - if (isset($date['year']) === true) { - $years = $date['year']; - } - return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour); - } - } - - // $date as object, part of foreign date as own date - switch($part) { - - // day formats - case self::DAY: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), - $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); - break; - - case self::WEEKDAY_SHORT: - $daylist = Zend_Locale_Data::getList($locale, 'day'); - $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); - $cnt = 0; - - foreach ($daylist as $key => $value) { - if (strtoupper(iconv_substr($value, 0, 3, 'UTF-8')) == strtoupper($date)) { - $found = $cnt; - break; - } - ++$cnt; - } - - // Weekday found - if ($cnt < 7) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - case self::DAY_SHORT: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), - $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); - break; - - case self::WEEKDAY: - $daylist = Zend_Locale_Data::getList($locale, 'day'); - $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); - $cnt = 0; - - foreach ($daylist as $key => $value) { - if (strtoupper($value) == strtoupper($date)) { - $found = $cnt; - break; - } - ++$cnt; - } - - // Weekday found - if ($cnt < 7) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - case self::WEEKDAY_8601: - $weekday = (int) $this->toString(self::WEEKDAY_8601, 'iso', $locale); - if ((intval($date) > 0) and (intval($date) < 8)) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - case self::DAY_SUFFIX: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('day suffix not supported', 0, null, $date); - break; - - case self::WEEKDAY_DIGIT: - $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); - if (is_numeric($date) and (intval($date) >= 0) and (intval($date) < 7)) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - case self::DAY_OF_YEAR: - if (is_numeric($date)) { - if (($calc == 'add') || ($calc == 'sub')) { - $year = 1970; - ++$date; - ++$day; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, $date, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); - break; - - case self::WEEKDAY_NARROW: - $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); - $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); - $cnt = 0; - foreach ($daylist as $key => $value) { - if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($date)) { - $found = $cnt; - break; - } - ++$cnt; - } - - // Weekday found - if ($cnt < 7) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - case self::WEEKDAY_NAME: - $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); - $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); - $cnt = 0; - foreach ($daylist as $key => $value) { - if (strtoupper($value) == strtoupper($date)) { - $found = $cnt; - break; - } - ++$cnt; - } - - // Weekday found - if ($cnt < 7) { - return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), - $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); - } - - // Weekday not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); - break; - - // week formats - case self::WEEK: - if (is_numeric($date)) { - $week = (int) $this->toString(self::WEEK, 'iso', $locale); - return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + ($date * 7), 1970, true), - parent::mktime(0, 0, 0, 1, 1 + ($week * 7), 1970, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, week expected", 0, null, $date); - break; - - // month formats - case self::MONTH_NAME: - $monthlist = Zend_Locale_Data::getList($locale, 'month'); - $cnt = 0; - foreach ($monthlist as $key => $value) { - if (strtoupper($value) == strtoupper($date)) { - $found = $key; - break; - } - ++$cnt; - } - $date = array_search($date, $monthlist); - - // Monthname found - if ($cnt < 12) { - $fixday = 0; - if ($calc == 'add') { - $date += $found; - $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } else if ($calc == 'sub') { - $date = $month - $found; - $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } - return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - // Monthname not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); - break; - - case self::MONTH: - if (is_numeric($date)) { - $fixday = 0; - if ($calc == 'add') { - $date += $month; - $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } else if ($calc == 'sub') { - $date = $month - $date; - $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } - return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); - break; - - case self::MONTH_NAME_SHORT: - $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); - $cnt = 0; - foreach ($monthlist as $key => $value) { - if (strtoupper($value) == strtoupper($date)) { - $found = $key; - break; - } - ++$cnt; - } - $date = array_search($date, $monthlist); - - // Monthname found - if ($cnt < 12) { - $fixday = 0; - if ($calc == 'add') { - $date += $found; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } else if ($calc == 'sub') { - $date = $month - $found; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } - return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - // Monthname not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); - break; - - case self::MONTH_SHORT: - if (is_numeric($date) === true) { - $fixday = 0; - if ($calc === 'add') { - $date += $month; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } else if ($calc === 'sub') { - $date = $month - $date; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); - break; - - case self::MONTH_DAYS: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('month days not supported', 0, null, $date); - break; - - case self::MONTH_NAME_NARROW: - $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'stand-alone', 'narrow')); - $cnt = 0; - foreach ($monthlist as $key => $value) { - if (strtoupper($value) === strtoupper($date)) { - $found = $key; - break; - } - ++$cnt; - } - $date = array_search($date, $monthlist); - - // Monthname found - if ($cnt < 12) { - $fixday = 0; - if ($calc === 'add') { - $date += $found; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } else if ($calc === 'sub') { - $date = $month - $found; - $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } - } - return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); - } - - // Monthname not found - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); - break; - - // year formats - case self::LEAPYEAR: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('leap year not supported', 0, null, $date); - break; - - case self::YEAR_8601: - if (is_numeric($date)) { - if ($calc === 'add') { - $date += $year; - $calc = 'set'; - } else if ($calc === 'sub') { - $date = $year - $date; - $calc = 'set'; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), - $this->mktime(0, 0, 0, $month, $day, $year, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); - break; - - case self::YEAR: - if (is_numeric($date)) { - if ($calc === 'add') { - $date += $year; - $calc = 'set'; - } else if ($calc === 'sub') { - $date = $year - $date; - $calc = 'set'; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), - $this->mktime(0, 0, 0, $month, $day, $year, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); - break; - - case self::YEAR_SHORT: - if (is_numeric($date)) { - $date = intval($date); - if (($calc == 'set') || ($calc == 'cmp')) { - $date = self::getFullYear($date); - } - if ($calc === 'add') { - $date += $year; - $calc = 'set'; - } else if ($calc === 'sub') { - $date = $year - $date; - $calc = 'set'; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); - break; - - case self::YEAR_SHORT_8601: - if (is_numeric($date)) { - $date = intval($date); - if (($calc === 'set') || ($calc === 'cmp')) { - $date = self::getFullYear($date); - } - if ($calc === 'add') { - $date += $year; - $calc = 'set'; - } else if ($calc === 'sub') { - $date = $year - $date; - $calc = 'set'; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), - $this->mktime(0, 0, 0, $month, $day, $year, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); - break; - - // time formats - case self::MERIDIEM: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('meridiem not supported', 0, null, $date); - break; - - case self::SWATCH: - if (is_numeric($date)) { - $rest = intval($date); - $hours = floor($rest * 24 / 1000); - $rest = $rest - ($hours * 1000 / 24); - $minutes = floor($rest * 1440 / 1000); - $rest = $rest - ($minutes * 1000 / 1440); - $seconds = floor($rest * 86400 / 1000); - return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true), - $this->mktime($hour, $minute, $second, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, swatchstamp expected", 0, null, $date); - break; - - case self::HOUR_SHORT_AM: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), - $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); - break; - - case self::HOUR_SHORT: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), - $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); - break; - - case self::HOUR_AM: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), - $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); - break; - - case self::HOUR: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), - $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); - break; - - case self::MINUTE: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), - $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); - break; - - case self::SECOND: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), - $this->mktime(0, 0, $second, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); - break; - - case self::MILLISECOND: - if (is_numeric($date)) { - switch($calc) { - case 'set' : - return $this->setMillisecond($date); - break; - case 'add' : - return $this->addMillisecond($date); - break; - case 'sub' : - return $this->subMillisecond($date); - break; - } - - return $this->compareMillisecond($date); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, milliseconds expected", 0, null, $date); - break; - - case self::MINUTE_SHORT: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), - $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); - break; - - case self::SECOND_SHORT: - if (is_numeric($date)) { - return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), - $this->mktime(0, 0, $second, 1, 1, 1970, true), false); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); - break; - - // timezone formats - // break intentionally omitted - case self::TIMEZONE_NAME: - case self::TIMEZONE: - case self::TIMEZONE_SECS: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('timezone not supported', 0, null, $date); - break; - - case self::DAYLIGHT: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('daylight not supported', 0, null, $date); - break; - - case self::GMT_DIFF: - case self::GMT_DIFF_SEP: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('gmtdiff not supported', 0, null, $date); - break; - - // date strings - case self::ISO_8601: - // (-)YYYY-MM-dd - preg_match('/^(-{0,1}\d{4})-(\d{2})-(\d{2})/', $date, $datematch); - // (-)YY-MM-dd - if (empty($datematch)) { - preg_match('/^(-{0,1}\d{2})-(\d{2})-(\d{2})/', $date, $datematch); - } - // (-)YYYYMMdd - if (empty($datematch)) { - preg_match('/^(-{0,1}\d{4})(\d{2})(\d{2})/', $date, $datematch); - } - // (-)YYMMdd - if (empty($datematch)) { - preg_match('/^(-{0,1}\d{2})(\d{2})(\d{2})/', $date, $datematch); - } - $tmpdate = $date; - if (!empty($datematch)) { - $dateMatchCharCount = iconv_strlen($datematch[0], 'UTF-8'); - $tmpdate = iconv_substr($date, - $dateMatchCharCount, - iconv_strlen($date, 'UTF-8') - $dateMatchCharCount, - 'UTF-8'); - } - // (T)hh:mm:ss - preg_match('/[T,\s]{0,1}(\d{2}):(\d{2}):(\d{2})/', $tmpdate, $timematch); - // (T)hhmmss - if (empty($timematch)) { - preg_match('/[T,\s]{0,1}(\d{2})(\d{2})(\d{2})/', $tmpdate, $timematch); - } - // (T)hh:mm - if (empty($timematch)) { - preg_match('/[T,\s]{0,1}(\d{2}):(\d{2})/', $tmpdate, $timematch); - } - // (T)hhmm - if (empty($timematch)) { - preg_match('/[T,\s]{0,1}(\d{2})(\d{2})/', $tmpdate, $timematch); - } - if (empty($datematch) and empty($timematch)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("unsupported ISO8601 format ($date)", 0, null, $date); - } - if (!empty($timematch)) { - $timeMatchCharCount = iconv_strlen($timematch[0], 'UTF-8'); - $tmpdate = iconv_substr($tmpdate, - $timeMatchCharCount, - iconv_strlen($tmpdate, 'UTF-8') - $timeMatchCharCount, - 'UTF-8'); - } - if (empty($datematch)) { - $datematch[1] = 1970; - $datematch[2] = 1; - $datematch[3] = 1; - } else if (iconv_strlen($datematch[1], 'UTF-8') == 2) { - $datematch[1] = self::getFullYear($datematch[1]); - } - if (empty($timematch)) { - $timematch[1] = 0; - $timematch[2] = 0; - $timematch[3] = 0; - } - if (!isset($timematch[3])) { - $timematch[3] = 0; - } - - if (($calc == 'set') || ($calc == 'cmp')) { - --$datematch[2]; - --$month; - --$datematch[3]; - --$day; - $datematch[1] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($timematch[1], $timematch[2], $timematch[3], 1 + $datematch[2], 1 + $datematch[3], 1970 + $datematch[1], false), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); - break; - - case self::RFC_2822: - $result = preg_match('/^\w{3},\s(\d{1,2})\s(\w{3})\s(\d{4})\s' - . '(\d{2}):(\d{2}):{0,1}(\d{0,2})\s([+-]' - . '{1}\d{4}|\w{1,20})$/', $date, $match); - - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no RFC 2822 format ($date)", 0, null, $date); - } - - $months = $this->_getDigitFromName($match[2]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); - break; - - case self::TIMESTAMP: - if (is_numeric($date)) { - return $this->_assign($calc, $date, $this->getUnixTimestamp()); - } - - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, timestamp expected", 0, null, $date); - break; - - // additional formats - // break intentionally omitted - case self::ERA: - case self::ERA_NAME: - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('era not supported', 0, null, $date); - break; - - case self::DATES: - try { - $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - - return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATE_FULL: - try { - $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATE_LONG: - try { - $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - if (($calc == 'set') || ($calc == 'cmp')){ - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATE_MEDIUM: - try { - $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATE_SHORT: - try { - $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - $parsed['year'] = self::getFullYear($parsed['year']); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::TIMES: - try { - if ($calc != 'set') { - $month = 1; - $day = 1; - $year = 1970; - } - $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::TIME_FULL: - try { - $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); - $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - if ($calc != 'set') { - $month = 1; - $day = 1; - $year = 1970; - } - - if (!isset($parsed['second'])) { - $parsed['second'] = 0; - } - - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::TIME_LONG: - try { - $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); - $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - if ($calc != 'set') { - $month = 1; - $day = 1; - $year = 1970; - } - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::TIME_MEDIUM: - try { - $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); - $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - if ($calc != 'set') { - $month = 1; - $day = 1; - $year = 1970; - } - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::TIME_SHORT: - try { - $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); - $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - if ($calc != 'set') { - $month = 1; - $day = 1; - $year = 1970; - } - - if (!isset($parsed['second'])) { - $parsed['second'] = 0; - } - - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), - $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATETIME: - try { - $parsed = Zend_Locale_Format::getDateTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATETIME_FULL: - try { - $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); - $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - - if (!isset($parsed['second'])) { - $parsed['second'] = 0; - } - - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATETIME_LONG: - try { - $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); - $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - if (($calc == 'set') || ($calc == 'cmp')){ - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATETIME_MEDIUM: - try { - $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); - $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - case self::DATETIME_SHORT: - try { - $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); - $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); - - $parsed['year'] = self::getFullYear($parsed['year']); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$parsed['month']; - --$month; - --$parsed['day']; - --$day; - $parsed['year'] -= 1970; - $year -= 1970; - } - - if (!isset($parsed['second'])) { - $parsed['second'] = 0; - } - - return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - break; - - // ATOM and RFC_3339 are identical - case self::ATOM: - case self::RFC_3339: - $result = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\d{0,4}([+-]{1}\d{2}:\d{2}|Z)$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, ATOM format expected", 0, null, $date); - } - - if (($calc == 'set') || ($calc == 'cmp')) { - --$match[2]; - --$month; - --$match[3]; - --$day; - $match[1] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - case self::COOKIE: - $result = preg_match("/^\w{6,9},\s(\d{2})-(\w{3})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})\s.{3,20}$/", $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, COOKIE format expected", 0, null, $date); - } - $matchStartPos = iconv_strpos($match[0], ' ', 0, 'UTF-8') + 1; - $match[0] = iconv_substr($match[0], - $matchStartPos, - iconv_strlen($match[0], 'UTF-8') - $matchStartPos, - 'UTF-8'); - - $months = $this->_getDigitFromName($match[2]); - $match[3] = self::getFullYear($match[3]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - case self::RFC_822: - case self::RFC_1036: - // new RFC 822 format, identical to RFC 1036 standard - $result = preg_match('/^\w{0,3},{0,1}\s{0,1}(\d{1,2})\s(\w{3})\s(\d{2})\s(\d{2}):(\d{2}):{0,1}(\d{0,2})\s([+-]{1}\d{4}|\w{1,20})$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, RFC 822 date format expected", 0, null, $date); - } - - $months = $this->_getDigitFromName($match[2]); - $match[3] = self::getFullYear($match[3]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); - break; - - case self::RFC_850: - $result = preg_match('/^\w{6,9},\s(\d{2})-(\w{3})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})\s.{3,21}$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, RFC 850 date format expected", 0, null, $date); - } - - $months = $this->_getDigitFromName($match[2]); - $match[3] = self::getFullYear($match[3]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - case self::RFC_1123: - $result = preg_match('/^\w{0,3},{0,1}\s{0,1}(\d{1,2})\s(\w{3})\s(\d{2,4})\s(\d{2}):(\d{2}):{0,1}(\d{0,2})\s([+-]{1}\d{4}|\w{1,20})$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, RFC 1123 date format expected", 0, null, $date); - } - - $months = $this->_getDigitFromName($match[2]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - case self::RSS: - $result = preg_match('/^\w{3},\s(\d{2})\s(\w{3})\s(\d{2,4})\s(\d{1,2}):(\d{2}):(\d{2})\s.{1,21}$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, RSS date format expected", 0, null, $date); - } - - $months = $this->_getDigitFromName($match[2]); - $match[3] = self::getFullYear($match[3]); - - if (($calc == 'set') || ($calc == 'cmp')) { - --$months; - --$month; - --$match[1]; - --$day; - $match[3] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - case self::W3C: - $result = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})[+-]{1}\d{2}:\d{2}$/', $date, $match); - if (!$result) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid date ($date) operand, W3C date format expected", 0, null, $date); - } - - if (($calc == 'set') || ($calc == 'cmp')) { - --$match[2]; - --$month; - --$match[3]; - --$day; - $match[1] -= 1970; - $year -= 1970; - } - return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), - $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); - break; - - default: - if (!is_numeric($date) || !empty($part)) { - try { - if (empty($part)) { - $part = Zend_Locale_Format::getDateFormat($locale) . " "; - $part .= Zend_Locale_Format::getTimeFormat($locale); - } - - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso')); - if ((strpos(strtoupper($part), 'YY') !== false) and (strpos(strtoupper($part), 'YYYY') === false)) { - $parsed['year'] = self::getFullYear($parsed['year']); - } - - if (($calc == 'set') || ($calc == 'cmp')) { - if (isset($parsed['month'])) { - --$parsed['month']; - } else { - $parsed['month'] = 0; - } - - if (isset($parsed['day'])) { - --$parsed['day']; - } else { - $parsed['day'] = 0; - } - - if (!isset($parsed['year'])) { - $parsed['year'] = 1970; - } - } - - return $this->_assign($calc, $this->mktime( - isset($parsed['hour']) ? $parsed['hour'] : 0, - isset($parsed['minute']) ? $parsed['minute'] : 0, - isset($parsed['second']) ? $parsed['second'] : 0, - isset($parsed['month']) ? (1 + $parsed['month']) : 1, - isset($parsed['day']) ? (1 + $parsed['day']) : 1, - $parsed['year'], - false), $this->getUnixTimestamp(), false); - } catch (Zend_Locale_Exception $e) { - if (!is_numeric($date)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); - } - } - } - - return $this->_assign($calc, $date, $this->getUnixTimestamp(), false); - break; - } - } - - /** - * Returns true when both date objects or date parts are equal. - * For example: - * 15.May.2000 <-> 15.June.2000 Equals only for Day or Year... all other will return false - * - * @param string|integer|array|Zend_Date $date Date or datepart to equal with - * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return boolean - * @throws Zend_Date_Exception - */ - public function equals($date, $part = self::TIMESTAMP, $locale = null) - { - $result = $this->compare($date, $part, $locale); - - if ($result == 0) { - return true; - } - - return false; - } - - /** - * Returns if the given date or datepart is earlier - * For example: - * 15.May.2000 <-> 13.June.1999 will return true for day, year and date, but not for month - * - * @param string|integer|array|Zend_Date $date Date or datepart to compare with - * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return boolean - * @throws Zend_Date_Exception - */ - public function isEarlier($date, $part = null, $locale = null) - { - $result = $this->compare($date, $part, $locale); - - if ($result == -1) { - return true; - } - - return false; - } - - /** - * Returns if the given date or datepart is later - * For example: - * 15.May.2000 <-> 13.June.1999 will return true for month but false for day, year and date - * Returns if the given date is later - * - * @param string|integer|array|Zend_Date $date Date or datepart to compare with - * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return boolean - * @throws Zend_Date_Exception - */ - public function isLater($date, $part = null, $locale = null) - { - $result = $this->compare($date, $part, $locale); - - if ($result == 1) { - return true; - } - - return false; - } - - /** - * Returns only the time of the date as new Zend_Date object - * For example: - * 15.May.2000 10:11:23 will return a dateobject equal to 01.Jan.1970 10:11:23 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getTime($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'H:i:s'; - } else { - $format = self::TIME_MEDIUM; - } - - return $this->copyPart($format, $locale); - } - - /** - * Returns the calculated time - * - * @param string $calc Calculation to make - * @param string|integer|array|Zend_Date $time Time to calculate with, if null the actual time is taken - * @param string $format Timeformat for parsing input - * @param string|Zend_Locale $locale Locale for parsing input - * @return integer|Zend_Date new time - * @throws Zend_Date_Exception - */ - private function _time($calc, $time, $format, $locale) - { - if ($time === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $time must be set, null is not allowed'); - } - - if ($time instanceof Zend_Date) { - // extract time from object - $time = $time->toString('HH:mm:ss', 'iso'); - } else { - if (is_array($time)) { - if ((isset($time['hour']) === true) || (isset($time['minute']) === true) or - (isset($time['second']) === true)) { - $parsed = $time; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no hour, minute or second given in array"); - } - } else { - if (self::$_options['format_type'] == 'php') { - $format = Zend_Locale_Format::convertPhpToIsoFormat($format); - } - try { - if ($locale === null) { - $locale = $this->getLocale(); - } - - $parsed = Zend_Locale_Format::getTime($time, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e); - } - } - - if (!array_key_exists('hour', $parsed)) { - $parsed['hour'] = 0; - } - - if (!array_key_exists('minute', $parsed)) { - $parsed['minute'] = 0; - } - - if (!array_key_exists('second', $parsed)) { - $parsed['second'] = 0; - } - - $time = str_pad($parsed['hour'], 2, '0', STR_PAD_LEFT) . ":"; - $time .= str_pad($parsed['minute'], 2, '0', STR_PAD_LEFT) . ":"; - $time .= str_pad($parsed['second'], 2, '0', STR_PAD_LEFT); - } - - $return = $this->_calcdetail($calc, $time, self::TIMES, 'de'); - if ($calc != 'cmp') { - return $this; - } - - return $return; - } - - - /** - * Sets a new time for the date object. Format defines how to parse the time string. - * Also a complete date can be given, but only the time is used for setting. - * For example: dd.MMMM.yyTHH:mm' and 'ss sec'-> 10.May.07T25:11 and 44 sec => 1h11min44sec + 1 day - * Returned is the new date object and the existing date is left as it was before - * - * @param string|integer|array|Zend_Date $time Time to set - * @param string $format OPTIONAL Timeformat for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setTime($time, $format = null, $locale = null) - { - return $this->_time('set', $time, $format, $locale); - } - - - /** - * Adds a time to the existing date. Format defines how to parse the time string. - * If only parts are given the other parts are set to 0. - * If no format is given, the standardformat of this locale is used. - * For example: HH:mm:ss -> 10 -> +10 hours - * - * @param string|integer|array|Zend_Date $time Time to add - * @param string $format OPTIONAL Timeformat for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addTime($time, $format = null, $locale = null) - { - return $this->_time('add', $time, $format, $locale); - } - - - /** - * Subtracts a time from the existing date. Format defines how to parse the time string. - * If only parts are given the other parts are set to 0. - * If no format is given, the standardformat of this locale is used. - * For example: HH:mm:ss -> 10 -> -10 hours - * - * @param string|integer|array|Zend_Date $time Time to sub - * @param string $format OPTIONAL Timeformat for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent inteface - * @throws Zend_Date_Exception - */ - public function subTime($time, $format = null, $locale = null) - { - return $this->_time('sub', $time, $format, $locale); - } - - - /** - * Compares the time from the existing date. Format defines how to parse the time string. - * If only parts are given the other parts are set to default. - * If no format us given, the standardformat of this locale is used. - * For example: HH:mm:ss -> 10 -> 10 hours - * - * @param string|integer|array|Zend_Date $time Time to compare - * @param string $format OPTIONAL Timeformat for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareTime($time, $format = null, $locale = null) - { - return $this->_time('cmp', $time, $format, $locale); - } - - /** - * Returns a clone of $this, with the time part set to 00:00:00. - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getDate($locale = null) - { - $orig = self::$_options['format_type']; - if (self::$_options['format_type'] == 'php') { - self::$_options['format_type'] = 'iso'; - } - - $date = $this->copyPart(self::DATE_MEDIUM, $locale); - $date->addTimestamp($this->getGmtOffset()); - self::$_options['format_type'] = $orig; - - return $date; - } - - /** - * Returns the calculated date - * - * @param string $calc Calculation to make - * @param string|integer|array|Zend_Date $date Date to calculate with, if null the actual date is taken - * @param string $format Date format for parsing - * @param string|Zend_Locale $locale Locale for parsing input - * @return integer|Zend_Date new date - * @throws Zend_Date_Exception - */ - private function _date($calc, $date, $format, $locale) - { - if ($date === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); - } - - if ($date instanceof Zend_Date) { - // extract date from object - $date = $date->toString('d.M.y', 'iso'); - } else { - if (is_array($date)) { - if ((isset($date['year']) === true) || (isset($date['month']) === true) or - (isset($date['day']) === true)) { - $parsed = $date; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no day,month or year given in array"); - } - } else { - if ((self::$_options['format_type'] == 'php') && !defined($format)) { - $format = Zend_Locale_Format::convertPhpToIsoFormat($format); - } - try { - if ($locale === null) { - $locale = $this->getLocale(); - } - - $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); - if ((strpos(strtoupper($format), 'YY') !== false) and (strpos(strtoupper($format), 'YYYY') === false)) { - $parsed['year'] = self::getFullYear($parsed['year']); - } - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e); - } - } - - if (!array_key_exists('day', $parsed)) { - $parsed['day'] = 1; - } - - if (!array_key_exists('month', $parsed)) { - $parsed['month'] = 1; - } - - if (!array_key_exists('year', $parsed)) { - $parsed['year'] = 0; - } - - $date = $parsed['day'] . "." . $parsed['month'] . "." . $parsed['year']; - } - - $return = $this->_calcdetail($calc, $date, self::DATE_MEDIUM, 'de'); - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - - /** - * Sets a new date for the date object. Format defines how to parse the date string. - * Also a complete date with time can be given, but only the date is used for setting. - * For example: MMMM.yy HH:mm-> May.07 22:11 => 01.May.07 00:00 - * Returned is the new date object and the existing time is left as it was before - * - * @param string|integer|array|Zend_Date $date Date to set - * @param string $format OPTIONAL Date format for parsing - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setDate($date, $format = null, $locale = null) - { - return $this->_date('set', $date, $format, $locale); - } - - - /** - * Adds a date to the existing date object. Format defines how to parse the date string. - * If only parts are given the other parts are set to 0. - * If no format is given, the standardformat of this locale is used. - * For example: MM.dd.YYYY -> 10 -> +10 months - * - * @param string|integer|array|Zend_Date $date Date to add - * @param string $format OPTIONAL Date format for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addDate($date, $format = null, $locale = null) - { - return $this->_date('add', $date, $format, $locale); - } - - - /** - * Subtracts a date from the existing date object. Format defines how to parse the date string. - * If only parts are given the other parts are set to 0. - * If no format is given, the standardformat of this locale is used. - * For example: MM.dd.YYYY -> 10 -> -10 months - * Be aware: Subtracting 2 months is not equal to Adding -2 months !!! - * - * @param string|integer|array|Zend_Date $date Date to sub - * @param string $format OPTIONAL Date format for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subDate($date, $format = null, $locale = null) - { - return $this->_date('sub', $date, $format, $locale); - } - - - /** - * Compares the date from the existing date object, ignoring the time. - * Format defines how to parse the date string. - * If only parts are given the other parts are set to 0. - * If no format is given, the standardformat of this locale is used. - * For example: 10.01.2000 => 10.02.1999 -> false - * - * @param string|integer|array|Zend_Date $date Date to compare - * @param string $format OPTIONAL Date format for parsing input - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareDate($date, $format = null, $locale = null) - { - return $this->_date('cmp', $date, $format, $locale); - } - - - /** - * Returns the full ISO 8601 date from the date object. - * Always the complete ISO 8601 specifiction is used. If an other ISO date is needed - * (ISO 8601 defines several formats) use toString() instead. - * This function does not return the ISO date as object. Use copy() instead. - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return string - */ - public function getIso($locale = null) - { - return $this->toString(self::ISO_8601, 'iso', $locale); - } - - - /** - * Sets a new date for the date object. Not given parts are set to default. - * Only supported ISO 8601 formats are accepted. - * For example: 050901 -> 01.Sept.2005 00:00:00, 20050201T10:00:30 -> 01.Feb.2005 10h00m30s - * Returned is the new date object - * - * @param string|integer|Zend_Date $date ISO Date to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setIso($date, $locale = null) - { - return $this->_calcvalue('set', $date, 'iso', self::ISO_8601, $locale); - } - - - /** - * Adds a ISO date to the date object. Not given parts are set to default. - * Only supported ISO 8601 formats are accepted. - * For example: 050901 -> + 01.Sept.2005 00:00:00, 10:00:00 -> +10h - * Returned is the new date object - * - * @param string|integer|Zend_Date $date ISO Date to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addIso($date, $locale = null) - { - return $this->_calcvalue('add', $date, 'iso', self::ISO_8601, $locale); - } - - - /** - * Subtracts a ISO date from the date object. Not given parts are set to default. - * Only supported ISO 8601 formats are accepted. - * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h - * Returned is the new date object - * - * @param string|integer|Zend_Date $date ISO Date to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subIso($date, $locale = null) - { - return $this->_calcvalue('sub', $date, 'iso', self::ISO_8601, $locale); - } - - - /** - * Compares a ISO date with the date object. Not given parts are set to default. - * Only supported ISO 8601 formats are accepted. - * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h - * Returns if equal, earlier or later - * - * @param string|integer|Zend_Date $date ISO Date to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareIso($date, $locale = null) - { - return $this->_calcvalue('cmp', $date, 'iso', self::ISO_8601, $locale); - } - - - /** - * Returns a RFC 822 compilant datestring from the date object. - * This function does not return the RFC date as object. Use copy() instead. - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return string - */ - public function getArpa($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'D\, d M y H\:i\:s O'; - } else { - $format = self::RFC_822; - } - - return $this->toString($format, 'iso', $locale); - } - - - /** - * Sets a RFC 822 date as new date for the date object. - * Only RFC 822 compilant date strings are accepted. - * For example: Sat, 14 Feb 09 00:31:30 +0100 - * Returned is the new date object - * - * @param string|integer|Zend_Date $date RFC 822 to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setArpa($date, $locale = null) - { - return $this->_calcvalue('set', $date, 'arpa', self::RFC_822, $locale); - } - - - /** - * Adds a RFC 822 date to the date object. - * ARPA messages are used in emails or HTTP Headers. - * Only RFC 822 compilant date strings are accepted. - * For example: Sat, 14 Feb 09 00:31:30 +0100 - * Returned is the new date object - * - * @param string|integer|Zend_Date $date RFC 822 Date to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addArpa($date, $locale = null) - { - return $this->_calcvalue('add', $date, 'arpa', self::RFC_822, $locale); - } - - - /** - * Subtracts a RFC 822 date from the date object. - * ARPA messages are used in emails or HTTP Headers. - * Only RFC 822 compilant date strings are accepted. - * For example: Sat, 14 Feb 09 00:31:30 +0100 - * Returned is the new date object - * - * @param string|integer|Zend_Date $date RFC 822 Date to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subArpa($date, $locale = null) - { - return $this->_calcvalue('sub', $date, 'arpa', self::RFC_822, $locale); - } - - - /** - * Compares a RFC 822 compilant date with the date object. - * ARPA messages are used in emails or HTTP Headers. - * Only RFC 822 compilant date strings are accepted. - * For example: Sat, 14 Feb 09 00:31:30 +0100 - * Returns if equal, earlier or later - * - * @param string|integer|Zend_Date $date RFC 822 Date to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareArpa($date, $locale = null) - { - return $this->_calcvalue('cmp', $date, 'arpa', self::RFC_822, $locale); - } - - /** - * Check if location is supported - * - * @param array $location locations array - * @throws Zend_Date_Exception - * @return float $horizon float - */ - private function _checkLocation($location) - { - if (!isset($location['longitude']) || !isset($location['latitude'])) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('Location must include \'longitude\' and \'latitude\'', 0, null, $location); - } - if (($location['longitude'] > 180) || ($location['longitude'] < -180)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('Longitude must be between -180 and 180', 0, null, $location); - } - if (($location['latitude'] > 90) || ($location['latitude'] < -90)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('Latitude must be between -90 and 90', 0, null, $location); - } - - if (!isset($location['horizon'])){ - $location['horizon'] = 'effective'; - } - - switch ($location['horizon']) { - case 'civil' : - return -0.104528; - break; - case 'nautic' : - return -0.207912; - break; - case 'astronomic' : - return -0.309017; - break; - default : - return -0.0145439; - break; - } - } - - - /** - * Returns the time of sunrise for this date and a given location as new date object - * For a list of cities and correct locations use the class Zend_Date_Cities - * - * @param array $location location of sunrise - * ['horizon'] -> civil, nautic, astronomical, effective (default) - * ['longitude'] -> longitude of location - * ['latitude'] -> latitude of location - * @return Zend_Date - * @throws Zend_Date_Exception - */ - public function getSunrise($location) - { - $horizon = $this->_checkLocation($location); - $result = clone $this; - $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); - return $result; - } - - - /** - * Returns the time of sunset for this date and a given location as new date object - * For a list of cities and correct locations use the class Zend_Date_Cities - * - * @param array $location location of sunset - * ['horizon'] -> civil, nautic, astronomical, effective (default) - * ['longitude'] -> longitude of location - * ['latitude'] -> latitude of location - * @return Zend_Date - * @throws Zend_Date_Exception - */ - public function getSunset($location) - { - $horizon = $this->_checkLocation($location); - $result = clone $this; - $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); - return $result; - } - - - /** - * Returns an array with the sunset and sunrise dates for all horizon types - * For a list of cities and correct locations use the class Zend_Date_Cities - * - * @param array $location location of suninfo - * ['horizon'] -> civil, nautic, astronomical, effective (default) - * ['longitude'] -> longitude of location - * ['latitude'] -> latitude of location - * @return array - [sunset|sunrise][effective|civil|nautic|astronomic] - * @throws Zend_Date_Exception - */ - public function getSunInfo($location) - { - $suninfo = array(); - for ($i = 0; $i < 4; ++$i) { - switch ($i) { - case 0 : - $location['horizon'] = 'effective'; - break; - case 1 : - $location['horizon'] = 'civil'; - break; - case 2 : - $location['horizon'] = 'nautic'; - break; - case 3 : - $location['horizon'] = 'astronomic'; - break; - } - $horizon = $this->_checkLocation($location); - $result = clone $this; - $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); - $suninfo['sunrise'][$location['horizon']] = $result; - $result = clone $this; - $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); - $suninfo['sunset'][$location['horizon']] = $result; - } - return $suninfo; - } - - /** - * Check a given year for leap year. - * - * @param integer|array|Zend_Date $year Year to check - * @throws Zend_Date_Exception - * @return boolean - */ - public static function checkLeapYear($year) - { - if ($year instanceof Zend_Date) { - $year = (int) $year->toString(self::YEAR, 'iso'); - } - - if (is_array($year)) { - if (isset($year['year']) === true) { - $year = $year['year']; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no year given in array"); - } - } - - if (!is_numeric($year)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("year ($year) has to be integer for checkLeapYear()", 0, null, $year); - } - - return (bool) parent::isYearLeapYear($year); - } - - - /** - * Returns true, if the year is a leap year. - * - * @return boolean - */ - public function isLeapYear() - { - return self::checkLeapYear($this); - } - - - /** - * Returns if the set date is todays date - * - * @return boolean - */ - public function isToday() - { - $today = $this->date('Ymd', $this->_getTime()); - $day = $this->date('Ymd', $this->getUnixTimestamp()); - return ($today == $day); - } - - - /** - * Returns if the set date is yesterdays date - * - * @return boolean - */ - public function isYesterday() - { - list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); - // adjusts for leap days and DST changes that are timezone specific - $yesterday = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day -1, $year)); - $day = $this->date('Ymd', $this->getUnixTimestamp()); - return $day == $yesterday; - } - - - /** - * Returns if the set date is tomorrows date - * - * @return boolean - */ - public function isTomorrow() - { - list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); - // adjusts for leap days and DST changes that are timezone specific - $tomorrow = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day +1, $year)); - $day = $this->date('Ymd', $this->getUnixTimestamp()); - return $day == $tomorrow; - } - - /** - * Returns the actual date as new date object - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public static function now($locale = null) - { - return new Zend_Date(time(), self::TIMESTAMP, $locale); - } - - /** - * Calculate date details - * - * @param string $calc Calculation to make - * @param string|integer|array|Zend_Date $date Date or Part to calculate - * @param string $type Datepart for Calculation - * @param string|Zend_Locale $locale Locale for parsing input - * @return integer|string new date - * @throws Zend_Date_Exception - */ - private function _calcdetail($calc, $date, $type, $locale) - { - $old = false; - if (self::$_options['format_type'] == 'php') { - self::$_options['format_type'] = 'iso'; - $old = true; - } - - switch($calc) { - case 'set' : - $return = $this->set($date, $type, $locale); - break; - case 'add' : - $return = $this->add($date, $type, $locale); - break; - case 'sub' : - $return = $this->sub($date, $type, $locale); - break; - default : - $return = $this->compare($date, $type, $locale); - break; - } - - if ($old) { - self::$_options['format_type'] = 'php'; - } - - return $return; - } - - /** - * Internal calculation, returns the requested date type - * - * @param string $calc Calculation to make - * @param string|integer|Zend_Date $value Datevalue to calculate with, if null the actual value is taken - * @param string $type - * @param string $parameter - * @param string|Zend_Locale $locale Locale for parsing input - * @throws Zend_Date_Exception - * @return integer|Zend_Date new date - */ - private function _calcvalue($calc, $value, $type, $parameter, $locale) - { - if ($value === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("parameter $type must be set, null is not allowed"); - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if ($value instanceof Zend_Date) { - // extract value from object - $value = $value->toString($parameter, 'iso', $locale); - } else if (!is_array($value) && !is_numeric($value) && ($type != 'iso') && ($type != 'arpa')) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid $type ($value) operand", 0, null, $value); - } - - $return = $this->_calcdetail($calc, $value, $parameter, $locale); - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - - /** - * Returns only the year from the date object as new object. - * For example: 10.May.2000 10:30:00 -> 01.Jan.2000 00:00:00 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getYear($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'Y'; - } else { - $format = self::YEAR; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Sets a new year - * If the year is between 0 and 69, 2000 will be set (2000-2069) - * If the year if between 70 and 99, 1999 will be set (1970-1999) - * 3 or 4 digit years are set as expected. If you need to set year 0-99 - * use set() instead. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $year Year to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setYear($year, $locale = null) - { - return $this->_calcvalue('set', $year, 'year', self::YEAR, $locale); - } - - - /** - * Adds the year to the existing date object - * If the year is between 0 and 69, 2000 will be added (2000-2069) - * If the year if between 70 and 99, 1999 will be added (1970-1999) - * 3 or 4 digit years are added as expected. If you need to add years from 0-99 - * use add() instead. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $year Year to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addYear($year, $locale = null) - { - return $this->_calcvalue('add', $year, 'year', self::YEAR, $locale); - } - - - /** - * Subs the year from the existing date object - * If the year is between 0 and 69, 2000 will be subtracted (2000-2069) - * If the year if between 70 and 99, 1999 will be subtracted (1970-1999) - * 3 or 4 digit years are subtracted as expected. If you need to subtract years from 0-99 - * use sub() instead. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $year Year to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subYear($year, $locale = null) - { - return $this->_calcvalue('sub', $year, 'year', self::YEAR, $locale); - } - - - /** - * Compares the year with the existing date object, ignoring other date parts. - * For example: 10.03.2000 -> 15.02.2000 -> true - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $year Year to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareYear($year, $locale = null) - { - return $this->_calcvalue('cmp', $year, 'year', self::YEAR, $locale); - } - - - /** - * Returns only the month from the date object as new object. - * For example: 10.May.2000 10:30:00 -> 01.May.1970 00:00:00 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getMonth($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'm'; - } else { - $format = self::MONTH; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Returns the calculated month - * - * @param string $calc Calculation to make - * @param string|integer|array|Zend_Date $month Month to calculate with, if null the actual month is taken - * @param string|Zend_Locale $locale Locale for parsing input - * @return integer|Zend_Date new time - * @throws Zend_Date_Exception - */ - private function _month($calc, $month, $locale) - { - if ($month === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $month must be set, null is not allowed'); - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if ($month instanceof Zend_Date) { - // extract month from object - $found = $month->toString(self::MONTH_SHORT, 'iso', $locale); - } else { - if (is_numeric($month)) { - $found = $month; - } else if (is_array($month)) { - if (isset($month['month']) === true) { - $month = $month['month']; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no month given in array"); - } - } else { - $monthlist = Zend_Locale_Data::getList($locale, 'month'); - $monthlist2 = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); - - $monthlist = array_merge($monthlist, $monthlist2); - $found = 0; - $cnt = 0; - foreach ($monthlist as $key => $value) { - if (strtoupper($value) == strtoupper($month)) { - $found = ($key % 12) + 1; - break; - } - ++$cnt; - } - if ($found == 0) { - foreach ($monthlist2 as $key => $value) { - if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($month)) { - $found = $key + 1; - break; - } - ++$cnt; - } - } - if ($found == 0) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("unknown month name ($month)", 0, null, $month); - } - } - } - $return = $this->_calcdetail($calc, $found, self::MONTH_SHORT, $locale); - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - - /** - * Sets a new month - * The month can be a number or a string. Setting months lower then 0 and greater then 12 - * will result in adding or subtracting the relevant year. (12 months equal one year) - * If a localized monthname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $month Month to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setMonth($month, $locale = null) - { - return $this->_month('set', $month, $locale); - } - - - /** - * Adds months to the existing date object. - * The month can be a number or a string. Adding months lower then 0 and greater then 12 - * will result in adding or subtracting the relevant year. (12 months equal one year) - * If a localized monthname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $month Month to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addMonth($month, $locale = null) - { - return $this->_month('add', $month, $locale); - } - - - /** - * Subtracts months from the existing date object. - * The month can be a number or a string. Subtracting months lower then 0 and greater then 12 - * will result in adding or subtracting the relevant year. (12 months equal one year) - * If a localized monthname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * - * @param string|integer|array|Zend_Date $month Month to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subMonth($month, $locale = null) - { - return $this->_month('sub', $month, $locale); - } - - - /** - * Compares the month with the existing date object, ignoring other date parts. - * For example: 10.03.2000 -> 15.03.1950 -> true - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $month Month to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareMonth($month, $locale = null) - { - return $this->_month('cmp', $month, $locale); - } - - - /** - * Returns the day as new date object - * Example: 20.May.1986 -> 20.Jan.1970 00:00:00 - * - * @param Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getDay($locale = null) - { - return $this->copyPart(self::DAY_SHORT, $locale); - } - - /** - * Returns the calculated day - * - * @param string $calc Type of calculation to make - * @param Zend_Date $day Day to calculate, when null the actual day is calculated - * @param Zend_Locale $locale Locale for parsing input - * @throws Zend_Date_Exception - * @return Zend_Date|integer - */ - private function _day($calc, $day, $locale) - { - if ($day === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $day must be set, null is not allowed'); - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if ($day instanceof Zend_Date) { - $day = $day->toString(self::DAY_SHORT, 'iso', $locale); - } - - if (is_numeric($day)) { - $type = self::DAY_SHORT; - } else if (is_array($day)) { - if (isset($day['day']) === true) { - $day = $day['day']; - $type = self::WEEKDAY; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no day given in array"); - } - } else { - switch (iconv_strlen($day, 'UTF-8')) { - case 1 : - $type = self::WEEKDAY_NARROW; - break; - case 2: - $type = self::WEEKDAY_NAME; - break; - case 3: - $type = self::WEEKDAY_SHORT; - break; - default: - $type = self::WEEKDAY; - break; - } - } - $return = $this->_calcdetail($calc, $day, $type, $locale); - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - - /** - * Sets a new day - * The day can be a number or a string. Setting days lower then 0 or greater than the number of this months days - * will result in adding or subtracting the relevant month. - * If a localized dayname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * Example: setDay('Montag', 'de_AT'); will set the monday of this week as day. - * - * @param string|integer|array|Zend_Date $day Day to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setDay($day, $locale = null) - { - return $this->_day('set', $day, $locale); - } - - - /** - * Adds days to the existing date object. - * The day can be a number or a string. Adding days lower then 0 or greater than the number of this months days - * will result in adding or subtracting the relevant month. - * If a localized dayname is given it will be parsed with the default locale or the optional - * set locale. - * - * @param string|integer|array|Zend_Date $day Day to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addDay($day, $locale = null) - { - return $this->_day('add', $day, $locale); - } - - - /** - * Subtracts days from the existing date object. - * The day can be a number or a string. Subtracting days lower then 0 or greater than the number of this months days - * will result in adding or subtracting the relevant month. - * If a localized dayname is given it will be parsed with the default locale or the optional - * set locale. - * - * @param string|integer|array|Zend_Date $day Day to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subDay($day, $locale = null) - { - return $this->_day('sub', $day, $locale); - } - - - /** - * Compares the day with the existing date object, ignoring other date parts. - * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $day Day to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareDay($day, $locale = null) - { - return $this->_day('cmp', $day, $locale); - } - - - /** - * Returns the weekday as new date object - * Weekday is always from 1-7 - * Example: 09-Jan-2007 -> 2 = Tuesday -> 02-Jan-1970 (when 02.01.1970 is also Tuesday) - * - * @param Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getWeekday($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'l'; - } else { - $format = self::WEEKDAY; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Returns the calculated weekday - * - * @param string $calc Type of calculation to make - * @param Zend_Date $weekday Weekday to calculate, when null the actual weekday is calculated - * @param Zend_Locale $locale Locale for parsing input - * @return Zend_Date|integer - * @throws Zend_Date_Exception - */ - private function _weekday($calc, $weekday, $locale) - { - if ($weekday === null) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('parameter $weekday must be set, null is not allowed'); - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if ($weekday instanceof Zend_Date) { - $weekday = $weekday->toString(self::WEEKDAY_8601, 'iso', $locale); - } - - if (is_numeric($weekday)) { - $type = self::WEEKDAY_8601; - } else if (is_array($weekday)) { - if (isset($weekday['weekday']) === true) { - $weekday = $weekday['weekday']; - $type = self::WEEKDAY; - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("no weekday given in array"); - } - } else { - switch(iconv_strlen($weekday, 'UTF-8')) { - case 1: - $type = self::WEEKDAY_NARROW; - break; - case 2: - $type = self::WEEKDAY_NAME; - break; - case 3: - $type = self::WEEKDAY_SHORT; - break; - default: - $type = self::WEEKDAY; - break; - } - } - $return = $this->_calcdetail($calc, $weekday, $type, $locale); - if ($calc != 'cmp') { - return $this; - } - return $return; - } - - - /** - * Sets a new weekday - * The weekday can be a number or a string. If a localized weekday name is given, - * then it will be parsed as a date in $locale (defaults to the same locale as $this). - * Returned is the new date object. - * Example: setWeekday(3); will set the wednesday of this week as day. - * - * @param string|integer|array|Zend_Date $weekday Weekday to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setWeekday($weekday, $locale = null) - { - return $this->_weekday('set', $weekday, $locale); - } - - - /** - * Adds weekdays to the existing date object. - * The weekday can be a number or a string. - * If a localized dayname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * Example: addWeekday(3); will add the difference of days from the begining of the month until - * wednesday. - * - * @param string|integer|array|Zend_Date $weekday Weekday to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addWeekday($weekday, $locale = null) - { - return $this->_weekday('add', $weekday, $locale); - } - - - /** - * Subtracts weekdays from the existing date object. - * The weekday can be a number or a string. - * If a localized dayname is given it will be parsed with the default locale or the optional - * set locale. - * Returned is the new date object - * Example: subWeekday(3); will subtract the difference of days from the begining of the month until - * wednesday. - * - * @param string|integer|array|Zend_Date $weekday Weekday to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subWeekday($weekday, $locale = null) - { - return $this->_weekday('sub', $weekday, $locale); - } - - - /** - * Compares the weekday with the existing date object, ignoring other date parts. - * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $weekday Weekday to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareWeekday($weekday, $locale = null) - { - return $this->_weekday('cmp', $weekday, $locale); - } - - - /** - * Returns the day of year as new date object - * Example: 02.Feb.1986 10:00:00 -> 02.Feb.1970 00:00:00 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getDayOfYear($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'D'; - } else { - $format = self::DAY_OF_YEAR; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Sets a new day of year - * The day of year is always a number. - * Returned is the new date object - * Example: 04.May.2004 -> setDayOfYear(10) -> 10.Jan.2004 - * - * @param string|integer|array|Zend_Date $day Day of Year to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setDayOfYear($day, $locale = null) - { - return $this->_calcvalue('set', $day, 'day of year', self::DAY_OF_YEAR, $locale); - } - - - /** - * Adds a day of year to the existing date object. - * The day of year is always a number. - * Returned is the new date object - * Example: addDayOfYear(10); will add 10 days to the existing date object. - * - * @param string|integer|array|Zend_Date $day Day of Year to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addDayOfYear($day, $locale = null) - { - return $this->_calcvalue('add', $day, 'day of year', self::DAY_OF_YEAR, $locale); - } - - - /** - * Subtracts a day of year from the existing date object. - * The day of year is always a number. - * Returned is the new date object - * Example: subDayOfYear(10); will subtract 10 days from the existing date object. - * - * @param string|integer|array|Zend_Date $day Day of Year to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subDayOfYear($day, $locale = null) - { - return $this->_calcvalue('sub', $day, 'day of year', self::DAY_OF_YEAR, $locale); - } - - - /** - * Compares the day of year with the existing date object. - * For example: compareDayOfYear(33) -> 02.Feb.2007 -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $day Day of Year to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareDayOfYear($day, $locale = null) - { - return $this->_calcvalue('cmp', $day, 'day of year', self::DAY_OF_YEAR, $locale); - } - - - /** - * Returns the hour as new date object - * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 10:00:00 - * - * @param Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getHour($locale = null) - { - return $this->copyPart(self::HOUR, $locale); - } - - - /** - * Sets a new hour - * The hour is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> setHour(7); -> 04.May.1993 07:07:25 - * - * @param string|integer|array|Zend_Date $hour Hour to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setHour($hour, $locale = null) - { - return $this->_calcvalue('set', $hour, 'hour', self::HOUR_SHORT, $locale); - } - - - /** - * Adds hours to the existing date object. - * The hour is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> addHour(12); -> 05.May.1993 01:07:25 - * - * @param string|integer|array|Zend_Date $hour Hour to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addHour($hour, $locale = null) - { - return $this->_calcvalue('add', $hour, 'hour', self::HOUR_SHORT, $locale); - } - - - /** - * Subtracts hours from the existing date object. - * The hour is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> subHour(6); -> 05.May.1993 07:07:25 - * - * @param string|integer|array|Zend_Date $hour Hour to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subHour($hour, $locale = null) - { - return $this->_calcvalue('sub', $hour, 'hour', self::HOUR_SHORT, $locale); - } - - - /** - * Compares the hour with the existing date object. - * For example: 10:30:25 -> compareHour(10) -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $hour Hour to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareHour($hour, $locale = null) - { - return $this->_calcvalue('cmp', $hour, 'hour', self::HOUR_SHORT, $locale); - } - - - /** - * Returns the minute as new date object - * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:30:00 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getMinute($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'i'; - } else { - $format = self::MINUTE; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Sets a new minute - * The minute is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> setMinute(29); -> 04.May.1993 13:29:25 - * - * @param string|integer|array|Zend_Date $minute Minute to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setMinute($minute, $locale = null) - { - return $this->_calcvalue('set', $minute, 'minute', self::MINUTE_SHORT, $locale); - } - - - /** - * Adds minutes to the existing date object. - * The minute is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> addMinute(65); -> 04.May.1993 13:12:25 - * - * @param string|integer|array|Zend_Date $minute Minute to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addMinute($minute, $locale = null) - { - return $this->_calcvalue('add', $minute, 'minute', self::MINUTE_SHORT, $locale); - } - - - /** - * Subtracts minutes from the existing date object. - * The minute is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> subMinute(9); -> 04.May.1993 12:58:25 - * - * @param string|integer|array|Zend_Date $minute Minute to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subMinute($minute, $locale = null) - { - return $this->_calcvalue('sub', $minute, 'minute', self::MINUTE_SHORT, $locale); - } - - - /** - * Compares the minute with the existing date object. - * For example: 10:30:25 -> compareMinute(30) -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $minute Hour to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareMinute($minute, $locale = null) - { - return $this->_calcvalue('cmp', $minute, 'minute', self::MINUTE_SHORT, $locale); - } - - - /** - * Returns the second as new date object - * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:00:25 - * - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getSecond($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 's'; - } else { - $format = self::SECOND; - } - - return $this->copyPart($format, $locale); - } - - - /** - * Sets new seconds to the existing date object. - * The second is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> setSecond(100); -> 04.May.1993 13:08:40 - * - * @param string|integer|array|Zend_Date $second Second to set - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setSecond($second, $locale = null) - { - return $this->_calcvalue('set', $second, 'second', self::SECOND_SHORT, $locale); - } - - - /** - * Adds seconds to the existing date object. - * The second is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> addSecond(65); -> 04.May.1993 13:08:30 - * - * @param string|integer|array|Zend_Date $second Second to add - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addSecond($second, $locale = null) - { - return $this->_calcvalue('add', $second, 'second', self::SECOND_SHORT, $locale); - } - - - /** - * Subtracts seconds from the existing date object. - * The second is always a number. - * Returned is the new date object - * Example: 04.May.1993 13:07:25 -> subSecond(10); -> 04.May.1993 13:07:15 - * - * @param string|integer|array|Zend_Date $second Second to sub - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subSecond($second, $locale = null) - { - return $this->_calcvalue('sub', $second, 'second', self::SECOND_SHORT, $locale); - } - - - /** - * Compares the second with the existing date object. - * For example: 10:30:25 -> compareSecond(25) -> 0 - * Returns if equal, earlier or later - * - * @param string|integer|array|Zend_Date $second Second to compare - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - * @throws Zend_Date_Exception - */ - public function compareSecond($second, $locale = null) - { - return $this->_calcvalue('cmp', $second, 'second', self::SECOND_SHORT, $locale); - } - - - /** - * Returns the precision for fractional seconds - * - * @return integer - */ - public function getFractionalPrecision() - { - return $this->_precision; - } - - - /** - * Sets a new precision for fractional seconds - * - * @param integer $precision Precision for the fractional datepart 3 = milliseconds - * @throws Zend_Date_Exception - * @return Zend_Date Provides a fluent interface - */ - public function setFractionalPrecision($precision) - { - if (!intval($precision) || ($precision < 0) || ($precision > 9)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); - } - - $this->_precision = (int) $precision; - if ($this->_precision < strlen($this->_fractional)) { - $this->_fractional = substr($this->_fractional, 0, $this->_precision); - } else { - $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_RIGHT); - } - - return $this; - } - - - /** - * Returns the milliseconds of the date object - * - * @return string - */ - public function getMilliSecond() - { - return $this->_fractional; - } - - /** - * Sets new milliseconds for the date object - * Example: setMilliSecond(550, 2) -> equals +5 Sec +50 MilliSec - * - * @param integer|Zend_Date $milli (Optional) Millisecond to set, when null the actual millisecond is set - * @param integer $precision (Optional) Fraction precision of the given milliseconds - * @throws Zend_Date_Exception - * @return Zend_Date Provides a fluent interface - */ - public function setMilliSecond($milli = null, $precision = null) - { - if ($milli === null) { - list($milli, $time) = explode(" ", microtime()); - $milli = intval($milli); - $precision = 6; - } else if (!is_numeric($milli)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); - } - - if ($precision === null) { - $precision = $this->_precision; - } - - if (!is_int($precision) || $precision < 1 || $precision > 9) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); - } - - $this->_fractional = 0; - $this->addMilliSecond($milli, $precision); - return $this; - } - - /** - * Adds milliseconds to the date object - * - * @param integer|Zend_Date $milli (Optional) Millisecond to add, when null the actual millisecond is added - * @param integer $precision (Optional) Fractional precision for the given milliseconds - * @throws Zend_Date_Exception - * @return Zend_Date Provides a fluent interface - */ - public function addMilliSecond($milli = null, $precision = null) - { - if ($milli === null) { - list($milli, $time) = explode(" ", microtime()); - $milli = intval($milli); - } else if (!is_numeric($milli)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); - } - - if ($precision === null) { - // Use internal default precision - // Is not as logic as using the length of the input. But this would break tests and maybe other things - // as an input value of integer 10, which is used in tests, must be parsed as 10 milliseconds (real milliseconds, precision 3) - // but with auto-detect of precision, 100 milliseconds would be added. - $precision = $this->_precision; - } - - if (!is_int($precision) || $precision < 1 || $precision > 9) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception( - "precision ($precision) must be a positive integer less than 10", 0, null, $precision - ); - } - - if ($this->_precision > $precision) { - $milli = $milli * pow(10, $this->_precision - $precision); - } elseif ($this->_precision < $precision) { - $milli = round($milli / pow(10, $precision - $this->_precision)); - } - - $this->_fractional += $milli; - - // Add/sub milliseconds + add/sub seconds - $max = pow(10, $this->_precision); - // Milli includes seconds - if ($this->_fractional >= $max) { - while ($this->_fractional >= $max) { - $this->addSecond(1); - $this->_fractional -= $max; - } - } - - if ($this->_fractional < 0) { - while ($this->_fractional < 0) { - $this->subSecond(1); - $this->_fractional += $max; - } - } - - if ($this->_precision > strlen($this->_fractional)) { - $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_LEFT); - } - - return $this; - } - - - /** - * Subtracts a millisecond - * - * @param integer|Zend_Date $milli (Optional) Millisecond to sub, when null the actual millisecond is subtracted - * @param integer $precision (Optional) Fractional precision for the given milliseconds - * @return Zend_Date Provides a fluent interface - */ - public function subMilliSecond($milli = null, $precision = null) - { - $this->addMilliSecond(0 - $milli, $precision); - return $this; - } - - /** - * Compares only the millisecond part, returning the difference - * - * @param integer|Zend_Date $milli OPTIONAL Millisecond to compare, when null the actual millisecond is compared - * @param integer $precision OPTIONAL Fractional precision for the given milliseconds - * @throws Zend_Date_Exception On invalid input - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - public function compareMilliSecond($milli = null, $precision = null) - { - if ($milli === null) { - list($milli, $time) = explode(" ", microtime()); - $milli = intval($milli); - } else if (is_numeric($milli) === false) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); - } - - if ($precision === null) { - $precision = strlen($milli); - } else if (!is_int($precision) || $precision < 1 || $precision > 9) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); - } - - if ($precision === 0) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('precision is 0'); - } - - if ($precision != $this->_precision) { - if ($precision > $this->_precision) { - $diff = $precision - $this->_precision; - $milli = (int) ($milli / (10 * $diff)); - } else { - $diff = $this->_precision - $precision; - $milli = (int) ($milli * (10 * $diff)); - } - } - - $comp = $this->_fractional - $milli; - if ($comp < 0) { - return -1; - } else if ($comp > 0) { - return 1; - } - return 0; - } - - /** - * Returns the week as new date object using monday as begining of the week - * Example: 12.Jan.2007 -> 08.Jan.1970 00:00:00 - * - * @param Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date - */ - public function getWeek($locale = null) - { - if (self::$_options['format_type'] == 'php') { - $format = 'W'; - } else { - $format = self::WEEK; - } - - return $this->copyPart($format, $locale); - } - - /** - * Sets a new week. The week is always a number. The day of week is not changed. - * Returned is the new date object - * Example: 09.Jan.2007 13:07:25 -> setWeek(1); -> 02.Jan.2007 13:07:25 - * - * @param string|integer|array|Zend_Date $week Week to set - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function setWeek($week, $locale = null) - { - return $this->_calcvalue('set', $week, 'week', self::WEEK, $locale); - } - - /** - * Adds a week. The week is always a number. The day of week is not changed. - * Returned is the new date object - * Example: 09.Jan.2007 13:07:25 -> addWeek(1); -> 16.Jan.2007 13:07:25 - * - * @param string|integer|array|Zend_Date $week Week to add - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function addWeek($week, $locale = null) - { - return $this->_calcvalue('add', $week, 'week', self::WEEK, $locale); - } - - /** - * Subtracts a week. The week is always a number. The day of week is not changed. - * Returned is the new date object - * Example: 09.Jan.2007 13:07:25 -> subWeek(1); -> 02.Jan.2007 13:07:25 - * - * @param string|integer|array|Zend_Date $week Week to sub - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return Zend_Date Provides a fluent interface - * @throws Zend_Date_Exception - */ - public function subWeek($week, $locale = null) - { - return $this->_calcvalue('sub', $week, 'week', self::WEEK, $locale); - } - - /** - * Compares only the week part, returning the difference - * Returned is the new date object - * Returns if equal, earlier or later - * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 - * - * @param string|integer|array|Zend_Date $week Week to compare - * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - public function compareWeek($week, $locale = null) - { - return $this->_calcvalue('cmp', $week, 'week', self::WEEK, $locale); - } - - /** - * Sets a new standard locale for the date object. - * This locale will be used for all functions - * Returned is the really set locale. - * Example: 'de_XX' will be set to 'de' because 'de_XX' does not exist - * 'xx_YY' will be set to 'root' because 'xx' does not exist - * - * @param string|Zend_Locale $locale (Optional) Locale for parsing input - * @throws Zend_Date_Exception When the given locale does not exist - * @return Zend_Date Provides fluent interface - */ - public function setLocale($locale = null) - { - try { - $this->_locale = Zend_Locale::findLocale($locale); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception($e->getMessage(), 0, $e); - } - - return $this; - } - - /** - * Returns the actual set locale - * - * @return string - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Checks if the given date is a real date or datepart. - * Returns false if a expected datepart is missing or a datepart exceeds its possible border. - * But the check will only be done for the expected dateparts which are given by format. - * If no format is given the standard dateformat for the actual locale is used. - * f.e. 30.February.2007 will return false if format is 'dd.MMMM.YYYY' - * - * @param string|array|Zend_Date $date Date to parse for correctness - * @param string $format (Optional) Format for parsing the date string - * @param string|Zend_Locale $locale (Optional) Locale for parsing date parts - * @return boolean True when all date parts are correct - */ - public static function isDate($date, $format = null, $locale = null) - { - if (!is_string($date) && !is_numeric($date) && !($date instanceof Zend_Date) && - !is_array($date)) { - return false; - } - - if (($format !== null) && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') - && (Zend_Locale::isLocale($format, null, false))) { - $locale = $format; - $format = null; - } - - $locale = Zend_Locale::findLocale($locale); - - if ($format === null) { - $format = Zend_Locale_Format::getDateFormat($locale); - } else if ((self::$_options['format_type'] == 'php') && !defined($format)) { - $format = Zend_Locale_Format::convertPhpToIsoFormat($format); - } - - $format = self::_getLocalizedToken($format, $locale); - if (!is_array($date)) { - try { - $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, - 'date_format' => $format, 'format_type' => 'iso', - 'fix_date' => false)); - } catch (Zend_Locale_Exception $e) { - // Date can not be parsed - return false; - } - } else { - $parsed = $date; - } - - if (((strpos($format, 'Y') !== false) || (strpos($format, 'y') !== false)) and - (!isset($parsed['year']))) { - // Year expected but not found - return false; - } - - if ((strpos($format, 'M') !== false) and (!isset($parsed['month']))) { - // Month expected but not found - return false; - } - - if ((strpos($format, 'd') !== false) and (!isset($parsed['day']))) { - // Day expected but not found - return false; - } - - if (((strpos($format, 'H') !== false) || (strpos($format, 'h') !== false)) and - (!isset($parsed['hour']))) { - // Hour expected but not found - return false; - } - - if ((strpos($format, 'm') !== false) and (!isset($parsed['minute']))) { - // Minute expected but not found - return false; - } - - if ((strpos($format, 's') !== false) and (!isset($parsed['second']))) { - // Second expected but not found - return false; - } - - // Set not given dateparts - if (isset($parsed['hour']) === false) { - $parsed['hour'] = 12; - } - - if (isset($parsed['minute']) === false) { - $parsed['minute'] = 0; - } - - if (isset($parsed['second']) === false) { - $parsed['second'] = 0; - } - - if (isset($parsed['month']) === false) { - $parsed['month'] = 1; - } - - if (isset($parsed['day']) === false) { - $parsed['day'] = 1; - } - - if (isset($parsed['year']) === false) { - $parsed['year'] = 1970; - } - - if (self::isYearLeapYear($parsed['year'])) { - $parsed['year'] = 1972; - } else { - $parsed['year'] = 1971; - } - - $date = new self($parsed, null, $locale); - $timestamp = $date->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], - $parsed['month'], $parsed['day'], $parsed['year']); - - if ($parsed['year'] != $date->date('Y', $timestamp)) { - // Given year differs from parsed year - return false; - } - - if ($parsed['month'] != $date->date('n', $timestamp)) { - // Given month differs from parsed month - return false; - } - - if ($parsed['day'] != $date->date('j', $timestamp)) { - // Given day differs from parsed day - return false; - } - - if ($parsed['hour'] != $date->date('G', $timestamp)) { - // Given hour differs from parsed hour - return false; - } - - if ($parsed['minute'] != $date->date('i', $timestamp)) { - // Given minute differs from parsed minute - return false; - } - - if ($parsed['second'] != $date->date('s', $timestamp)) { - // Given second differs from parsed second - return false; - } - - return true; - } - - /** - * Returns the ISO Token for all localized constants - * - * @param string $token Token to normalize - * @param string $locale Locale to search - * @return string - */ - protected static function _getLocalizedToken($token, $locale) - { - switch($token) { - case self::ISO_8601 : - return "yyyy-MM-ddThh:mm:ss"; - break; - case self::RFC_2822 : - return "EEE, dd MMM yyyy HH:mm:ss"; - break; - case self::DATES : - return Zend_Locale_Data::getContent($locale, 'date'); - break; - case self::DATE_FULL : - return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); - break; - case self::DATE_LONG : - return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); - break; - case self::DATE_MEDIUM : - return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); - break; - case self::DATE_SHORT : - return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); - break; - case self::TIMES : - return Zend_Locale_Data::getContent($locale, 'time'); - break; - case self::TIME_FULL : - return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); - break; - case self::TIME_LONG : - return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); - break; - case self::TIME_MEDIUM : - return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); - break; - case self::TIME_SHORT : - return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); - break; - case self::DATETIME : - return Zend_Locale_Data::getContent($locale, 'datetime'); - break; - case self::DATETIME_FULL : - return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); - break; - case self::DATETIME_LONG : - return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); - break; - case self::DATETIME_MEDIUM : - return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); - break; - case self::DATETIME_SHORT : - return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); - break; - case self::ATOM : - case self::RFC_3339 : - case self::W3C : - return "yyyy-MM-DD HH:mm:ss"; - break; - case self::COOKIE : - case self::RFC_850 : - return "EEEE, dd-MM-yyyy HH:mm:ss"; - break; - case self::RFC_822 : - case self::RFC_1036 : - case self::RFC_1123 : - case self::RSS : - return "EEE, dd MM yyyy HH:mm:ss"; - break; - } - - return $token; - } -} diff --git a/lib/Zend/Date/Cities.php b/lib/Zend/Date/Cities.php deleted file mode 100644 index 97e07070fd3..00000000000 --- a/lib/Zend/Date/Cities.php +++ /dev/null @@ -1,322 +0,0 @@ - array('latitude' => 5.3411111, 'longitude' => -4.0280556), - 'Abu Dhabi' => array('latitude' => 24.4666667, 'longitude' => 54.3666667), - 'Abuja' => array('latitude' => 9.1758333, 'longitude' => 7.1808333), - 'Accra' => array('latitude' => 5.55, 'longitude' => -0.2166667), - 'Adamstown' => array('latitude' => -25.0666667, 'longitude' => -130.0833333), - 'Addis Ababa' => array('latitude' => 9.0333333, 'longitude' => 38.7), - 'Adelaide' => array('latitude' => -34.9333333, 'longitude' => 138.6), - 'Algiers' => array('latitude' => 36.7630556, 'longitude' => 3.0505556), - 'Alofi' => array('latitude' => -19.0166667, 'longitude' => -169.9166667), - 'Amman' => array('latitude' => 31.95, 'longitude' => 35.9333333), - 'Amsterdam' => array('latitude' => 52.35, 'longitude' => 4.9166667), - 'Andorra la Vella' => array('latitude' => 42.5, 'longitude' => 1.5166667), - 'Ankara' => array('latitude' => 39.9272222, 'longitude' => 32.8644444), - 'Antananarivo' => array('latitude' => -18.9166667, 'longitude' => 47.5166667), - 'Apia' => array('latitude' => -13.8333333, 'longitude' => -171.7333333), - 'Ashgabat' => array('latitude' => 37.95, 'longitude' => 58.3833333), - 'Asmara' => array('latitude' => 15.3333333, 'longitude' => 38.9333333), - 'Astana' => array('latitude' => 51.1811111, 'longitude' => 71.4277778), - 'Asunción' => array('latitude' => -25.2666667, 'longitude' => -57.6666667), - 'Athens' => array('latitude' => 37.9833333, 'longitude' => 23.7333333), - 'Auckland' => array('latitude' => -36.8666667, 'longitude' => 174.7666667), - 'Avarua' => array('latitude' => -21.2, 'longitude' => -159.7666667), - 'Baghdad' => array('latitude' => 33.3386111, 'longitude' => 44.3938889), - 'Baku' => array('latitude' => 40.3952778, 'longitude' => 49.8822222), - 'Bamako' => array('latitude' => 12.65, 'longitude' => -8), - 'Bandar Seri Begawan' => array('latitude' => 4.8833333, 'longitude' => 114.9333333), - 'Bankok' => array('latitude' => 13.5833333, 'longitude' => 100.2166667), - 'Bangui' => array('latitude' => 4.3666667, 'longitude' => 18.5833333), - 'Banjul' => array('latitude' => 13.4530556, 'longitude' => -16.5775), - 'Basel' => array('latitude' => 47.5666667, 'longitude' => 7.6), - 'Basseterre' => array('latitude' => 17.3, 'longitude' => -62.7166667), - 'Beijing' => array('latitude' => 39.9288889, 'longitude' => 116.3883333), - 'Beirut' => array('latitude' => 33.8719444, 'longitude' => 35.5097222), - 'Belgrade' => array('latitude' => 44.8186111, 'longitude' => 20.4680556), - 'Belmopan' => array('latitude' => 17.25, 'longitude' => -88.7666667), - 'Berlin' => array('latitude' => 52.5166667, 'longitude' => 13.4), - 'Bern' => array('latitude' => 46.9166667, 'longitude' => 7.4666667), - 'Bishkek' => array('latitude' => 42.8730556, 'longitude' => 74.6002778), - 'Bissau' => array('latitude' => 11.85, 'longitude' => -15.5833333), - 'Bloemfontein' => array('latitude' => -29.1333333, 'longitude' => 26.2), - 'Bogotá' => array('latitude' => 4.6, 'longitude' => -74.0833333), - 'Brasilia' => array('latitude' => -15.7833333, 'longitude' => -47.9166667), - 'Bratislava' => array('latitude' => 48.15, 'longitude' => 17.1166667), - 'Brazzaville' => array('latitude' => -4.2591667, 'longitude' => 15.2847222), - 'Bridgetown' => array('latitude' => 13.1, 'longitude' => -59.6166667), - 'Brisbane' => array('latitude' => -27.5, 'longitude' => 153.0166667), - 'Brussels' => array('latitude' => 50.8333333, 'longitude' => 4.3333333), - 'Bucharest' => array('latitude' => 44.4333333, 'longitude' => 26.1), - 'Budapest' => array('latitude' => 47.5, 'longitude' => 19.0833333), - 'Buenos Aires' => array('latitude' => -34.5875, 'longitude' => -58.6725), - 'Bujumbura' => array('latitude' => -3.3761111, 'longitude' => 29.36), - 'Cairo' => array('latitude' => 30.05, 'longitude' => 31.25), - 'Calgary' => array('latitude' => 51.0833333, 'longitude' => -114.0833333), - 'Canberra' => array('latitude' => -35.2833333, 'longitude' => 149.2166667), - 'Cape Town' => array('latitude' => -33.9166667, 'longitude' => 18.4166667), - 'Caracas' => array('latitude' => 10.5, 'longitude' => -66.9166667), - 'Castries' => array('latitude' => 14, 'longitude' => -61), - 'Charlotte Amalie' => array('latitude' => 18.34389, 'longitude' => -64.93111), - 'Chicago' => array('latitude' => 41.85, 'longitude' => -87.65), - 'Chisinau' => array('latitude' => 47.055556, 'longitude' => 28.8575), - 'Cockburn Town' => array('latitude' => 21.4666667, 'longitude' => -71.1333333), - 'Colombo' => array('latitude' => 6.9319444, 'longitude' => 79.8477778), - 'Conakry' => array('latitude' => 9.5091667, 'longitude' => -13.7122222), - 'Copenhagen' => array('latitude' => 55.6666667, 'longitude' => 12.5833333), - 'Cotonou' => array('latitude' => 6.35, 'longitude' => 2.4333333), - 'Dakar' => array('latitude' => 14.6708333, 'longitude' => -17.4380556), - 'Damascus' => array('latitude' => 33.5, 'longitude' => 36.3), - 'Dar es Salaam' => array('latitude' => -6.8, 'longitude' => 39.2833333), - 'Dhaka' => array('latitude' => 23.7230556, 'longitude' => 90.4086111), - 'Dili' => array('latitude' => -8.5586111, 'longitude' => 125.5736111), - 'Djibouti' => array('latitude' => 11.595, 'longitude' => 43.1480556), - 'Dodoma' => array('latitude' => -6.1833333, 'longitude' => 35.75), - 'Doha' => array('latitude' => 25.2866667, 'longitude' => 51.5333333), - 'Dubai' => array('latitude' => 25.2522222, 'longitude' => 55.28), - 'Dublin' => array('latitude' => 53.3330556, 'longitude' => -6.2488889), - 'Dushanbe' => array('latitude' => 38.56, 'longitude' => 68.7738889 ), - 'Fagatogo' => array('latitude' => -14.2825, 'longitude' => -170.69), - 'Fongafale' => array('latitude' => -8.5166667, 'longitude' => 179.2166667), - 'Freetown' => array('latitude' => 8.49, 'longitude' => -13.2341667), - 'Gaborone' => array('latitude' => -24.6463889, 'longitude' => 25.9119444), - 'Geneva' => array('latitude' => 46.2, 'longitude' => 6.1666667), - 'George Town' => array('latitude' => 19.3, 'longitude' => -81.3833333), - 'Georgetown' => array('latitude' => 6.8, 'longitude' => -58.1666667), - 'Gibraltar' => array('latitude' => 36.1333333, 'longitude' => -5.35), - 'Glasgow' => array('latitude' => 55.8333333, 'longitude' => -4.25), - 'Guatemala la Nueva' => array('latitude' => 14.6211111, 'longitude' => -90.5269444), - 'Hagatna' => array('latitude' => 13.47417, 'longitude' => 144.74778), - 'The Hague' => array('latitude' => 52.0833333, 'longitude' => 4.3), - 'Hamilton' => array('latitude' => 32.2941667, 'longitude' => -64.7838889), - 'Hanoi' => array('latitude' => 21.0333333, 'longitude' => 105.85), - 'Harare' => array('latitude' => -17.8177778, 'longitude' => 31.0447222), - 'Havana' => array('latitude' => 23.1319444, 'longitude' => -82.3641667), - 'Helsinki' => array('latitude' => 60.1755556, 'longitude' => 24.9341667), - 'Honiara' => array('latitude' => -9.4333333, 'longitude' => 159.95), - 'Islamabad' => array('latitude' => 30.8486111, 'longitude' => 72.4944444), - 'Istanbul' => array('latitude' => 41.0186111, 'longitude' => 28.9647222), - 'Jakarta' => array('latitude' => -6.1744444, 'longitude' => 106.8294444), - 'Jamestown' => array('latitude' => -15.9333333, 'longitude' => -5.7166667), - 'Jerusalem' => array('latitude' => 31.7666667, 'longitude' => 35.2333333), - 'Johannesburg' => array('latitude' => -26.2, 'longitude' => 28.0833333), - 'Kabul' => array('latitude' => 34.5166667, 'longitude' => 69.1833333), - 'Kampala' => array('latitude' => 0.3155556, 'longitude' => 32.5655556), - 'Kathmandu' => array('latitude' => 27.7166667, 'longitude' => 85.3166667), - 'Khartoum' => array('latitude' => 15.5880556, 'longitude' => 32.5341667), - 'Kigali' => array('latitude' => -1.9536111, 'longitude' => 30.0605556), - 'Kingston' => array('latitude' => -29.05, 'longitude' => 167.95), - 'Kingstown' => array('latitude' => 13.1333333, 'longitude' => -61.2166667), - 'Kinshasa' => array('latitude' => -4.3, 'longitude' => 15.3), - 'Kolkata' => array('latitude' => 22.5697222, 'longitude' => 88.3697222), - 'Kuala Lumpur' => array('latitude' => 3.1666667, 'longitude' => 101.7), - 'Kuwait City' => array('latitude' => 29.3697222, 'longitude' => 47.9783333), - 'Kiev' => array('latitude' => 50.4333333, 'longitude' => 30.5166667), - 'La Paz' => array('latitude' => -16.5, 'longitude' => -68.15), - 'Libreville' => array('latitude' => 0.3833333, 'longitude' => 9.45), - 'Lilongwe' => array('latitude' => -13.9833333, 'longitude' => 33.7833333), - 'Lima' => array('latitude' => -12.05, 'longitude' => -77.05), - 'Lisbon' => array('latitude' => 38.7166667, 'longitude' => -9.1333333), - 'Ljubljana' => array('latitude' => 46.0552778, 'longitude' => 14.5144444), - 'Lobamba' => array('latitude' => -26.4666667, 'longitude' => 31.2), - 'Lomé' => array('latitude' => 9.7166667, 'longitude' => 38.3), - 'London' => array('latitude' => 51.5, 'longitude' => -0.1166667), - 'Los Angeles' => array('latitude' => 34.05222, 'longitude' => -118.24278), - 'Luanda' => array('latitude' => -8.8383333, 'longitude' => 13.2344444), - 'Lusaka' => array('latitude' => -15.4166667, 'longitude' => 28.2833333), - 'Luxembourg' => array('latitude' => 49.6116667, 'longitude' => 6.13), - 'Madrid' => array('latitude' => 40.4, 'longitude' => -3.6833333), - 'Majuro' => array('latitude' => 7.1, 'longitude' => 171.3833333), - 'Malabo' => array('latitude' => 3.75, 'longitude' => 8.7833333), - 'Managua' => array('latitude' => 12.1508333, 'longitude' => -86.2683333), - 'Manama' => array('latitude' => 26.2361111, 'longitude' => 50.5830556), - 'Manila' => array('latitude' => 14.6041667, 'longitude' => 120.9822222), - 'Maputo' => array('latitude' => -25.9652778, 'longitude' => 32.5891667), - 'Maseru' => array('latitude' => -29.3166667, 'longitude' => 27.4833333), - 'Mbabane' => array('latitude' => -26.3166667, 'longitude' => 31.1333333), - 'Melbourne' => array('latitude' => -37.8166667, 'longitude' => 144.9666667), - 'Melekeok' => array('latitude' => 7.4933333, 'longitude' => 134.6341667), - 'Mexiko City' => array('latitude' => 19.4341667, 'longitude' => -99.1386111), - 'Minsk' => array('latitude' => 53.9, 'longitude' => 27.5666667), - 'Mogadishu' => array('latitude' => 2.0666667, 'longitude' => 45.3666667), - 'Monaco' => array('latitude' => 43.7333333, 'longitude' => 7.4166667), - 'Monrovia' => array('latitude' => 6.3105556, 'longitude' => -10.8047222), - 'Montevideo' => array('latitude' => -34.8580556, 'longitude' => -56.1708333), - 'Montreal' => array('latitude' => 45.5, 'longitude' => -73.5833333), - 'Moroni' => array('latitude' => -11.7041667, 'longitude' => 43.2402778), - 'Moscow' => array('latitude' => 55.7522222, 'longitude' => 37.6155556), - 'Muscat' => array('latitude' => 23.6133333, 'longitude' => 58.5933333), - 'Nairobi' => array('latitude' => -1.3166667, 'longitude' => 36.8333333), - 'Nassau' => array('latitude' => 25.0833333, 'longitude' => -77.35), - 'N´Djamena' => array('latitude' => 12.1130556, 'longitude' => 15.0491667), - 'New Dehli' => array('latitude' => 28.6, 'longitude' => 77.2), - 'New York' => array('latitude' => 40.71417, 'longitude' => -74.00639), - 'Newcastle' => array('latitude' => -32.9166667, 'longitude' => 151.75), - 'Niamey' => array('latitude' => 13.6666667, 'longitude' => 1.7833333), - 'Nicosia' => array('latitude' => 35.1666667, 'longitude' => 33.3666667), - 'Nouakchott' => array('latitude' => 18.0863889, 'longitude' => -15.9752778), - 'Noumea' => array('latitude' => -22.2666667, 'longitude' => 166.45), - 'Nuku´alofa' => array('latitude' => -21.1333333, 'longitude' => -175.2), - 'Nuuk' => array('latitude' => 64.1833333, 'longitude' => -51.75), - 'Oranjestad' => array('latitude' => 12.5166667, 'longitude' => -70.0333333), - 'Oslo' => array('latitude' => 59.9166667, 'longitude' => 10.75), - 'Ouagadougou' => array('latitude' => 12.3702778, 'longitude' => -1.5247222), - 'Palikir' => array('latitude' => 6.9166667, 'longitude' => 158.15), - 'Panama City' => array('latitude' => 8.9666667, 'longitude' => -79.5333333), - 'Papeete' => array('latitude' => -17.5333333, 'longitude' => -149.5666667), - 'Paramaribo' => array('latitude' => 5.8333333, 'longitude' => -55.1666667), - 'Paris' => array('latitude' => 48.8666667, 'longitude' => 2.3333333), - 'Perth' => array('latitude' => -31.9333333, 'longitude' => 115.8333333), - 'Phnom Penh' => array('latitude' => 11.55, 'longitude' => 104.9166667), - 'Podgorica' => array('latitude' => 43.7752778, 'longitude' => 19.6827778), - 'Port Louis' => array('latitude' => -20.1666667, 'longitude' => 57.5), - 'Port Moresby' => array('latitude' => -9.4647222, 'longitude' => 147.1925), - 'Port-au-Prince' => array('latitude' => 18.5391667, 'longitude' => -72.335), - 'Port of Spain' => array('latitude' => 10.6666667, 'longitude' => -61.5), - 'Porto-Novo' => array('latitude' => 6.4833333, 'longitude' => 2.6166667), - 'Prague' => array('latitude' => 50.0833333, 'longitude' => 14.4666667), - 'Praia' => array('latitude' => 14.9166667, 'longitude' => -23.5166667), - 'Pretoria' => array('latitude' => -25.7069444, 'longitude' => 28.2294444), - 'Pyongyang' => array('latitude' => 39.0194444, 'longitude' => 125.7547222), - 'Quito' => array('latitude' => -0.2166667, 'longitude' => -78.5), - 'Rabat' => array('latitude' => 34.0252778, 'longitude' => -6.8361111), - 'Reykjavik' => array('latitude' => 64.15, 'longitude' => -21.95), - 'Riga' => array('latitude' => 56.95, 'longitude' => 24.1), - 'Rio de Janero' => array('latitude' => -22.9, 'longitude' => -43.2333333), - 'Road Town' => array('latitude' => 18.4166667, 'longitude' => -64.6166667), - 'Rome' => array('latitude' => 41.9, 'longitude' => 12.4833333), - 'Roseau' => array('latitude' => 15.3, 'longitude' => -61.4), - 'Rotterdam' => array('latitude' => 51.9166667, 'longitude' => 4.5), - 'Salvador' => array('latitude' => -12.9833333, 'longitude' => -38.5166667), - 'San José' => array('latitude' => 9.9333333, 'longitude' => -84.0833333), - 'San Juan' => array('latitude' => 18.46833, 'longitude' => -66.10611), - 'San Marino' => array('latitude' => 43.5333333, 'longitude' => 12.9666667), - 'San Salvador' => array('latitude' => 13.7086111, 'longitude' => -89.2030556), - 'Sanaá' => array('latitude' => 15.3547222, 'longitude' => 44.2066667), - 'Santa Cruz' => array('latitude' => -17.8, 'longitude' => -63.1666667), - 'Santiago' => array('latitude' => -33.45, 'longitude' => -70.6666667), - 'Santo Domingo' => array('latitude' => 18.4666667, 'longitude' => -69.9), - 'Sao Paulo' => array('latitude' => -23.5333333, 'longitude' => -46.6166667), - 'Sarajevo' => array('latitude' => 43.85, 'longitude' => 18.3833333), - 'Seoul' => array('latitude' => 37.5663889, 'longitude' => 126.9997222), - 'Shanghai' => array('latitude' => 31.2222222, 'longitude' => 121.4580556), - 'Sydney' => array('latitude' => -33.8833333, 'longitude' => 151.2166667), - 'Singapore' => array('latitude' => 1.2930556, 'longitude' => 103.8558333), - 'Skopje' => array('latitude' => 42, 'longitude' => 21.4333333), - 'Sofia' => array('latitude' => 42.6833333, 'longitude' => 23.3166667), - 'St. George´s' => array('latitude' => 12.05, 'longitude' => -61.75), - 'St. John´s' => array('latitude' => 17.1166667, 'longitude' => -61.85), - 'Stanley' => array('latitude' => -51.7, 'longitude' => -57.85), - 'Stockholm' => array('latitude' => 59.3333333, 'longitude' => 18.05), - 'Suva' => array('latitude' => -18.1333333, 'longitude' => 178.4166667), - 'Taipei' => array('latitude' => 25.0166667, 'longitude' => 121.45), - 'Tallinn' => array('latitude' => 59.4338889, 'longitude' => 24.7280556), - 'Tashkent' => array('latitude' => 41.3166667, 'longitude' => 69.25), - 'Tbilisi' => array('latitude' => 41.725, 'longitude' => 44.7908333), - 'Tegucigalpa' => array('latitude' => 14.1, 'longitude' => -87.2166667), - 'Tehran' => array('latitude' => 35.6719444, 'longitude' => 51.4244444), - 'The Hague' => array('latitude' => 52.0833333, 'longitude' => 4.3), - 'Thimphu' => array('latitude' => 27.4833333, 'longitude' => 89.6), - 'Tirana' => array('latitude' => 41.3275, 'longitude' => 19.8188889), - 'Tiraspol' => array('latitude' => 46.8402778, 'longitude' => 29.6433333), - 'Tokyo' => array('latitude' => 35.685, 'longitude' => 139.7513889), - 'Toronto' => array('latitude' => 43.6666667, 'longitude' => -79.4166667), - 'Tórshavn' => array('latitude' => 62.0166667, 'longitude' => -6.7666667), - 'Tripoli' => array('latitude' => 32.8925, 'longitude' => 13.18), - 'Tunis' => array('latitude' => 36.8027778, 'longitude' => 10.1797222), - 'Ulaanbaatar' => array('latitude' => 47.9166667, 'longitude' => 106.9166667), - 'Vaduz' => array('latitude' => 47.1333333, 'longitude' => 9.5166667), - 'Valletta' => array('latitude' => 35.8997222, 'longitude' => 14.5147222), - 'Valparaiso' => array('latitude' => -33.0477778, 'longitude' => -71.6011111), - 'Vancouver' => array('latitude' => 49.25, 'longitude' => -123.1333333), - 'Vatican City' => array('latitude' => 41.9, 'longitude' => 12.4833333), - 'Victoria' => array('latitude' => -4.6166667, 'longitude' => 55.45), - 'Vienna' => array('latitude' => 48.2, 'longitude' => 16.3666667), - 'Vientaine' => array('latitude' => 17.9666667, 'longitude' => 102.6), - 'Vilnius' => array('latitude' => 54.6833333, 'longitude' => 25.3166667), - 'Warsaw' => array('latitude' => 52.25, 'longitude' => 21), - 'Washington dc' => array('latitude' => 38.895, 'longitude' => -77.03667), - 'Wellington' => array('latitude' => -41.3, 'longitude' => 174.7833333), - 'Willemstad' => array('latitude' => 12.1, 'longitude' => -68.9166667), - 'Windhoek' => array('latitude' => -22.57, 'longitude' => 17.0836111), - 'Yamoussoukro' => array('latitude' => 6.8166667, 'longitude' => -5.2833333), - 'Yaoundé' => array('latitude' => 3.8666667, 'longitude' => 11.5166667), - 'Yerevan' => array('latitude' => 40.1811111, 'longitude' => 44.5136111), - 'Zürich' => array('latitude' => 47.3666667, 'longitude' => 8.55), - 'Zagreb' => array('latitude' => 45.8, 'longitude' => 16) - ); - - /** - * Returns the location from the selected city - * - * @param string $city City to get location for - * @param string $horizon Horizon to use : - * default: effective - * others are civil, nautic, astronomic - * @return array - * @throws Zend_Date_Exception When city is unknown - */ - public static function City($city, $horizon = false) - { - foreach (self::$cities as $key => $value) { - if (strtolower($key) === strtolower($city)) { - $return = $value; - $return['horizon'] = $horizon; - return $return; - } - } - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('unknown city'); - } - - /** - * Return a list with all known cities - * - * @return array - */ - public static function getCityList() - { - return array_keys(self::$cities); - } -} diff --git a/lib/Zend/Date/DateObject.php b/lib/Zend/Date/DateObject.php deleted file mode 100644 index 5628429ee11..00000000000 --- a/lib/Zend/Date/DateObject.php +++ /dev/null @@ -1,1096 +0,0 @@ - 0, 1960 => -315619200, 1950 => -631152000, - 1940 => -946771200, 1930 => -1262304000, 1920 => -1577923200, - 1910 => -1893456000, 1900 => -2208988800, 1890 => -2524521600, - 1880 => -2840140800, 1870 => -3155673600, 1860 => -3471292800, - 1850 => -3786825600, 1840 => -4102444800, 1830 => -4417977600, - 1820 => -4733596800, 1810 => -5049129600, 1800 => -5364662400, - 1790 => -5680195200, 1780 => -5995814400, 1770 => -6311347200, - 1760 => -6626966400, 1750 => -6942499200, 1740 => -7258118400, - 1730 => -7573651200, 1720 => -7889270400, 1710 => -8204803200, - 1700 => -8520336000, 1690 => -8835868800, 1680 => -9151488000, - 1670 => -9467020800, 1660 => -9782640000, 1650 => -10098172800, - 1640 => -10413792000, 1630 => -10729324800, 1620 => -11044944000, - 1610 => -11360476800, 1600 => -11676096000); - - /** - * Set this object to have a new UNIX timestamp. - * - * @param string|integer $timestamp OPTIONAL timestamp; defaults to local time using time() - * @return string|integer old timestamp - * @throws Zend_Date_Exception - */ - protected function setUnixTimestamp($timestamp = null) - { - $old = $this->_unixTimestamp; - - if (is_numeric($timestamp)) { - $this->_unixTimestamp = $timestamp; - } else if ($timestamp === null) { - $this->_unixTimestamp = time(); - } else { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception('\'' . $timestamp . '\' is not a valid UNIX timestamp', 0, null, $timestamp); - } - - return $old; - } - - /** - * Returns this object's UNIX timestamp - * A timestamp greater then the integer range will be returned as string - * This function does not return the timestamp as object. Use copy() instead. - * - * @return integer|string timestamp - */ - protected function getUnixTimestamp() - { - if ($this->_unixTimestamp === intval($this->_unixTimestamp)) { - return (int) $this->_unixTimestamp; - } else { - return (string) $this->_unixTimestamp; - } - } - - /** - * Internal function. - * Returns time(). This method exists to allow unit tests to work-around methods that might otherwise - * be hard-coded to use time(). For example, this makes it possible to test isYesterday() in Date.php. - * - * @param integer $sync OPTIONAL time syncronisation value - * @return integer timestamp - */ - protected function _getTime($sync = null) - { - if ($sync !== null) { - $this->_syncronised = round($sync); - } - return (time() + $this->_syncronised); - } - - /** - * Internal mktime function used by Zend_Date. - * The timestamp returned by mktime() can exceed the precision of traditional UNIX timestamps, - * by allowing PHP to auto-convert to using a float value. - * - * Returns a timestamp relative to 1970/01/01 00:00:00 GMT/UTC. - * DST (Summer/Winter) is depriciated since php 5.1.0. - * Year has to be 4 digits otherwise it would be recognised as - * year 70 AD instead of 1970 AD as expected !! - * - * @param integer $hour - * @param integer $minute - * @param integer $second - * @param integer $month - * @param integer $day - * @param integer $year - * @param boolean $gmt OPTIONAL true = other arguments are for UTC time, false = arguments are for local time/date - * @return integer|float timestamp (number of seconds elapsed relative to 1970/01/01 00:00:00 GMT/UTC) - */ - protected function mktime($hour, $minute, $second, $month, $day, $year, $gmt = false) - { - // complete date but in 32bit timestamp - use PHP internal - if ((1901 < $year) and ($year < 2038)) { - - $oldzone = @date_default_timezone_get(); - // Timezone also includes DST settings, therefor substracting the GMT offset is not enough - // We have to set the correct timezone to get the right value - if (($this->_timezone != $oldzone) and ($gmt === false)) { - date_default_timezone_set($this->_timezone); - } - $result = ($gmt) ? @gmmktime($hour, $minute, $second, $month, $day, $year) - : @mktime($hour, $minute, $second, $month, $day, $year); - date_default_timezone_set($oldzone); - - return $result; - } - - if ($gmt !== true) { - $second += $this->_offset; - } - - if (isset(self::$_cache)) { - $id = strtr('Zend_DateObject_mkTime_' . $this->_offset . '_' . $year.$month.$day.'_'.$hour.$minute.$second . '_'.(int)$gmt, '-','_'); - if ($result = self::$_cache->load($id)) { - return unserialize($result); - } - } - - // date to integer - $day = intval($day); - $month = intval($month); - $year = intval($year); - - // correct months > 12 and months < 1 - if ($month > 12) { - $overlap = floor($month / 12); - $year += $overlap; - $month -= $overlap * 12; - } else { - $overlap = ceil((1 - $month) / 12); - $year -= $overlap; - $month += $overlap * 12; - } - - $date = 0; - if ($year >= 1970) { - - // Date is after UNIX epoch - // go through leapyears - // add months from latest given year - for ($count = 1970; $count <= $year; $count++) { - - $leapyear = self::isYearLeapYear($count); - if ($count < $year) { - - $date += 365; - if ($leapyear === true) { - $date++; - } - - } else { - - for ($mcount = 0; $mcount < ($month - 1); $mcount++) { - $date += self::$_monthTable[$mcount]; - if (($leapyear === true) and ($mcount == 1)) { - $date++; - } - - } - } - } - - $date += $day - 1; - $date = (($date * 86400) + ($hour * 3600) + ($minute * 60) + $second); - } else { - - // Date is before UNIX epoch - // go through leapyears - // add months from latest given year - for ($count = 1969; $count >= $year; $count--) { - - $leapyear = self::isYearLeapYear($count); - if ($count > $year) - { - $date += 365; - if ($leapyear === true) - $date++; - } else { - - for ($mcount = 11; $mcount > ($month - 1); $mcount--) { - $date += self::$_monthTable[$mcount]; - if (($leapyear === true) and ($mcount == 2)) { - $date++; - } - - } - } - } - - $date += (self::$_monthTable[$month - 1] - $day); - $date = -(($date * 86400) + (86400 - (($hour * 3600) + ($minute * 60) + $second))); - - // gregorian correction for 5.Oct.1582 - if ($date < -12220185600) { - $date += 864000; - } else if ($date < -12219321600) { - $date = -12219321600; - } - } - - if (isset(self::$_cache)) { - if (self::$_cacheTags) { - self::$_cache->save( serialize($date), $id, array('Zend_Date')); - } else { - self::$_cache->save( serialize($date), $id); - } - } - - return $date; - } - - /** - * Returns true, if given $year is a leap year. - * - * @param integer $year - * @return boolean true, if year is leap year - */ - protected static function isYearLeapYear($year) - { - // all leapyears can be divided through 4 - if (($year % 4) != 0) { - return false; - } - - // all leapyears can be divided through 400 - if ($year % 400 == 0) { - return true; - } else if (($year > 1582) and ($year % 100 == 0)) { - return false; - } - - return true; - } - - /** - * Internal mktime function used by Zend_Date for handling 64bit timestamps. - * - * Returns a formatted date for a given timestamp. - * - * @param string $format format for output - * @param mixed $timestamp - * @param boolean $gmt OPTIONAL true = other arguments are for UTC time, false = arguments are for local time/date - * @return string - */ - protected function date($format, $timestamp = null, $gmt = false) - { - $oldzone = @date_default_timezone_get(); - if ($this->_timezone != $oldzone) { - date_default_timezone_set($this->_timezone); - } - - if ($timestamp === null) { - $result = ($gmt) ? @gmdate($format) : @date($format); - date_default_timezone_set($oldzone); - return $result; - } - - if (abs($timestamp) <= 0x7FFFFFFF) { - // See ZF-11992 - // "o" will sometimes resolve to the previous year (see - // http://php.net/date ; it's part of the ISO 8601 - // standard). However, this is not desired, so replacing - // all occurrences of "o" not preceded by a backslash - // with "Y" - $format = preg_replace('/(?_offset . '_'. $timestamp . '_'.(int)$gmt, '-','_'); - if ($result2 = self::$_cache->load($idstamp)) { - $timestamp = unserialize($result2); - $jump = true; - } - } - - // check on false or null alone fails - if (empty($gmt) and empty($jump)) { - $tempstamp = $timestamp; - if ($tempstamp > 0) { - while (abs($tempstamp) > 0x7FFFFFFF) { - $tempstamp -= (86400 * 23376); - } - - $dst = date("I", $tempstamp); - if ($dst === 1) { - $timestamp += 3600; - } - - $temp = date('Z', $tempstamp); - $timestamp += $temp; - } - - if (isset(self::$_cache)) { - if (self::$_cacheTags) { - self::$_cache->save( serialize($timestamp), $idstamp, array('Zend_Date')); - } else { - self::$_cache->save( serialize($timestamp), $idstamp); - } - } - } - - if (($timestamp < 0) and ($gmt !== true)) { - $timestamp -= $this->_offset; - } - - date_default_timezone_set($oldzone); - $date = $this->getDateParts($timestamp, true); - $length = strlen($format); - $output = ''; - - for ($i = 0; $i < $length; $i++) { - switch($format[$i]) { - // day formats - case 'd': // day of month, 2 digits, with leading zero, 01 - 31 - $output .= (($date['mday'] < 10) ? '0' . $date['mday'] : $date['mday']); - break; - - case 'D': // day of week, 3 letters, Mon - Sun - $output .= date('D', 86400 * (3 + self::dayOfWeek($date['year'], $date['mon'], $date['mday']))); - break; - - case 'j': // day of month, without leading zero, 1 - 31 - $output .= $date['mday']; - break; - - case 'l': // day of week, full string name, Sunday - Saturday - $output .= date('l', 86400 * (3 + self::dayOfWeek($date['year'], $date['mon'], $date['mday']))); - break; - - case 'N': // ISO 8601 numeric day of week, 1 - 7 - $day = self::dayOfWeek($date['year'], $date['mon'], $date['mday']); - if ($day == 0) { - $day = 7; - } - $output .= $day; - break; - - case 'S': // english suffix for day of month, st nd rd th - if (($date['mday'] % 10) == 1) { - $output .= 'st'; - } else if ((($date['mday'] % 10) == 2) and ($date['mday'] != 12)) { - $output .= 'nd'; - } else if (($date['mday'] % 10) == 3) { - $output .= 'rd'; - } else { - $output .= 'th'; - } - break; - - case 'w': // numeric day of week, 0 - 6 - $output .= self::dayOfWeek($date['year'], $date['mon'], $date['mday']); - break; - - case 'z': // day of year, 0 - 365 - $output .= $date['yday']; - break; - - - // week formats - case 'W': // ISO 8601, week number of year - $output .= $this->weekNumber($date['year'], $date['mon'], $date['mday']); - break; - - - // month formats - case 'F': // string month name, january - december - $output .= date('F', mktime(0, 0, 0, $date['mon'], 2, 1971)); - break; - - case 'm': // number of month, with leading zeros, 01 - 12 - $output .= (($date['mon'] < 10) ? '0' . $date['mon'] : $date['mon']); - break; - - case 'M': // 3 letter month name, Jan - Dec - $output .= date('M',mktime(0, 0, 0, $date['mon'], 2, 1971)); - break; - - case 'n': // number of month, without leading zeros, 1 - 12 - $output .= $date['mon']; - break; - - case 't': // number of day in month - $output .= self::$_monthTable[$date['mon'] - 1]; - break; - - - // year formats - case 'L': // is leap year ? - $output .= (self::isYearLeapYear($date['year'])) ? '1' : '0'; - break; - - case 'o': // ISO 8601 year number - $week = $this->weekNumber($date['year'], $date['mon'], $date['mday']); - if (($week > 50) and ($date['mon'] == 1)) { - $output .= ($date['year'] - 1); - } else { - $output .= $date['year']; - } - break; - - case 'Y': // year number, 4 digits - $output .= $date['year']; - break; - - case 'y': // year number, 2 digits - $output .= substr($date['year'], strlen($date['year']) - 2, 2); - break; - - - // time formats - case 'a': // lower case am/pm - $output .= (($date['hours'] >= 12) ? 'pm' : 'am'); - break; - - case 'A': // upper case am/pm - $output .= (($date['hours'] >= 12) ? 'PM' : 'AM'); - break; - - case 'B': // swatch internet time - $dayseconds = ($date['hours'] * 3600) + ($date['minutes'] * 60) + $date['seconds']; - if ($gmt === true) { - $dayseconds += 3600; - } - $output .= (int) (($dayseconds % 86400) / 86.4); - break; - - case 'g': // hours without leading zeros, 12h format - if ($date['hours'] > 12) { - $hour = $date['hours'] - 12; - } else { - if ($date['hours'] == 0) { - $hour = '12'; - } else { - $hour = $date['hours']; - } - } - $output .= $hour; - break; - - case 'G': // hours without leading zeros, 24h format - $output .= $date['hours']; - break; - - case 'h': // hours with leading zeros, 12h format - if ($date['hours'] > 12) { - $hour = $date['hours'] - 12; - } else { - if ($date['hours'] == 0) { - $hour = '12'; - } else { - $hour = $date['hours']; - } - } - $output .= (($hour < 10) ? '0'.$hour : $hour); - break; - - case 'H': // hours with leading zeros, 24h format - $output .= (($date['hours'] < 10) ? '0' . $date['hours'] : $date['hours']); - break; - - case 'i': // minutes with leading zeros - $output .= (($date['minutes'] < 10) ? '0' . $date['minutes'] : $date['minutes']); - break; - - case 's': // seconds with leading zeros - $output .= (($date['seconds'] < 10) ? '0' . $date['seconds'] : $date['seconds']); - break; - - - // timezone formats - case 'e': // timezone identifier - if ($gmt === true) { - $output .= gmdate('e', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } else { - $output .= date('e', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } - break; - - case 'I': // daylight saving time or not - if ($gmt === true) { - $output .= gmdate('I', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } else { - $output .= date('I', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } - break; - - case 'O': // difference to GMT in hours - $gmtstr = ($gmt === true) ? 0 : $this->getGmtOffset(); - $output .= sprintf('%s%04d', ($gmtstr <= 0) ? '+' : '-', abs($gmtstr) / 36); - break; - - case 'P': // difference to GMT with colon - $gmtstr = ($gmt === true) ? 0 : $this->getGmtOffset(); - $gmtstr = sprintf('%s%04d', ($gmtstr <= 0) ? '+' : '-', abs($gmtstr) / 36); - $output = $output . substr($gmtstr, 0, 3) . ':' . substr($gmtstr, 3); - break; - - case 'T': // timezone settings - if ($gmt === true) { - $output .= gmdate('T', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } else { - $output .= date('T', mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], 2000)); - } - break; - - case 'Z': // timezone offset in seconds - $output .= ($gmt === true) ? 0 : -$this->getGmtOffset(); - break; - - - // complete time formats - case 'c': // ISO 8601 date format - $difference = $this->getGmtOffset(); - $difference = sprintf('%s%04d', ($difference <= 0) ? '+' : '-', abs($difference) / 36); - $difference = substr($difference, 0, 3) . ':' . substr($difference, 3); - $output .= $date['year'] . '-' - . (($date['mon'] < 10) ? '0' . $date['mon'] : $date['mon']) . '-' - . (($date['mday'] < 10) ? '0' . $date['mday'] : $date['mday']) . 'T' - . (($date['hours'] < 10) ? '0' . $date['hours'] : $date['hours']) . ':' - . (($date['minutes'] < 10) ? '0' . $date['minutes'] : $date['minutes']) . ':' - . (($date['seconds'] < 10) ? '0' . $date['seconds'] : $date['seconds']) - . $difference; - break; - - case 'r': // RFC 2822 date format - $difference = $this->getGmtOffset(); - $difference = sprintf('%s%04d', ($difference <= 0) ? '+' : '-', abs($difference) / 36); - $output .= gmdate('D', 86400 * (3 + self::dayOfWeek($date['year'], $date['mon'], $date['mday']))) . ', ' - . (($date['mday'] < 10) ? '0' . $date['mday'] : $date['mday']) . ' ' - . date('M', mktime(0, 0, 0, $date['mon'], 2, 1971)) . ' ' - . $date['year'] . ' ' - . (($date['hours'] < 10) ? '0' . $date['hours'] : $date['hours']) . ':' - . (($date['minutes'] < 10) ? '0' . $date['minutes'] : $date['minutes']) . ':' - . (($date['seconds'] < 10) ? '0' . $date['seconds'] : $date['seconds']) . ' ' - . $difference; - break; - - case 'U': // Unix timestamp - $output .= $origstamp; - break; - - - // special formats - case "\\": // next letter to print with no format - $i++; - if ($i < $length) { - $output .= $format[$i]; - } - break; - - default: // letter is no format so add it direct - $output .= $format[$i]; - break; - } - } - - return (string) $output; - } - - /** - * Returns the day of week for a Gregorian calendar date. - * 0 = sunday, 6 = saturday - * - * @param integer $year - * @param integer $month - * @param integer $day - * @return integer dayOfWeek - */ - protected static function dayOfWeek($year, $month, $day) - { - if ((1901 < $year) and ($year < 2038)) { - return (int) date('w', mktime(0, 0, 0, $month, $day, $year)); - } - - // gregorian correction - $correction = 0; - if (($year < 1582) || (($year == 1582) and (($month < 10) || (($month == 10) && ($day < 15))))) { - $correction = 3; - } - - if ($month > 2) { - $month -= 2; - } else { - $month += 10; - $year--; - } - - $day = floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4); - $day += floor(($year / 100) / 4) - 2 * floor($year / 100) + 77 + $correction; - - return (int) ($day - 7 * floor($day / 7)); - } - - /** - * Internal getDateParts function for handling 64bit timestamps, similar to: - * http://www.php.net/getdate - * - * Returns an array of date parts for $timestamp, relative to 1970/01/01 00:00:00 GMT/UTC. - * - * $fast specifies ALL date parts should be returned (slower) - * Default is false, and excludes $dayofweek, weekday, month and timestamp from parts returned. - * - * @param mixed $timestamp - * @param boolean $fast OPTIONAL defaults to fast (false), resulting in fewer date parts - * @return array - */ - protected function getDateParts($timestamp = null, $fast = null) - { - - // actual timestamp - if (!is_numeric($timestamp)) { - return getdate(); - } - - // 32bit timestamp - if (abs($timestamp) <= 0x7FFFFFFF) { - return @getdate((int) $timestamp); - } - - if (isset(self::$_cache)) { - $id = strtr('Zend_DateObject_getDateParts_' . $timestamp.'_'.(int)$fast, '-','_'); - if ($result = self::$_cache->load($id)) { - return unserialize($result); - } - } - - $otimestamp = $timestamp; - $numday = 0; - $month = 0; - // gregorian correction - if ($timestamp < -12219321600) { - $timestamp -= 864000; - } - - // timestamp lower 0 - if ($timestamp < 0) { - $sec = 0; - $act = 1970; - - // iterate through 10 years table, increasing speed - foreach(self::$_yearTable as $year => $seconds) { - if ($timestamp >= $seconds) { - $i = $act; - break; - } - $sec = $seconds; - $act = $year; - } - - $timestamp -= $sec; - if (!isset($i)) { - $i = $act; - } - - // iterate the max last 10 years - do { - --$i; - $day = $timestamp; - - $timestamp += 31536000; - $leapyear = self::isYearLeapYear($i); - if ($leapyear === true) { - $timestamp += 86400; - } - - if ($timestamp >= 0) { - $year = $i; - break; - } - } while ($timestamp < 0); - - $secondsPerYear = 86400 * ($leapyear ? 366 : 365) + $day; - - $timestamp = $day; - // iterate through months - for ($i = 12; --$i >= 0;) { - $day = $timestamp; - - $timestamp += self::$_monthTable[$i] * 86400; - if (($leapyear === true) and ($i == 1)) { - $timestamp += 86400; - } - - if ($timestamp >= 0) { - $month = $i; - $numday = self::$_monthTable[$i]; - if (($leapyear === true) and ($i == 1)) { - ++$numday; - } - break; - } - } - - $timestamp = $day; - $numberdays = $numday + ceil(($timestamp + 1) / 86400); - - $timestamp += ($numday - $numberdays + 1) * 86400; - $hours = floor($timestamp / 3600); - } else { - - // iterate through years - for ($i = 1970;;$i++) { - $day = $timestamp; - - $timestamp -= 31536000; - $leapyear = self::isYearLeapYear($i); - if ($leapyear === true) { - $timestamp -= 86400; - } - - if ($timestamp < 0) { - $year = $i; - break; - } - } - - $secondsPerYear = $day; - - $timestamp = $day; - // iterate through months - for ($i = 0; $i <= 11; $i++) { - $day = $timestamp; - $timestamp -= self::$_monthTable[$i] * 86400; - - if (($leapyear === true) and ($i == 1)) { - $timestamp -= 86400; - } - - if ($timestamp < 0) { - $month = $i; - $numday = self::$_monthTable[$i]; - if (($leapyear === true) and ($i == 1)) { - ++$numday; - } - break; - } - } - - $timestamp = $day; - $numberdays = ceil(($timestamp + 1) / 86400); - $timestamp = $timestamp - ($numberdays - 1) * 86400; - $hours = floor($timestamp / 3600); - } - - $timestamp -= $hours * 3600; - - $month += 1; - $minutes = floor($timestamp / 60); - $seconds = $timestamp - $minutes * 60; - - if ($fast === true) { - $array = array( - 'seconds' => $seconds, - 'minutes' => $minutes, - 'hours' => $hours, - 'mday' => $numberdays, - 'mon' => $month, - 'year' => $year, - 'yday' => floor($secondsPerYear / 86400), - ); - } else { - - $dayofweek = self::dayOfWeek($year, $month, $numberdays); - $array = array( - 'seconds' => $seconds, - 'minutes' => $minutes, - 'hours' => $hours, - 'mday' => $numberdays, - 'wday' => $dayofweek, - 'mon' => $month, - 'year' => $year, - 'yday' => floor($secondsPerYear / 86400), - 'weekday' => gmdate('l', 86400 * (3 + $dayofweek)), - 'month' => gmdate('F', mktime(0, 0, 0, $month, 1, 1971)), - 0 => $otimestamp - ); - } - - if (isset(self::$_cache)) { - if (self::$_cacheTags) { - self::$_cache->save( serialize($array), $id, array('Zend_Date')); - } else { - self::$_cache->save( serialize($array), $id); - } - } - - return $array; - } - - /** - * Internal getWeekNumber function for handling 64bit timestamps - * - * Returns the ISO 8601 week number of a given date - * - * @param integer $year - * @param integer $month - * @param integer $day - * @return integer - */ - protected function weekNumber($year, $month, $day) - { - if ((1901 < $year) and ($year < 2038)) { - return (int) date('W', mktime(0, 0, 0, $month, $day, $year)); - } - - $dayofweek = self::dayOfWeek($year, $month, $day); - $firstday = self::dayOfWeek($year, 1, 1); - if (($month == 1) and (($firstday < 1) || ($firstday > 4)) and ($day < 4)) { - $firstday = self::dayOfWeek($year - 1, 1, 1); - $month = 12; - $day = 31; - - } else if (($month == 12) and ((self::dayOfWeek($year + 1, 1, 1) < 5) and - (self::dayOfWeek($year + 1, 1, 1) > 0))) { - return 1; - } - - return intval (((self::dayOfWeek($year, 1, 1) < 5) and (self::dayOfWeek($year, 1, 1) > 0)) + - 4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256); - } - - /** - * Internal _range function - * Sets the value $a to be in the range of [0, $b] - * - * @param float $a - value to correct - * @param float $b - maximum range to set - */ - private function _range($a, $b) { - while ($a < 0) { - $a += $b; - } - while ($a >= $b) { - $a -= $b; - } - return $a; - } - - /** - * Calculates the sunrise or sunset based on a location - * - * @param array $location Location for calculation MUST include 'latitude', 'longitude', 'horizon' - * @param bool $horizon true: sunrise; false: sunset - * @return mixed - false: midnight sun, integer: - */ - protected function calcSun($location, $horizon, $rise = false) - { - // timestamp within 32bit - if (abs($this->_unixTimestamp) <= 0x7FFFFFFF) { - if ($rise === false) { - return date_sunset($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location['latitude'], - $location['longitude'], 90 + $horizon, $this->getGmtOffset() / 3600); - } - return date_sunrise($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location['latitude'], - $location['longitude'], 90 + $horizon, $this->getGmtOffset() / 3600); - } - - // self calculation - timestamp bigger than 32bit - // fix circle values - $quarterCircle = 0.5 * M_PI; - $halfCircle = M_PI; - $threeQuarterCircle = 1.5 * M_PI; - $fullCircle = 2 * M_PI; - - // radiant conversion for coordinates - $radLatitude = $location['latitude'] * $halfCircle / 180; - $radLongitude = $location['longitude'] * $halfCircle / 180; - - // get solar coordinates - $tmpRise = $rise ? $quarterCircle : $threeQuarterCircle; - $radDay = $this->date('z',$this->_unixTimestamp) + ($tmpRise - $radLongitude) / $fullCircle; - - // solar anomoly and longitude - $solAnomoly = $radDay * 0.017202 - 0.0574039; - $solLongitude = $solAnomoly + 0.0334405 * sin($solAnomoly); - $solLongitude += 4.93289 + 3.49066E-4 * sin(2 * $solAnomoly); - - // get quadrant - $solLongitude = $this->_range($solLongitude, $fullCircle); - - if (($solLongitude / $quarterCircle) - intval($solLongitude / $quarterCircle) == 0) { - $solLongitude += 4.84814E-6; - } - - // solar ascension - $solAscension = sin($solLongitude) / cos($solLongitude); - $solAscension = atan2(0.91746 * $solAscension, 1); - - // adjust quadrant - if ($solLongitude > $threeQuarterCircle) { - $solAscension += $fullCircle; - } else if ($solLongitude > $quarterCircle) { - $solAscension += $halfCircle; - } - - // solar declination - $solDeclination = 0.39782 * sin($solLongitude); - $solDeclination /= sqrt(-$solDeclination * $solDeclination + 1); - $solDeclination = atan2($solDeclination, 1); - - $solHorizon = $horizon - sin($solDeclination) * sin($radLatitude); - $solHorizon /= cos($solDeclination) * cos($radLatitude); - - // midnight sun, always night - if (abs($solHorizon) > 1) { - return false; - } - - $solHorizon /= sqrt(-$solHorizon * $solHorizon + 1); - $solHorizon = $quarterCircle - atan2($solHorizon, 1); - - if ($rise) { - $solHorizon = $fullCircle - $solHorizon; - } - - // time calculation - $localTime = $solHorizon + $solAscension - 0.0172028 * $radDay - 1.73364; - $universalTime = $localTime - $radLongitude; - - // determinate quadrant - $universalTime = $this->_range($universalTime, $fullCircle); - - // radiant to hours - $universalTime *= 24 / $fullCircle; - - // convert to time - $hour = intval($universalTime); - $universalTime = ($universalTime - $hour) * 60; - $min = intval($universalTime); - $universalTime = ($universalTime - $min) * 60; - $sec = intval($universalTime); - - return $this->mktime($hour, $min, $sec, $this->date('m', $this->_unixTimestamp), - $this->date('j', $this->_unixTimestamp), $this->date('Y', $this->_unixTimestamp), - -1, true); - } - - /** - * Sets a new timezone for calculation of $this object's gmt offset. - * For a list of supported timezones look here: http://php.net/timezones - * If no timezone can be detected or the given timezone is wrong UTC will be set. - * - * @param string $zone OPTIONAL timezone for date calculation; defaults to date_default_timezone_get() - * @return Zend_Date_DateObject Provides fluent interface - * @throws Zend_Date_Exception - */ - public function setTimezone($zone = null) - { - $oldzone = @date_default_timezone_get(); - if ($zone === null) { - $zone = $oldzone; - } - - // throw an error on false input, but only if the new date extension is available - if (function_exists('timezone_open')) { - if (!@timezone_open($zone)) { - #require_once 'Zend/Date/Exception.php'; - throw new Zend_Date_Exception("timezone ($zone) is not a known timezone", 0, null, $zone); - } - } - // this can generate an error if the date extension is not available and a false timezone is given - $result = @date_default_timezone_set($zone); - if ($result === true) { - $this->_offset = mktime(0, 0, 0, 1, 2, 1970) - gmmktime(0, 0, 0, 1, 2, 1970); - $this->_timezone = $zone; - } - date_default_timezone_set($oldzone); - - if (($zone == 'UTC') || ($zone == 'GMT')) { - $this->_dst = false; - } else { - $this->_dst = true; - } - - return $this; - } - - /** - * Return the timezone of $this object. - * The timezone is initially set when the object is instantiated. - * - * @return string actual set timezone string - */ - public function getTimezone() - { - return $this->_timezone; - } - - /** - * Return the offset to GMT of $this object's timezone. - * The offset to GMT is initially set when the object is instantiated using the currently, - * in effect, default timezone for PHP functions. - * - * @return integer seconds difference between GMT timezone and timezone when object was instantiated - */ - public function getGmtOffset() - { - $date = $this->getDateParts($this->getUnixTimestamp(), true); - $zone = @date_default_timezone_get(); - $result = @date_default_timezone_set($this->_timezone); - if ($result === true) { - $offset = $this->mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], $date['year'], false) - - $this->mktime($date['hours'], $date['minutes'], $date['seconds'], - $date['mon'], $date['mday'], $date['year'], true); - } - date_default_timezone_set($zone); - - return $offset; - } - - /** - * Internal method to check if the given cache supports tags - * - * @param Zend_Cache $cache - */ - protected static function _getTagSupportForCache() - { - $backend = self::$_cache->getBackend(); - if ($backend instanceof Zend_Cache_Backend_ExtendedInterface) { - $cacheOptions = $backend->getCapabilities(); - self::$_cacheTags = $cacheOptions['tags']; - } else { - self::$_cacheTags = false; - } - - return self::$_cacheTags; - } -} diff --git a/lib/Zend/Date/Exception.php b/lib/Zend/Date/Exception.php deleted file mode 100644 index 9fdee9d79f7..00000000000 --- a/lib/Zend/Date/Exception.php +++ /dev/null @@ -1,49 +0,0 @@ -operand = $op; - parent::__construct($message, $code, $e); - } - - public function getOperand() - { - return $this->operand; - } -} diff --git a/lib/Zend/Db.php b/lib/Zend/Db.php deleted file mode 100644 index 456e715f21f..00000000000 --- a/lib/Zend/Db.php +++ /dev/null @@ -1,286 +0,0 @@ -toArray(); - } - - /* - * Convert Zend_Config argument to plain string - * adapter name and separate config object. - */ - if ($adapter instanceof Zend_Config) { - if (isset($adapter->params)) { - $config = $adapter->params->toArray(); - } - if (isset($adapter->adapter)) { - $adapter = (string) $adapter->adapter; - } else { - $adapter = null; - } - } - - /* - * Verify that adapter parameters are in an array. - */ - if (!is_array($config)) { - /** - * @see Zend_Db_Exception - */ - #require_once 'Zend/Db/Exception.php'; - throw new Zend_Db_Exception('Adapter parameters must be in an array or a Zend_Config object'); - } - - /* - * Verify that an adapter name has been specified. - */ - if (!is_string($adapter) || empty($adapter)) { - /** - * @see Zend_Db_Exception - */ - #require_once 'Zend/Db/Exception.php'; - throw new Zend_Db_Exception('Adapter name must be specified in a string'); - } - - /* - * Form full adapter class name - */ - $adapterNamespace = 'Zend_Db_Adapter'; - if (isset($config['adapterNamespace'])) { - if ($config['adapterNamespace'] != '') { - $adapterNamespace = $config['adapterNamespace']; - } - unset($config['adapterNamespace']); - } - - // Adapter no longer normalized- see http://framework.zend.com/issues/browse/ZF-5606 - $adapterName = $adapterNamespace . '_'; - $adapterName .= str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($adapter)))); - - /* - * Load the adapter class. This throws an exception - * if the specified class cannot be loaded. - */ - if (!class_exists($adapterName)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($adapterName); - } - - /* - * Create an instance of the adapter class. - * Pass the config to the adapter class constructor. - */ - $dbAdapter = new $adapterName($config); - - /* - * Verify that the object created is a descendent of the abstract adapter type. - */ - if (! $dbAdapter instanceof Zend_Db_Adapter_Abstract) { - /** - * @see Zend_Db_Exception - */ - #require_once 'Zend/Db/Exception.php'; - throw new Zend_Db_Exception("Adapter class '$adapterName' does not extend Zend_Db_Adapter_Abstract"); - } - - return $dbAdapter; - } - -} diff --git a/lib/Zend/Db/Adapter/Abstract.php b/lib/Zend/Db/Adapter/Abstract.php deleted file mode 100644 index 9df910f75ad..00000000000 --- a/lib/Zend/Db/Adapter/Abstract.php +++ /dev/null @@ -1,1280 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE - ); - - /** Weither or not that object can get serialized - * - * @var bool - */ - protected $_allowSerialization = true; - - /** - * Weither or not the database should be reconnected - * to that adapter when waking up - * - * @var bool - */ - protected $_autoReconnectOnUnserialize = false; - - /** - * Constructor. - * - * $config is an array of key/value pairs or an instance of Zend_Config - * containing configuration options. These options are common to most adapters: - * - * dbname => (string) The name of the database to user - * username => (string) Connect to the database as this username. - * password => (string) Password associated with the username. - * host => (string) What host to connect to, defaults to localhost - * - * Some options are used on a case-by-case basis by adapters: - * - * port => (string) The port of the database - * persistent => (boolean) Whether to use a persistent connection or not, defaults to false - * protocol => (string) The network protocol, defaults to TCPIP - * caseFolding => (int) style of case-alteration used for identifiers - * socket => (string) The socket or named pipe that should be used - * - * @param array|Zend_Config $config An array or instance of Zend_Config having configuration data - * @throws Zend_Db_Adapter_Exception - */ - public function __construct($config) - { - /* - * Verify that adapter parameters are in an array. - */ - if (!is_array($config)) { - /* - * Convert Zend_Config argument to a plain array. - */ - if ($config instanceof Zend_Config) { - $config = $config->toArray(); - } else { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception('Adapter parameters must be in an array or a Zend_Config object'); - } - } - - $this->_checkRequiredOptions($config); - - $options = array( - Zend_Db::CASE_FOLDING => $this->_caseFolding, - Zend_Db::AUTO_QUOTE_IDENTIFIERS => $this->_autoQuoteIdentifiers, - Zend_Db::FETCH_MODE => $this->_fetchMode, - ); - $driverOptions = array(); - - /* - * normalize the config and merge it with the defaults - */ - if (array_key_exists('options', $config)) { - // can't use array_merge() because keys might be integers - foreach ((array) $config['options'] as $key => $value) { - $options[$key] = $value; - } - } - if (array_key_exists('driver_options', $config)) { - if (!empty($config['driver_options'])) { - // can't use array_merge() because keys might be integers - foreach ((array) $config['driver_options'] as $key => $value) { - $driverOptions[$key] = $value; - } - } - } - - if (!isset($config['charset'])) { - $config['charset'] = null; - } - - if (!isset($config['persistent'])) { - $config['persistent'] = false; - } - - $this->_config = array_merge($this->_config, $config); - $this->_config['options'] = $options; - $this->_config['driver_options'] = $driverOptions; - - - // obtain the case setting, if there is one - if (array_key_exists(Zend_Db::CASE_FOLDING, $options)) { - $case = (int) $options[Zend_Db::CASE_FOLDING]; - switch ($case) { - case Zend_Db::CASE_LOWER: - case Zend_Db::CASE_UPPER: - case Zend_Db::CASE_NATURAL: - $this->_caseFolding = $case; - break; - default: - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception('Case must be one of the following constants: ' - . 'Zend_Db::CASE_NATURAL, Zend_Db::CASE_LOWER, Zend_Db::CASE_UPPER'); - } - } - - if (array_key_exists(Zend_Db::FETCH_MODE, $options)) { - if (is_string($options[Zend_Db::FETCH_MODE])) { - $constant = 'Zend_Db::FETCH_' . strtoupper($options[Zend_Db::FETCH_MODE]); - if(defined($constant)) { - $options[Zend_Db::FETCH_MODE] = constant($constant); - } - } - $this->setFetchMode((int) $options[Zend_Db::FETCH_MODE]); - } - - // obtain quoting property if there is one - if (array_key_exists(Zend_Db::AUTO_QUOTE_IDENTIFIERS, $options)) { - $this->_autoQuoteIdentifiers = (bool) $options[Zend_Db::AUTO_QUOTE_IDENTIFIERS]; - } - - // obtain allow serialization property if there is one - if (array_key_exists(Zend_Db::ALLOW_SERIALIZATION, $options)) { - $this->_allowSerialization = (bool) $options[Zend_Db::ALLOW_SERIALIZATION]; - } - - // obtain auto reconnect on unserialize property if there is one - if (array_key_exists(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE, $options)) { - $this->_autoReconnectOnUnserialize = (bool) $options[Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE]; - } - - // create a profiler object - $profiler = false; - if (array_key_exists(Zend_Db::PROFILER, $this->_config)) { - $profiler = $this->_config[Zend_Db::PROFILER]; - unset($this->_config[Zend_Db::PROFILER]); - } - $this->setProfiler($profiler); - } - - /** - * Check for config options that are mandatory. - * Throw exceptions if any are missing. - * - * @param array $config - * @throws Zend_Db_Adapter_Exception - */ - protected function _checkRequiredOptions(array $config) - { - // we need at least a dbname - if (! array_key_exists('dbname', $config)) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance"); - } - - if (! array_key_exists('password', $config)) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials"); - } - - if (! array_key_exists('username', $config)) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials"); - } - } - - /** - * Returns the underlying database connection object or resource. - * If not presently connected, this initiates the connection. - * - * @return object|resource|null - */ - public function getConnection() - { - $this->_connect(); - return $this->_connection; - } - - /** - * Returns the configuration variables in this adapter. - * - * @return array - */ - public function getConfig() - { - return $this->_config; - } - - /** - * Set the adapter's profiler object. - * - * The argument may be a boolean, an associative array, an instance of - * Zend_Db_Profiler, or an instance of Zend_Config. - * - * A boolean argument sets the profiler to enabled if true, or disabled if - * false. The profiler class is the adapter's default profiler class, - * Zend_Db_Profiler. - * - * An instance of Zend_Db_Profiler sets the adapter's instance to that - * object. The profiler is enabled and disabled separately. - * - * An associative array argument may contain any of the keys 'enabled', - * 'class', and 'instance'. The 'enabled' and 'instance' keys correspond to the - * boolean and object types documented above. The 'class' key is used to name a - * class to use for a custom profiler. The class must be Zend_Db_Profiler or a - * subclass. The class is instantiated with no constructor arguments. The 'class' - * option is ignored when the 'instance' option is supplied. - * - * An object of type Zend_Config may contain the properties 'enabled', 'class', and - * 'instance', just as if an associative array had been passed instead. - * - * @param Zend_Db_Profiler|Zend_Config|array|boolean $profiler - * @return Zend_Db_Adapter_Abstract Provides a fluent interface - * @throws Zend_Db_Profiler_Exception if the object instance or class specified - * is not Zend_Db_Profiler or an extension of that class. - */ - public function setProfiler($profiler) - { - $enabled = null; - $profilerClass = $this->_defaultProfilerClass; - $profilerInstance = null; - - if ($profilerIsObject = is_object($profiler)) { - if ($profiler instanceof Zend_Db_Profiler) { - $profilerInstance = $profiler; - } else if ($profiler instanceof Zend_Config) { - $profiler = $profiler->toArray(); - } else { - /** - * @see Zend_Db_Profiler_Exception - */ - #require_once 'Zend/Db/Profiler/Exception.php'; - throw new Zend_Db_Profiler_Exception('Profiler argument must be an instance of either Zend_Db_Profiler' - . ' or Zend_Config when provided as an object'); - } - } - - if (is_array($profiler)) { - if (isset($profiler['enabled'])) { - $enabled = (bool) $profiler['enabled']; - } - if (isset($profiler['class'])) { - $profilerClass = $profiler['class']; - } - if (isset($profiler['instance'])) { - $profilerInstance = $profiler['instance']; - } - } else if (!$profilerIsObject) { - $enabled = (bool) $profiler; - } - - if ($profilerInstance === null) { - if (!class_exists($profilerClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($profilerClass); - } - $profilerInstance = new $profilerClass(); - } - - if (!$profilerInstance instanceof Zend_Db_Profiler) { - /** @see Zend_Db_Profiler_Exception */ - #require_once 'Zend/Db/Profiler/Exception.php'; - throw new Zend_Db_Profiler_Exception('Class ' . get_class($profilerInstance) . ' does not extend ' - . 'Zend_Db_Profiler'); - } - - if (null !== $enabled) { - $profilerInstance->setEnabled($enabled); - } - - $this->_profiler = $profilerInstance; - - return $this; - } - - - /** - * Returns the profiler for this adapter. - * - * @return Zend_Db_Profiler - */ - public function getProfiler() - { - return $this->_profiler; - } - - /** - * Get the default statement class. - * - * @return string - */ - public function getStatementClass() - { - return $this->_defaultStmtClass; - } - - /** - * Set the default statement class. - * - * @return Zend_Db_Adapter_Abstract Fluent interface - */ - public function setStatementClass($class) - { - $this->_defaultStmtClass = $class; - return $this; - } - - /** - * Prepares and executes an SQL statement with bound data. - * - * @param mixed $sql The SQL statement with placeholders. - * May be a string or Zend_Db_Select. - * @param mixed $bind An array of data to bind to the placeholders. - * @return Zend_Db_Statement_Interface - */ - public function query($sql, $bind = array()) - { - // connect to the database if needed - $this->_connect(); - - // is the $sql a Zend_Db_Select object? - if ($sql instanceof Zend_Db_Select) { - if (empty($bind)) { - $bind = $sql->getBind(); - } - - $sql = $sql->assemble(); - } - - // make sure $bind to an array; - // don't use (array) typecasting because - // because $bind may be a Zend_Db_Expr object - if (!is_array($bind)) { - $bind = array($bind); - } - - // prepare and execute the statement with profiling - $stmt = $this->prepare($sql); - $stmt->execute($bind); - - // return the results embedded in the prepared statement object - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Leave autocommit mode and begin a transaction. - * - * @return Zend_Db_Adapter_Abstract - */ - public function beginTransaction() - { - $this->_connect(); - $q = $this->_profiler->queryStart('begin', Zend_Db_Profiler::TRANSACTION); - $this->_beginTransaction(); - $this->_profiler->queryEnd($q); - return $this; - } - - /** - * Commit a transaction and return to autocommit mode. - * - * @return Zend_Db_Adapter_Abstract - */ - public function commit() - { - $this->_connect(); - $q = $this->_profiler->queryStart('commit', Zend_Db_Profiler::TRANSACTION); - $this->_commit(); - $this->_profiler->queryEnd($q); - return $this; - } - - /** - * Roll back a transaction and return to autocommit mode. - * - * @return Zend_Db_Adapter_Abstract - */ - public function rollBack() - { - $this->_connect(); - $q = $this->_profiler->queryStart('rollback', Zend_Db_Profiler::TRANSACTION); - $this->_rollBack(); - $this->_profiler->queryEnd($q); - return $this; - } - - /** - * Inserts a table row with specified data. - * - * @param mixed $table The table to insert data into. - * @param array $bind Column-value pairs. - * @return int The number of affected rows. - * @throws Zend_Db_Adapter_Exception - */ - public function insert($table, array $bind) - { - // extract and quote col names from the array keys - $cols = array(); - $vals = array(); - $i = 0; - foreach ($bind as $col => $val) { - $cols[] = $this->quoteIdentifier($col, true); - if ($val instanceof Zend_Db_Expr) { - $vals[] = $val->__toString(); - unset($bind[$col]); - } else { - if ($this->supportsParameters('positional')) { - $vals[] = '?'; - } else { - if ($this->supportsParameters('named')) { - unset($bind[$col]); - $bind[':col'.$i] = $val; - $vals[] = ':col'.$i; - $i++; - } else { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding"); - } - } - } - } - - // build the statement - $sql = "INSERT INTO " - . $this->quoteIdentifier($table, true) - . ' (' . implode(', ', $cols) . ') ' - . 'VALUES (' . implode(', ', $vals) . ')'; - - // execute the statement and return the number of affected rows - if ($this->supportsParameters('positional')) { - $bind = array_values($bind); - } - $stmt = $this->query($sql, $bind); - $result = $stmt->rowCount(); - return $result; - } - - /** - * Updates table rows with specified data based on a WHERE clause. - * - * @param mixed $table The table to update. - * @param array $bind Column-value pairs. - * @param mixed $where UPDATE WHERE clause(s). - * @return int The number of affected rows. - * @throws Zend_Db_Adapter_Exception - */ - public function update($table, array $bind, $where = '') - { - /** - * Build "col = ?" pairs for the statement, - * except for Zend_Db_Expr which is treated literally. - */ - $set = array(); - $i = 0; - foreach ($bind as $col => $val) { - if ($val instanceof Zend_Db_Expr) { - $val = $val->__toString(); - unset($bind[$col]); - } else { - if ($this->supportsParameters('positional')) { - $val = '?'; - } else { - if ($this->supportsParameters('named')) { - unset($bind[$col]); - $bind[':col'.$i] = $val; - $val = ':col'.$i; - $i++; - } else { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding"); - } - } - } - $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val; - } - - $where = $this->_whereExpr($where); - - /** - * Build the UPDATE statement - */ - $sql = "UPDATE " - . $this->quoteIdentifier($table, true) - . ' SET ' . implode(', ', $set) - . (($where) ? " WHERE $where" : ''); - - /** - * Execute the statement and return the number of affected rows - */ - if ($this->supportsParameters('positional')) { - $stmt = $this->query($sql, array_values($bind)); - } else { - $stmt = $this->query($sql, $bind); - } - $result = $stmt->rowCount(); - return $result; - } - - /** - * Deletes table rows based on a WHERE clause. - * - * @param mixed $table The table to update. - * @param mixed $where DELETE WHERE clause(s). - * @return int The number of affected rows. - */ - public function delete($table, $where = '') - { - $where = $this->_whereExpr($where); - - /** - * Build the DELETE statement - */ - $sql = "DELETE FROM " - . $this->quoteIdentifier($table, true) - . (($where) ? " WHERE $where" : ''); - - /** - * Execute the statement and return the number of affected rows - */ - $stmt = $this->query($sql); - $result = $stmt->rowCount(); - return $result; - } - - /** - * Convert an array, string, or Zend_Db_Expr object - * into a string to put in a WHERE clause. - * - * @param mixed $where - * @return string - */ - protected function _whereExpr($where) - { - if (empty($where)) { - return $where; - } - if (!is_array($where)) { - $where = array($where); - } - foreach ($where as $cond => &$term) { - // is $cond an int? (i.e. Not a condition) - if (is_int($cond)) { - // $term is the full condition - if ($term instanceof Zend_Db_Expr) { - $term = $term->__toString(); - } - } else { - // $cond is the condition with placeholder, - // and $term is quoted into the condition - $term = $this->quoteInto($cond, $term); - } - $term = '(' . $term . ')'; - } - - $where = implode(' AND ', $where); - return $where; - } - - /** - * Creates and returns a new Zend_Db_Select object for this adapter. - * - * @return Zend_Db_Select - */ - public function select() - { - return new Zend_Db_Select($this); - } - - /** - * Get the fetch mode. - * - * @return int - */ - public function getFetchMode() - { - return $this->_fetchMode; - } - - /** - * Fetches all SQL result rows as a sequential array. - * Uses the current fetchMode for the adapter. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @param mixed $fetchMode Override current fetch mode. - * @return array - */ - public function fetchAll($sql, $bind = array(), $fetchMode = null) - { - if ($fetchMode === null) { - $fetchMode = $this->_fetchMode; - } - $stmt = $this->query($sql, $bind); - $result = $stmt->fetchAll($fetchMode); - return $result; - } - - /** - * Fetches the first row of the SQL result. - * Uses the current fetchMode for the adapter. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @param mixed $fetchMode Override current fetch mode. - * @return mixed Array, object, or scalar depending on fetch mode. - */ - public function fetchRow($sql, $bind = array(), $fetchMode = null) - { - if ($fetchMode === null) { - $fetchMode = $this->_fetchMode; - } - $stmt = $this->query($sql, $bind); - $result = $stmt->fetch($fetchMode); - return $result; - } - - /** - * Fetches all SQL result rows as an associative array. - * - * The first column is the key, the entire row array is the - * value. You should construct the query to be sure that - * the first column contains unique values, or else - * rows with duplicate values in the first column will - * overwrite previous data. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @return array - */ - public function fetchAssoc($sql, $bind = array()) - { - $stmt = $this->query($sql, $bind); - $data = array(); - while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) { - $tmp = array_values(array_slice($row, 0, 1)); - $data[$tmp[0]] = $row; - } - return $data; - } - - /** - * Fetches the first column of all SQL result rows as an array. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @return array - */ - public function fetchCol($sql, $bind = array()) - { - $stmt = $this->query($sql, $bind); - $result = $stmt->fetchAll(Zend_Db::FETCH_COLUMN, 0); - return $result; - } - - /** - * Fetches all SQL result rows as an array of key-value pairs. - * - * The first column is the key, the second column is the - * value. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @return array - */ - public function fetchPairs($sql, $bind = array()) - { - $stmt = $this->query($sql, $bind); - $data = array(); - while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) { - $data[$row[0]] = $row[1]; - } - return $data; - } - - /** - * Fetches the first column of the first row of the SQL result. - * - * @param string|Zend_Db_Select $sql An SQL SELECT statement. - * @param mixed $bind Data to bind into SELECT placeholders. - * @return string - */ - public function fetchOne($sql, $bind = array()) - { - $stmt = $this->query($sql, $bind); - $result = $stmt->fetchColumn(0); - return $result; - } - - /** - * Quote a raw string. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value)) { - return $value; - } elseif (is_float($value)) { - return sprintf('%F', $value); - } - return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'"; - } - - /** - * Safely quotes a value for an SQL statement. - * - * If an array is passed as the value, the array values are quoted - * and then returned as a comma-separated string. - * - * @param Zend_Db_Select|Zend_Db_Expr|array|null|int|string|float $value OPTIONAL A single value to quote into the condition. - * @param null|string|int $type OPTIONAL The type of the given value e.g. Zend_Db::INT_TYPE, "INT" - * @return string An SQL-safe quoted value (or string of separated values). - */ - public function quote($value, $type = null) - { - $this->_connect(); - - if ($value instanceof Zend_Db_Select) { - return '(' . $value->assemble() . ')'; - } - - if ($value instanceof Zend_Db_Expr) { - return $value->__toString(); - } - - if (is_array($value)) { - foreach ($value as &$val) { - $val = $this->quote($val, $type); - } - return implode(', ', $value); - } - - if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) { - $quotedValue = '0'; - switch ($this->_numericDataTypes[$type]) { - case Zend_Db::INT_TYPE: // 32-bit integer - $quotedValue = (string) intval($value); - break; - case Zend_Db::BIGINT_TYPE: // 64-bit integer - // ANSI SQL-style hex literals (e.g. x'[\dA-F]+') - // are not supported here, because these are string - // literals, not numeric literals. - if (preg_match('/^( - [+-]? # optional sign - (?: - 0[Xx][\da-fA-F]+ # ODBC-style hexadecimal - |\d+ # decimal or octal, or MySQL ZEROFILL decimal - (?:[eE][+-]?\d+)? # optional exponent on decimals or octals - ) - )/x', - (string) $value, $matches)) { - $quotedValue = $matches[1]; - } - break; - case Zend_Db::FLOAT_TYPE: // float or decimal - $quotedValue = sprintf('%F', $value); - } - return $quotedValue; - } - - return $this->_quote($value); - } - - /** - * Quotes a value and places into a piece of text at a placeholder. - * - * The placeholder is a question-mark; all placeholders will be replaced - * with the quoted value. For example: - * - * - * $text = "WHERE date < ?"; - * $date = "2005-01-02"; - * $safe = $sql->quoteInto($text, $date); - * // $safe = "WHERE date < '2005-01-02'" - * - * - * @param string $text The text with a placeholder. - * @param Zend_Db_Select|Zend_Db_Expr|array|null|int|string|float $value OPTIONAL A single value to quote into the condition. - * @param null|string|int $type OPTIONAL The type of the given value e.g. Zend_Db::INT_TYPE, "INT" - * @param integer $count OPTIONAL count of placeholders to replace - * @return string An SQL-safe quoted value placed into the original text. - */ - public function quoteInto($text, $value, $type = null, $count = null) - { - if ($count === null) { - return str_replace('?', $this->quote($value, $type), $text); - } else { - return implode($this->quote($value, $type), explode('?', $text, $count + 1)); - } - } - - /** - * Quotes an identifier. - * - * Accepts a string representing a qualified indentifier. For Example: - * - * $adapter->quoteIdentifier('myschema.mytable') - * - * Returns: "myschema"."mytable" - * - * Or, an array of one or more identifiers that may form a qualified identifier: - * - * $adapter->quoteIdentifier(array('myschema','my.table')) - * - * Returns: "myschema"."my.table" - * - * The actual quote character surrounding the identifiers may vary depending on - * the adapter. - * - * @param string|array|Zend_Db_Expr $ident The identifier. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @return string The quoted identifier. - */ - public function quoteIdentifier($ident, $auto=false) - { - return $this->_quoteIdentifierAs($ident, null, $auto); - } - - /** - * Quote a column identifier and alias. - * - * @param string|array|Zend_Db_Expr $ident The identifier or expression. - * @param string $alias An alias for the column. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @return string The quoted identifier and alias. - */ - public function quoteColumnAs($ident, $alias, $auto=false) - { - return $this->_quoteIdentifierAs($ident, $alias, $auto); - } - - /** - * Quote a table identifier and alias. - * - * @param string|array|Zend_Db_Expr $ident The identifier or expression. - * @param string $alias An alias for the table. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @return string The quoted identifier and alias. - */ - public function quoteTableAs($ident, $alias = null, $auto = false) - { - return $this->_quoteIdentifierAs($ident, $alias, $auto); - } - - /** - * Quote an identifier and an optional alias. - * - * @param string|array|Zend_Db_Expr $ident The identifier or expression. - * @param string $alias An optional alias. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @param string $as The string to add between the identifier/expression and the alias. - * @return string The quoted identifier and alias. - */ - protected function _quoteIdentifierAs($ident, $alias = null, $auto = false, $as = ' AS ') - { - if ($ident instanceof Zend_Db_Expr) { - $quoted = $ident->__toString(); - } elseif ($ident instanceof Zend_Db_Select) { - $quoted = '(' . $ident->assemble() . ')'; - } else { - if (is_string($ident)) { - $ident = explode('.', $ident); - } - if (is_array($ident)) { - $segments = array(); - foreach ($ident as $segment) { - if ($segment instanceof Zend_Db_Expr) { - $segments[] = $segment->__toString(); - } else { - $segments[] = $this->_quoteIdentifier($segment, $auto); - } - } - if ($alias !== null && end($ident) == $alias) { - $alias = null; - } - $quoted = implode('.', $segments); - } else { - $quoted = $this->_quoteIdentifier($ident, $auto); - } - } - if ($alias !== null) { - $quoted .= $as . $this->_quoteIdentifier($alias, $auto); - } - return $quoted; - } - - /** - * Quote an identifier. - * - * @param string $value The identifier or expression. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @return string The quoted identifier and alias. - */ - protected function _quoteIdentifier($value, $auto=false) - { - if ($auto === false || $this->_autoQuoteIdentifiers === true) { - $q = $this->getQuoteIdentifierSymbol(); - return ($q . str_replace("$q", "$q$q", $value) . $q); - } - return $value; - } - - /** - * Returns the symbol the adapter uses for delimited identifiers. - * - * @return string - */ - public function getQuoteIdentifierSymbol() - { - return '"'; - } - - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function lastSequenceId($sequenceName) - { - return null; - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function nextSequenceId($sequenceName) - { - return null; - } - - /** - * Helper method to change the case of the strings used - * when returning result sets in FETCH_ASSOC and FETCH_BOTH - * modes. - * - * This is not intended to be used by application code, - * but the method must be public so the Statement class - * can invoke it. - * - * @param string $key - * @return string - */ - public function foldCase($key) - { - switch ($this->_caseFolding) { - case Zend_Db::CASE_LOWER: - $value = strtolower((string) $key); - break; - case Zend_Db::CASE_UPPER: - $value = strtoupper((string) $key); - break; - case Zend_Db::CASE_NATURAL: - default: - $value = (string) $key; - } - return $value; - } - - /** - * called when object is getting serialized - * This disconnects the DB object that cant be serialized - * - * @throws Zend_Db_Adapter_Exception - * @return array - */ - public function __sleep() - { - if ($this->_allowSerialization == false) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception( - get_class($this) . ' is not allowed to be serialized' - ); - } - $this->_connection = null; - - return array_keys( - array_diff_key(get_object_vars($this), array('_connection' => null)) - ); - } - - /** - * called when object is getting unserialized - * - * @return void - */ - public function __wakeup() - { - if ($this->_autoReconnectOnUnserialize == true) { - $this->getConnection(); - } - } - - /** - * Abstract Methods - */ - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - abstract public function listTables(); - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - abstract public function describeTable($tableName, $schemaName = null); - - /** - * Creates a connection to the database. - * - * @return void - */ - abstract protected function _connect(); - - /** - * Test if a connection is active - * - * @return boolean - */ - abstract public function isConnected(); - - /** - * Force the connection to close. - * - * @return void - */ - abstract public function closeConnection(); - - /** - * Prepare a statement and return a PDOStatement-like object. - * - * @param string|Zend_Db_Select $sql SQL query - * @return Zend_Db_Statement|PDOStatement - */ - abstract public function prepare($sql); - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - abstract public function lastInsertId($tableName = null, $primaryKey = null); - - /** - * Begin a transaction. - */ - abstract protected function _beginTransaction(); - - /** - * Commit a transaction. - */ - abstract protected function _commit(); - - /** - * Roll-back a transaction. - */ - abstract protected function _rollBack(); - - /** - * Set the fetch mode. - * - * @param integer $mode - * @return void - * @throws Zend_Db_Adapter_Exception - */ - abstract public function setFetchMode($mode); - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param mixed $sql - * @param integer $count - * @param integer $offset - * @return string - */ - abstract public function limit($sql, $count, $offset = 0); - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - abstract public function supportsParameters($type); - - /** - * Retrieve server version in PHP style - * - * @return string - */ - abstract public function getServerVersion(); -} diff --git a/lib/Zend/Db/Adapter/Db2.php b/lib/Zend/Db/Adapter/Db2.php deleted file mode 100644 index a4380b521a5..00000000000 --- a/lib/Zend/Db/Adapter/Db2.php +++ /dev/null @@ -1,840 +0,0 @@ - (string) Connect to the database as this username. - * password => (string) Password associated with the username. - * host => (string) What host to connect to (default 127.0.0.1) - * dbname => (string) The name of the database to user - * protocol => (string) Protocol to use, defaults to "TCPIP" - * port => (integer) Port number to use for TCP/IP if protocol is "TCPIP" - * persistent => (boolean) Set TRUE to use a persistent connection (db2_pconnect) - * os => (string) This should be set to 'i5' if the db is on an os400/i5 - * schema => (string) The default schema the connection should use - * - * @var array - */ - protected $_config = array( - 'dbname' => null, - 'username' => null, - 'password' => null, - 'host' => 'localhost', - 'port' => '50000', - 'protocol' => 'TCPIP', - 'persistent' => false, - 'os' => null, - 'schema' => null - ); - - /** - * Execution mode - * - * @var int execution flag (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF) - */ - protected $_execute_mode = DB2_AUTOCOMMIT_ON; - - /** - * Default class name for a DB statement. - * - * @var string - */ - protected $_defaultStmtClass = 'Zend_Db_Statement_Db2'; - protected $_isI5 = false; - - /** - * Keys are UPPERCASE SQL datatypes or the constants - * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE. - * - * Values are: - * 0 = 32-bit integer - * 1 = 64-bit integer - * 2 = float or decimal - * - * @var array Associative array of datatypes to values 0, 1, or 2. - */ - protected $_numericDataTypes = array( - Zend_Db::INT_TYPE => Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INTEGER' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'NUMERIC' => Zend_Db::FLOAT_TYPE - ); - - /** - * Creates a connection resource. - * - * @return void - */ - protected function _connect() - { - if (is_resource($this->_connection)) { - // connection already exists - return; - } - - if (!extension_loaded('ibm_db2')) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception('The IBM DB2 extension is required for this adapter but the extension is not loaded'); - } - - $this->_determineI5(); - if ($this->_config['persistent']) { - // use persistent connection - $conn_func_name = 'db2_pconnect'; - } else { - // use "normal" connection - $conn_func_name = 'db2_connect'; - } - - if (!isset($this->_config['driver_options']['autocommit'])) { - // set execution mode - $this->_config['driver_options']['autocommit'] = &$this->_execute_mode; - } - - if (isset($this->_config['options'][Zend_Db::CASE_FOLDING])) { - $caseAttrMap = array( - Zend_Db::CASE_NATURAL => DB2_CASE_NATURAL, - Zend_Db::CASE_UPPER => DB2_CASE_UPPER, - Zend_Db::CASE_LOWER => DB2_CASE_LOWER - ); - $this->_config['driver_options']['DB2_ATTR_CASE'] = $caseAttrMap[$this->_config['options'][Zend_Db::CASE_FOLDING]]; - } - - if ($this->_isI5 && isset($this->_config['driver_options']['i5_naming'])) { - if ($this->_config['driver_options']['i5_naming']) { - $this->_config['driver_options']['i5_naming'] = DB2_I5_NAMING_ON; - } else { - $this->_config['driver_options']['i5_naming'] = DB2_I5_NAMING_OFF; - } - } - - if ($this->_config['host'] !== 'localhost' && !$this->_isI5) { - // if the host isn't localhost, use extended connection params - $dbname = 'DRIVER={IBM DB2 ODBC DRIVER}' . - ';DATABASE=' . $this->_config['dbname'] . - ';HOSTNAME=' . $this->_config['host'] . - ';PORT=' . $this->_config['port'] . - ';PROTOCOL=' . $this->_config['protocol'] . - ';UID=' . $this->_config['username'] . - ';PWD=' . $this->_config['password'] .';'; - $this->_connection = $conn_func_name( - $dbname, - null, - null, - $this->_config['driver_options'] - ); - } else { - // host is localhost, so use standard connection params - $this->_connection = $conn_func_name( - $this->_config['dbname'], - $this->_config['username'], - $this->_config['password'], - $this->_config['driver_options'] - ); - } - - // check the connection - if (!$this->_connection) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception(db2_conn_errormsg(), db2_conn_error()); - } - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return ((bool) (is_resource($this->_connection) - && get_resource_type($this->_connection) == 'DB2 Connection')); - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - if ($this->isConnected()) { - db2_close($this->_connection); - } - $this->_connection = null; - } - - /** - * Returns an SQL statement for preparation. - * - * @param string $sql The SQL statement with placeholders. - * @return Zend_Db_Statement_Db2 - */ - public function prepare($sql) - { - $this->_connect(); - $stmtClass = $this->_defaultStmtClass; - if (!class_exists($stmtClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($stmtClass); - } - $stmt = new $stmtClass($this, $sql); - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Gets the execution mode - * - * @return int the execution mode (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF) - */ - public function _getExecuteMode() - { - return $this->_execute_mode; - } - - /** - * @param integer $mode - * @return void - */ - public function _setExecuteMode($mode) - { - switch ($mode) { - case DB2_AUTOCOMMIT_OFF: - case DB2_AUTOCOMMIT_ON: - $this->_execute_mode = $mode; - db2_autocommit($this->_connection, $mode); - break; - default: - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception("execution mode not supported"); - break; - } - } - - /** - * Quote a raw string. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value) || is_float($value)) { - return $value; - } - /** - * Use db2_escape_string() if it is present in the IBM DB2 extension. - * But some supported versions of PHP do not include this function, - * so fall back to default quoting in the parent class. - */ - if (function_exists('db2_escape_string')) { - return "'" . db2_escape_string($value) . "'"; - } - return parent::_quote($value); - } - - /** - * @return string - */ - public function getQuoteIdentifierSymbol() - { - $this->_connect(); - $info = db2_server_info($this->_connection); - if ($info) { - $identQuote = $info->IDENTIFIER_QUOTE_CHAR; - } else { - // db2_server_info() does not return result on some i5 OS version - if ($this->_isI5) { - $identQuote ="'"; - } - } - return $identQuote; - } - - /** - * Returns a list of the tables in the database. - * @param string $schema OPTIONAL - * @return array - */ - public function listTables($schema = null) - { - $this->_connect(); - - if ($schema === null && $this->_config['schema'] != null) { - $schema = $this->_config['schema']; - } - - $tables = array(); - - if (!$this->_isI5) { - if ($schema) { - $stmt = db2_tables($this->_connection, null, $schema); - } else { - $stmt = db2_tables($this->_connection); - } - while ($row = db2_fetch_assoc($stmt)) { - $tables[] = $row['TABLE_NAME']; - } - } else { - $tables = $this->_i5listTables($schema); - } - - return $tables; - } - - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * DB2 not supports UNSIGNED integer. - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - // Ensure the connection is made so that _isI5 is set - $this->_connect(); - - if ($schemaName === null && $this->_config['schema'] != null) { - $schemaName = $this->_config['schema']; - } - - if (!$this->_isI5) { - - $sql = "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno, - c.typename, c.default, c.nulls, c.length, c.scale, - c.identity, tc.type AS tabconsttype, k.colseq - FROM syscat.columns c - LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc - ON (k.tabschema = tc.tabschema - AND k.tabname = tc.tabname - AND tc.type = 'P')) - ON (c.tabschema = k.tabschema - AND c.tabname = k.tabname - AND c.colname = k.colname) - WHERE " - . $this->quoteInto('UPPER(c.tabname) = UPPER(?)', $tableName); - - if ($schemaName) { - $sql .= $this->quoteInto(' AND UPPER(c.tabschema) = UPPER(?)', $schemaName); - } - - $sql .= " ORDER BY c.colno"; - - } else { - - // DB2 On I5 specific query - $sql = "SELECT DISTINCT C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, C.ORDINAL_POSITION, - C.DATA_TYPE, C.COLUMN_DEFAULT, C.NULLS ,C.LENGTH, C.SCALE, LEFT(C.IDENTITY,1), - LEFT(tc.TYPE, 1) AS tabconsttype, k.COLSEQ - FROM QSYS2.SYSCOLUMNS C - LEFT JOIN (QSYS2.syskeycst k JOIN QSYS2.SYSCST tc - ON (k.TABLE_SCHEMA = tc.TABLE_SCHEMA - AND k.TABLE_NAME = tc.TABLE_NAME - AND LEFT(tc.type,1) = 'P')) - ON (C.TABLE_SCHEMA = k.TABLE_SCHEMA - AND C.TABLE_NAME = k.TABLE_NAME - AND C.COLUMN_NAME = k.COLUMN_NAME) - WHERE " - . $this->quoteInto('UPPER(C.TABLE_NAME) = UPPER(?)', $tableName); - - if ($schemaName) { - $sql .= $this->quoteInto(' AND UPPER(C.TABLE_SCHEMA) = UPPER(?)', $schemaName); - } - - $sql .= " ORDER BY C.ORDINAL_POSITION FOR FETCH ONLY"; - } - - $desc = array(); - $stmt = $this->query($sql); - - /** - * To avoid case issues, fetch using FETCH_NUM - */ - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - /** - * The ordering of columns is defined by the query so we can map - * to variables to improve readability - */ - $tabschema = 0; - $tabname = 1; - $colname = 2; - $colno = 3; - $typename = 4; - $default = 5; - $nulls = 6; - $length = 7; - $scale = 8; - $identityCol = 9; - $tabconstType = 10; - $colseq = 11; - - foreach ($result as $key => $row) { - list ($primary, $primaryPosition, $identity) = array(false, null, false); - if ($row[$tabconstType] == 'P') { - $primary = true; - $primaryPosition = $row[$colseq]; - } - /** - * In IBM DB2, an column can be IDENTITY - * even if it is not part of the PRIMARY KEY. - */ - if ($row[$identityCol] == 'Y') { - $identity = true; - } - - // only colname needs to be case adjusted - $desc[$this->foldCase($row[$colname])] = array( - 'SCHEMA_NAME' => $this->foldCase($row[$tabschema]), - 'TABLE_NAME' => $this->foldCase($row[$tabname]), - 'COLUMN_NAME' => $this->foldCase($row[$colname]), - 'COLUMN_POSITION' => (!$this->_isI5) ? $row[$colno]+1 : $row[$colno], - 'DATA_TYPE' => $row[$typename], - 'DEFAULT' => $row[$default], - 'NULLABLE' => (bool) ($row[$nulls] == 'Y'), - 'LENGTH' => $row[$length], - 'SCALE' => $row[$scale], - 'PRECISION' => ($row[$typename] == 'DECIMAL' ? $row[$length] : 0), - 'UNSIGNED' => false, - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - - return $desc; - } - - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function lastSequenceId($sequenceName) - { - $this->_connect(); - - if (!$this->_isI5) { - $quotedSequenceName = $this->quoteIdentifier($sequenceName, true); - $sql = 'SELECT PREVVAL FOR ' . $quotedSequenceName . ' AS VAL FROM SYSIBM.SYSDUMMY1'; - } else { - $quotedSequenceName = $sequenceName; - $sql = 'SELECT PREVVAL FOR ' . $this->quoteIdentifier($sequenceName, true) . ' AS VAL FROM QSYS2.QSQPTABL'; - } - - $value = $this->fetchOne($sql); - return (string) $value; - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - $sql = 'SELECT NEXTVAL FOR '.$this->quoteIdentifier($sequenceName, true).' AS VAL FROM SYSIBM.SYSDUMMY1'; - $value = $this->fetchOne($sql); - return (string) $value; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * The IDENTITY_VAL_LOCAL() function gives the last generated identity value - * in the current process, even if it was for a GENERATED column. - * - * @param string $tableName OPTIONAL - * @param string $primaryKey OPTIONAL - * @param string $idType OPTIONAL used for i5 platform to define sequence/idenity unique value - * @return string - */ - - public function lastInsertId($tableName = null, $primaryKey = null, $idType = null) - { - $this->_connect(); - - if ($this->_isI5) { - return (string) $this->_i5LastInsertId($tableName, $idType); - } - - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= "_$primaryKey"; - } - $sequenceName .= '_seq'; - return $this->lastSequenceId($sequenceName); - } - - $sql = 'SELECT IDENTITY_VAL_LOCAL() AS VAL FROM SYSIBM.SYSDUMMY1'; - $value = $this->fetchOne($sql); - return (string) $value; - } - - /** - * Begin a transaction. - * - * @return void - */ - protected function _beginTransaction() - { - $this->_setExecuteMode(DB2_AUTOCOMMIT_OFF); - } - - /** - * Commit a transaction. - * - * @return void - */ - protected function _commit() - { - if (!db2_commit($this->_connection)) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception( - db2_conn_errormsg($this->_connection), - db2_conn_error($this->_connection)); - } - - $this->_setExecuteMode(DB2_AUTOCOMMIT_ON); - } - - /** - * Rollback a transaction. - * - * @return void - */ - protected function _rollBack() - { - if (!db2_rollback($this->_connection)) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception( - db2_conn_errormsg($this->_connection), - db2_conn_error($this->_connection)); - } - $this->_setExecuteMode(DB2_AUTOCOMMIT_ON); - } - - /** - * Set the fetch mode. - * - * @param integer $mode - * @return void - * @throws Zend_Db_Adapter_Db2_Exception - */ - public function setFetchMode($mode) - { - switch ($mode) { - case Zend_Db::FETCH_NUM: // seq array - case Zend_Db::FETCH_ASSOC: // assoc array - case Zend_Db::FETCH_BOTH: // seq+assoc array - case Zend_Db::FETCH_OBJ: // object - $this->_fetchMode = $mode; - break; - case Zend_Db::FETCH_BOUND: // bound to PHP variable - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception('FETCH_BOUND is not supported yet'); - break; - default: - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception("Invalid fetch mode '$mode' specified"); - break; - } - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** - * @see Zend_Db_Adapter_Db2_Exception - */ - #require_once 'Zend/Db/Adapter/Db2/Exception.php'; - throw new Zend_Db_Adapter_Db2_Exception("LIMIT argument offset=$offset is not valid"); - } - - if ($offset == 0) { - $limit_sql = $sql . " FETCH FIRST $count ROWS ONLY"; - return $limit_sql; - } - - /** - * DB2 does not implement the LIMIT clause as some RDBMS do. - * We have to simulate it with subqueries and ROWNUM. - * Unfortunately because we use the column wildcard "*", - * this puts an extra column into the query result set. - */ - $limit_sql = "SELECT z2.* - FROM ( - SELECT ROW_NUMBER() OVER() AS \"ZEND_DB_ROWNUM\", z1.* - FROM ( - " . $sql . " - ) z1 - ) z2 - WHERE z2.zend_db_rownum BETWEEN " . ($offset+1) . " AND " . ($offset+$count); - return $limit_sql; - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - if ($type == 'positional') { - return true; - } - - // if its 'named' or anything else - return false; - } - - /** - * Retrieve server version in PHP style - * - * @return string - */ - public function getServerVersion() - { - $this->_connect(); - $server_info = db2_server_info($this->_connection); - if ($server_info !== false) { - $version = $server_info->DBMS_VER; - if ($this->_isI5) { - $version = (int) substr($version, 0, 2) . '.' . (int) substr($version, 2, 2) . '.' . (int) substr($version, 4); - } - return $version; - } else { - return null; - } - } - - /** - * Return whether or not this is running on i5 - * - * @return bool - */ - public function isI5() - { - if ($this->_isI5 === null) { - $this->_determineI5(); - } - - return (bool) $this->_isI5; - } - - /** - * Check the connection parameters according to verify - * type of used OS - * - * @return void - */ - protected function _determineI5() - { - // first us the compiled flag. - $this->_isI5 = (php_uname('s') == 'OS400') ? true : false; - - // if this is set, then us it - if (isset($this->_config['os'])){ - if (strtolower($this->_config['os']) === 'i5') { - $this->_isI5 = true; - } else { - // any other value passed in, its null - $this->_isI5 = false; - } - } - - } - - /** - * Db2 On I5 specific method - * - * Returns a list of the tables in the database . - * Used only for DB2/400. - * - * @return array - */ - protected function _i5listTables($schema = null) - { - //list of i5 libraries. - $tables = array(); - if ($schema) { - $tablesStatement = db2_tables($this->_connection, null, $schema); - while ($rowTables = db2_fetch_assoc($tablesStatement) ) { - if ($rowTables['TABLE_NAME'] !== null) { - $tables[] = $rowTables['TABLE_NAME']; - } - } - } else { - $schemaStatement = db2_tables($this->_connection); - while ($schema = db2_fetch_assoc($schemaStatement)) { - if ($schema['TABLE_SCHEM'] !== null) { - // list of the tables which belongs to the selected library - $tablesStatement = db2_tables($this->_connection, NULL, $schema['TABLE_SCHEM']); - if (is_resource($tablesStatement)) { - while ($rowTables = db2_fetch_assoc($tablesStatement) ) { - if ($rowTables['TABLE_NAME'] !== null) { - $tables[] = $rowTables['TABLE_NAME']; - } - } - } - } - } - } - - return $tables; - } - - protected function _i5LastInsertId($objectName = null, $idType = null) - { - - if ($objectName === null) { - $sql = 'SELECT IDENTITY_VAL_LOCAL() AS VAL FROM QSYS2.QSQPTABL'; - $value = $this->fetchOne($sql); - return $value; - } - - if (strtoupper($idType) === 'S'){ - //check i5_lib option - $sequenceName = $objectName; - return $this->lastSequenceId($sequenceName); - } - - //returns last identity value for the specified table - //if (strtoupper($idType) === 'I') { - $tableName = $objectName; - return $this->fetchOne('SELECT IDENTITY_VAL_LOCAL() from ' . $this->quoteIdentifier($tableName)); - } - -} - - diff --git a/lib/Zend/Db/Adapter/Db2/Exception.php b/lib/Zend/Db/Adapter/Db2/Exception.php deleted file mode 100644 index 8b30fb96468..00000000000 --- a/lib/Zend/Db/Adapter/Db2/Exception.php +++ /dev/null @@ -1,45 +0,0 @@ -getCode(); - } - parent::__construct($message, $code, $e); - } - - public function hasChainedException() - { - return ($this->getPrevious() !== null); - } - - public function getChainedException() - { - return $this->getPrevious(); - } - -} diff --git a/lib/Zend/Db/Adapter/Mysqli.php b/lib/Zend/Db/Adapter/Mysqli.php deleted file mode 100644 index 4e2747445f1..00000000000 --- a/lib/Zend/Db/Adapter/Mysqli.php +++ /dev/null @@ -1,556 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INT' => Zend_Db::INT_TYPE, - 'INTEGER' => Zend_Db::INT_TYPE, - 'MEDIUMINT' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'TINYINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'SERIAL' => Zend_Db::BIGINT_TYPE, - 'DEC' => Zend_Db::FLOAT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'DOUBLE' => Zend_Db::FLOAT_TYPE, - 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE, - 'FIXED' => Zend_Db::FLOAT_TYPE, - 'FLOAT' => Zend_Db::FLOAT_TYPE - ); - - /** - * @var Zend_Db_Statement_Mysqli - */ - protected $_stmt = null; - - /** - * Default class name for a DB statement. - * - * @var string - */ - protected $_defaultStmtClass = 'Zend_Db_Statement_Mysqli'; - - /** - * Quote a raw string. - * - * @param mixed $value Raw string - * - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value) || is_float($value)) { - return $value; - } - $this->_connect(); - return "'" . $this->_connection->real_escape_string($value) . "'"; - } - - /** - * Returns the symbol the adapter uses for delimiting identifiers. - * - * @return string - */ - public function getQuoteIdentifierSymbol() - { - return "`"; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $result = array(); - // Use mysqli extension API, because SHOW doesn't work - // well as a prepared statement on MySQL 4.1. - $sql = 'SHOW TABLES'; - if ($queryResult = $this->getConnection()->query($sql)) { - while ($row = $queryResult->fetch_row()) { - $result[] = $row[0]; - } - $queryResult->close(); - } else { - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error); - } - return $result; - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - /** - * @todo use INFORMATION_SCHEMA someday when - * MySQL's implementation isn't too slow. - */ - - if ($schemaName) { - $sql = 'DESCRIBE ' . $this->quoteIdentifier("$schemaName.$tableName", true); - } else { - $sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, true); - } - - /** - * Use mysqli extension API, because DESCRIBE doesn't work - * well as a prepared statement on MySQL 4.1. - */ - if ($queryResult = $this->getConnection()->query($sql)) { - while ($row = $queryResult->fetch_assoc()) { - $result[] = $row; - } - $queryResult->close(); - } else { - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error); - } - - $desc = array(); - - $row_defaults = array( - 'Length' => null, - 'Scale' => null, - 'Precision' => null, - 'Unsigned' => null, - 'Primary' => false, - 'PrimaryPosition' => null, - 'Identity' => false - ); - $i = 1; - $p = 1; - foreach ($result as $key => $row) { - $row = array_merge($row_defaults, $row); - if (preg_match('/unsigned/', $row['Type'])) { - $row['Unsigned'] = true; - } - if (preg_match('/^((?:var)?char)\((\d+)\)/', $row['Type'], $matches)) { - $row['Type'] = $matches[1]; - $row['Length'] = $matches[2]; - } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row['Type'], $matches)) { - $row['Type'] = 'decimal'; - $row['Precision'] = $matches[1]; - $row['Scale'] = $matches[2]; - } else if (preg_match('/^float\((\d+),(\d+)\)/', $row['Type'], $matches)) { - $row['Type'] = 'float'; - $row['Precision'] = $matches[1]; - $row['Scale'] = $matches[2]; - } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row['Type'], $matches)) { - $row['Type'] = $matches[1]; - /** - * The optional argument of a MySQL int type is not precision - * or length; it is only a hint for display width. - */ - } - if (strtoupper($row['Key']) == 'PRI') { - $row['Primary'] = true; - $row['PrimaryPosition'] = $p; - if ($row['Extra'] == 'auto_increment') { - $row['Identity'] = true; - } else { - $row['Identity'] = false; - } - ++$p; - } - $desc[$this->foldCase($row['Field'])] = array( - 'SCHEMA_NAME' => null, // @todo - 'TABLE_NAME' => $this->foldCase($tableName), - 'COLUMN_NAME' => $this->foldCase($row['Field']), - 'COLUMN_POSITION' => $i, - 'DATA_TYPE' => $row['Type'], - 'DEFAULT' => $row['Default'], - 'NULLABLE' => (bool) ($row['Null'] == 'YES'), - 'LENGTH' => $row['Length'], - 'SCALE' => $row['Scale'], - 'PRECISION' => $row['Precision'], - 'UNSIGNED' => $row['Unsigned'], - 'PRIMARY' => $row['Primary'], - 'PRIMARY_POSITION' => $row['PrimaryPosition'], - 'IDENTITY' => $row['Identity'] - ); - ++$i; - } - return $desc; - } - - /** - * Creates a connection to the database. - * - * @return void - * @throws Zend_Db_Adapter_Mysqli_Exception - */ - protected function _connect() - { - if ($this->_connection) { - return; - } - - if (!extension_loaded('mysqli')) { - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception('The Mysqli extension is required for this adapter but the extension is not loaded'); - } - - if (isset($this->_config['port'])) { - $port = (integer) $this->_config['port']; - } else { - $port = null; - } - - if (isset($this->_config['socket'])) { - $socket = $this->_config['socket']; - } else { - $socket = null; - } - - $this->_connection = mysqli_init(); - - if(!empty($this->_config['driver_options'])) { - foreach($this->_config['driver_options'] as $option=>$value) { - if(is_string($option)) { - // Suppress warnings here - // Ignore it if it's not a valid constant - $option = @constant(strtoupper($option)); - if($option === null) - continue; - } - mysqli_options($this->_connection, $option, $value); - } - } - - // Suppress connection warnings here. - // Throw an exception instead. - $_isConnected = @mysqli_real_connect( - $this->_connection, - $this->_config['host'], - $this->_config['username'], - $this->_config['password'], - $this->_config['dbname'], - $port, - $socket - ); - - if ($_isConnected === false || mysqli_connect_errno()) { - - $this->closeConnection(); - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception(mysqli_connect_error()); - } - - if (!empty($this->_config['charset'])) { - mysqli_set_charset($this->_connection, $this->_config['charset']); - } - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return ((bool) ($this->_connection instanceof mysqli)); - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - if ($this->isConnected()) { - $this->_connection->close(); - } - $this->_connection = null; - } - - /** - * Prepare a statement and return a PDOStatement-like object. - * - * @param string $sql SQL query - * @return Zend_Db_Statement_Mysqli - */ - public function prepare($sql) - { - $this->_connect(); - if ($this->_stmt) { - $this->_stmt->close(); - } - $stmtClass = $this->_defaultStmtClass; - if (!class_exists($stmtClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($stmtClass); - } - $stmt = new $stmtClass($this, $sql); - if ($stmt === false) { - return false; - } - $stmt->setFetchMode($this->_fetchMode); - $this->_stmt = $stmt; - return $stmt; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * MySQL does not support sequences, so $tableName and $primaryKey are ignored. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - * @todo Return value should be int? - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - $mysqli = $this->_connection; - return (string) $mysqli->insert_id; - } - - /** - * Begin a transaction. - * - * @return void - */ - protected function _beginTransaction() - { - $this->_connect(); - $this->_connection->autocommit(false); - } - - /** - * Commit a transaction. - * - * @return void - */ - protected function _commit() - { - $this->_connect(); - $this->_connection->commit(); - $this->_connection->autocommit(true); - } - - /** - * Roll-back a transaction. - * - * @return void - */ - protected function _rollBack() - { - $this->_connect(); - $this->_connection->rollback(); - $this->_connection->autocommit(true); - } - - /** - * Set the fetch mode. - * - * @param int $mode - * @return void - * @throws Zend_Db_Adapter_Mysqli_Exception - */ - public function setFetchMode($mode) - { - switch ($mode) { - case Zend_Db::FETCH_LAZY: - case Zend_Db::FETCH_ASSOC: - case Zend_Db::FETCH_NUM: - case Zend_Db::FETCH_BOTH: - case Zend_Db::FETCH_NAMED: - case Zend_Db::FETCH_OBJ: - $this->_fetchMode = $mode; - break; - case Zend_Db::FETCH_BOUND: // bound to PHP variable - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception('FETCH_BOUND is not supported yet'); - break; - default: - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception("Invalid fetch mode '$mode' specified"); - } - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param int $count - * @param int $offset OPTIONAL - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** - * @see Zend_Db_Adapter_Mysqli_Exception - */ - #require_once 'Zend/Db/Adapter/Mysqli/Exception.php'; - throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument offset=$offset is not valid"); - } - - $sql .= " LIMIT $count"; - if ($offset > 0) { - $sql .= " OFFSET $offset"; - } - - return $sql; - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - switch ($type) { - case 'positional': - return true; - case 'named': - default: - return false; - } - } - - /** - * Retrieve server version in PHP style - * - *@return string - */ - public function getServerVersion() - { - $this->_connect(); - $version = $this->_connection->server_version; - $major = (int) ($version / 10000); - $minor = (int) ($version % 10000 / 100); - $revision = (int) ($version % 100); - return $major . '.' . $minor . '.' . $revision; - } -} diff --git a/lib/Zend/Db/Adapter/Mysqli/Exception.php b/lib/Zend/Db/Adapter/Mysqli/Exception.php deleted file mode 100644 index 30c5c6eb504..00000000000 --- a/lib/Zend/Db/Adapter/Mysqli/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ - (string) Connect to the database as this username. - * password => (string) Password associated with the username. - * dbname => Either the name of the local Oracle instance, or the - * name of the entry in tnsnames.ora to which you want to connect. - * persistent => (boolean) Set TRUE to use a persistent connection - * @var array - */ - protected $_config = array( - 'dbname' => null, - 'username' => null, - 'password' => null, - 'persistent' => false - ); - - /** - * Keys are UPPERCASE SQL datatypes or the constants - * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE. - * - * Values are: - * 0 = 32-bit integer - * 1 = 64-bit integer - * 2 = float or decimal - * - * @var array Associative array of datatypes to values 0, 1, or 2. - */ - protected $_numericDataTypes = array( - Zend_Db::INT_TYPE => Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'BINARY_DOUBLE' => Zend_Db::FLOAT_TYPE, - 'BINARY_FLOAT' => Zend_Db::FLOAT_TYPE, - 'NUMBER' => Zend_Db::FLOAT_TYPE, - ); - - /** - * @var integer - */ - protected $_execute_mode = null; - - /** - * Default class name for a DB statement. - * - * @var string - */ - protected $_defaultStmtClass = 'Zend_Db_Statement_Oracle'; - - /** - * Check if LOB field are returned as string - * instead of OCI-Lob object - * - * @var boolean - */ - protected $_lobAsString = null; - - /** - * Creates a connection resource. - * - * @return void - * @throws Zend_Db_Adapter_Oracle_Exception - */ - protected function _connect() - { - if (is_resource($this->_connection)) { - // connection already exists - return; - } - - if (!extension_loaded('oci8')) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception('The OCI8 extension is required for this adapter but the extension is not loaded'); - } - - $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS); - - $connectionFuncName = ($this->_config['persistent'] == true) ? 'oci_pconnect' : 'oci_connect'; - - $this->_connection = @$connectionFuncName( - $this->_config['username'], - $this->_config['password'], - $this->_config['dbname'], - $this->_config['charset']); - - // check the connection - if (!$this->_connection) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception(oci_error()); - } - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return ((bool) (is_resource($this->_connection) - && (get_resource_type($this->_connection) == 'oci8 connection' - || get_resource_type($this->_connection) == 'oci8 persistent connection'))); - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - if ($this->isConnected()) { - oci_close($this->_connection); - } - $this->_connection = null; - } - - /** - * Activate/deactivate return of LOB as string - * - * @param string $lob_as_string - * @return Zend_Db_Adapter_Oracle - */ - public function setLobAsString($lobAsString) - { - $this->_lobAsString = (bool) $lobAsString; - return $this; - } - - /** - * Return whether or not LOB are returned as string - * - * @return boolean - */ - public function getLobAsString() - { - if ($this->_lobAsString === null) { - // if never set by user, we use driver option if it exists otherwise false - if (isset($this->_config['driver_options']) && - isset($this->_config['driver_options']['lob_as_string'])) { - $this->_lobAsString = (bool) $this->_config['driver_options']['lob_as_string']; - } else { - $this->_lobAsString = false; - } - } - return $this->_lobAsString; - } - - /** - * Returns an SQL statement for preparation. - * - * @param string $sql The SQL statement with placeholders. - * @return Zend_Db_Statement_Oracle - */ - public function prepare($sql) - { - $this->_connect(); - $stmtClass = $this->_defaultStmtClass; - if (!class_exists($stmtClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($stmtClass); - } - $stmt = new $stmtClass($this, $sql); - if ($stmt instanceof Zend_Db_Statement_Oracle) { - $stmt->setLobAsString($this->getLobAsString()); - } - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Quote a raw string. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value) || is_float($value)) { - return $value; - } - $value = str_replace("'", "''", $value); - return "'" . addcslashes($value, "\000\n\r\\\032") . "'"; - } - - /** - * Quote a table identifier and alias. - * - * @param string|array|Zend_Db_Expr $ident The identifier or expression. - * @param string $alias An alias for the table. - * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option. - * @return string The quoted identifier and alias. - */ - public function quoteTableAs($ident, $alias = null, $auto = false) - { - // Oracle doesn't allow the 'AS' keyword between the table identifier/expression and alias. - return $this->_quoteIdentifierAs($ident, $alias, $auto, ' '); - } - - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function lastSequenceId($sequenceName) - { - $this->_connect(); - $sql = 'SELECT '.$this->quoteIdentifier($sequenceName, true).'.CURRVAL FROM dual'; - $value = $this->fetchOne($sql); - return $value; - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - $sql = 'SELECT '.$this->quoteIdentifier($sequenceName, true).'.NEXTVAL FROM dual'; - $value = $this->fetchOne($sql); - return $value; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * Oracle does not support IDENTITY columns, so if the sequence is not - * specified, this method returns null. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= "_$primaryKey"; - } - $sequenceName .= '_seq'; - return $this->lastSequenceId($sequenceName); - } - - // No support for IDENTITY columns; return null - return null; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $this->_connect(); - $data = $this->fetchCol('SELECT table_name FROM all_tables'); - return $data; - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $version = $this->getServerVersion(); - if (($version === null) || version_compare($version, '9.0.0', '>=')) { - $sql = "SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE, - TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH, - TC.DATA_SCALE, TC.DATA_PRECISION, C.CONSTRAINT_TYPE, CC.POSITION - FROM ALL_TAB_COLUMNS TC - LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C - ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P')) - ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME - WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)"; - $bind[':TBNAME'] = $tableName; - if ($schemaName) { - $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)'; - $bind[':SCNAME'] = $schemaName; - } - $sql .= ' ORDER BY TC.COLUMN_ID'; - } else { - $subSql="SELECT AC.OWNER, AC.TABLE_NAME, ACC.COLUMN_NAME, AC.CONSTRAINT_TYPE, ACC.POSITION - from ALL_CONSTRAINTS AC, ALL_CONS_COLUMNS ACC - WHERE ACC.CONSTRAINT_NAME = AC.CONSTRAINT_NAME - AND ACC.TABLE_NAME = AC.TABLE_NAME - AND ACC.OWNER = AC.OWNER - AND AC.CONSTRAINT_TYPE = 'P' - AND UPPER(AC.TABLE_NAME) = UPPER(:TBNAME)"; - $bind[':TBNAME'] = $tableName; - if ($schemaName) { - $subSql .= ' AND UPPER(ACC.OWNER) = UPPER(:SCNAME)'; - $bind[':SCNAME'] = $schemaName; - } - $sql="SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE, - TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH, - TC.DATA_SCALE, TC.DATA_PRECISION, CC.CONSTRAINT_TYPE, CC.POSITION - FROM ALL_TAB_COLUMNS TC, ($subSql) CC - WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME) - AND TC.OWNER = CC.OWNER(+) AND TC.TABLE_NAME = CC.TABLE_NAME(+) AND TC.COLUMN_NAME = CC.COLUMN_NAME(+)"; - if ($schemaName) { - $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)'; - } - $sql .= ' ORDER BY TC.COLUMN_ID'; - } - - $stmt = $this->query($sql, $bind); - - /** - * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection - */ - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $table_name = 0; - $owner = 1; - $column_name = 2; - $data_type = 3; - $data_default = 4; - $nullable = 5; - $column_id = 6; - $data_length = 7; - $data_scale = 8; - $data_precision = 9; - $constraint_type = 10; - $position = 11; - - $desc = array(); - foreach ($result as $key => $row) { - list ($primary, $primaryPosition, $identity) = array(false, null, false); - if ($row[$constraint_type] == 'P') { - $primary = true; - $primaryPosition = $row[$position]; - /** - * Oracle does not support auto-increment keys. - */ - $identity = false; - } - $desc[$this->foldCase($row[$column_name])] = array( - 'SCHEMA_NAME' => $this->foldCase($row[$owner]), - 'TABLE_NAME' => $this->foldCase($row[$table_name]), - 'COLUMN_NAME' => $this->foldCase($row[$column_name]), - 'COLUMN_POSITION' => $row[$column_id], - 'DATA_TYPE' => $row[$data_type], - 'DEFAULT' => $row[$data_default], - 'NULLABLE' => (bool) ($row[$nullable] == 'Y'), - 'LENGTH' => $row[$data_length], - 'SCALE' => $row[$data_scale], - 'PRECISION' => $row[$data_precision], - 'UNSIGNED' => null, // @todo - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - return $desc; - } - - /** - * Leave autocommit mode and begin a transaction. - * - * @return void - */ - protected function _beginTransaction() - { - $this->_setExecuteMode(OCI_DEFAULT); - } - - /** - * Commit a transaction and return to autocommit mode. - * - * @return void - * @throws Zend_Db_Adapter_Oracle_Exception - */ - protected function _commit() - { - if (!oci_commit($this->_connection)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception(oci_error($this->_connection)); - } - $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS); - } - - /** - * Roll back a transaction and return to autocommit mode. - * - * @return void - * @throws Zend_Db_Adapter_Oracle_Exception - */ - protected function _rollBack() - { - if (!oci_rollback($this->_connection)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception(oci_error($this->_connection)); - } - $this->_setExecuteMode(OCI_COMMIT_ON_SUCCESS); - } - - /** - * Set the fetch mode. - * - * @todo Support FETCH_CLASS and FETCH_INTO. - * - * @param integer $mode A fetch mode. - * @return void - * @throws Zend_Db_Adapter_Oracle_Exception - */ - public function setFetchMode($mode) - { - switch ($mode) { - case Zend_Db::FETCH_NUM: // seq array - case Zend_Db::FETCH_ASSOC: // assoc array - case Zend_Db::FETCH_BOTH: // seq+assoc array - case Zend_Db::FETCH_OBJ: // object - $this->_fetchMode = $mode; - break; - case Zend_Db::FETCH_BOUND: // bound to PHP variable - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception('FETCH_BOUND is not supported yet'); - break; - default: - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception("Invalid fetch mode '$mode' specified"); - break; - } - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - * @throws Zend_Db_Adapter_Oracle_Exception - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception("LIMIT argument offset=$offset is not valid"); - } - - /** - * Oracle does not implement the LIMIT clause as some RDBMS do. - * We have to simulate it with subqueries and ROWNUM. - * Unfortunately because we use the column wildcard "*", - * this puts an extra column into the query result set. - */ - $limit_sql = "SELECT z2.* - FROM ( - SELECT z1.*, ROWNUM AS \"zend_db_rownum\" - FROM ( - " . $sql . " - ) z1 - ) z2 - WHERE z2.\"zend_db_rownum\" BETWEEN " . ($offset+1) . " AND " . ($offset+$count); - return $limit_sql; - } - - /** - * @param integer $mode - * @throws Zend_Db_Adapter_Oracle_Exception - */ - private function _setExecuteMode($mode) - { - switch($mode) { - case OCI_COMMIT_ON_SUCCESS: - case OCI_DEFAULT: - case OCI_DESCRIBE_ONLY: - $this->_execute_mode = $mode; - break; - default: - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Adapter/Oracle/Exception.php'; - throw new Zend_Db_Adapter_Oracle_Exception("Invalid execution mode '$mode' specified"); - break; - } - } - - /** - * @return int - */ - public function _getExecuteMode() - { - return $this->_execute_mode; - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - switch ($type) { - case 'named': - return true; - case 'positional': - default: - return false; - } - } - - /** - * Retrieve server version in PHP style - * - * @return string - */ - public function getServerVersion() - { - $this->_connect(); - $version = oci_server_version($this->_connection); - if ($version !== false) { - $matches = null; - if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) { - return $matches[1]; - } else { - return null; - } - } else { - return null; - } - } -} diff --git a/lib/Zend/Db/Adapter/Oracle/Exception.php b/lib/Zend/Db/Adapter/Oracle/Exception.php deleted file mode 100644 index 79308b8ae74..00000000000 --- a/lib/Zend/Db/Adapter/Oracle/Exception.php +++ /dev/null @@ -1,60 +0,0 @@ -message = $error['code'] .' '. $error['message']; - } else { - $this->message = $error['code'] .' '. $error['message']." " - . substr($error['sqltext'], 0, $error['offset']) - . "*" - . substr($error['sqltext'], $error['offset']); - } - $this->code = $error['code']; - } else if (is_string($error)) { - $this->message = $error; - } - if (!$this->code && $code) { - $this->code = $code; - } - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Abstract.php b/lib/Zend/Db/Adapter/Pdo/Abstract.php deleted file mode 100644 index 8f36fcdaaa9..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Abstract.php +++ /dev/null @@ -1,402 +0,0 @@ -_config settings. - * - * @return string - */ - protected function _dsn() - { - // baseline of DSN parts - $dsn = $this->_config; - - // don't pass the username, password, charset, persistent and driver_options in the DSN - unset($dsn['username']); - unset($dsn['password']); - unset($dsn['options']); - unset($dsn['charset']); - unset($dsn['persistent']); - unset($dsn['driver_options']); - - // use all remaining parts in the DSN - foreach ($dsn as $key => $val) { - $dsn[$key] = "$key=$val"; - } - - return $this->_pdoType . ':' . implode(';', $dsn); - } - - /** - * Creates a PDO object and connects to the database. - * - * @return void - * @throws Zend_Db_Adapter_Exception - */ - protected function _connect() - { - // if we already have a PDO object, no need to re-connect. - if ($this->_connection) { - return; - } - - // get the dsn first, because some adapters alter the $_pdoType - $dsn = $this->_dsn(); - - // check for PDO extension - if (!extension_loaded('pdo')) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded'); - } - - // check the PDO driver is available - if (!in_array($this->_pdoType, PDO::getAvailableDrivers())) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception('The ' . $this->_pdoType . ' driver is not currently installed'); - } - - // create PDO connection - $q = $this->_profiler->queryStart('connect', Zend_Db_Profiler::CONNECT); - - // add the persistence flag if we find it in our config array - if (isset($this->_config['persistent']) && ($this->_config['persistent'] == true)) { - $this->_config['driver_options'][PDO::ATTR_PERSISTENT] = true; - } - - try { - $this->_connection = new PDO( - $dsn, - $this->_config['username'], - $this->_config['password'], - $this->_config['driver_options'] - ); - - $this->_profiler->queryEnd($q); - - // set the PDO connection to perform case-folding on array keys, or not - $this->_connection->setAttribute(PDO::ATTR_CASE, $this->_caseFolding); - - // always use exceptions. - $this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - - } catch (PDOException $e) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e); - } - - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return ((bool) ($this->_connection instanceof PDO)); - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - $this->_connection = null; - } - - /** - * Prepares an SQL statement. - * - * @param string $sql The SQL statement with placeholders. - * @param array $bind An array of data to bind to the placeholders. - * @return PDOStatement - */ - public function prepare($sql) - { - $this->_connect(); - $stmtClass = $this->_defaultStmtClass; - if (!class_exists($stmtClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($stmtClass); - } - $stmt = new $stmtClass($this, $sql); - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * On RDBMS brands that don't support sequences, $tableName and $primaryKey - * are ignored. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - $this->_connect(); - return $this->_connection->lastInsertId(); - } - - /** - * Special handling for PDO query(). - * All bind parameter names must begin with ':' - * - * @param string|Zend_Db_Select $sql The SQL statement with placeholders. - * @param array $bind An array of data to bind to the placeholders. - * @return Zend_Db_Statement_Pdo - * @throws Zend_Db_Adapter_Exception To re-throw PDOException. - */ - public function query($sql, $bind = array()) - { - if (empty($bind) && $sql instanceof Zend_Db_Select) { - $bind = $sql->getBind(); - } - - if (is_array($bind)) { - foreach ($bind as $name => $value) { - if (!is_int($name) && !preg_match('/^:/', $name)) { - $newName = ":$name"; - unset($bind[$name]); - $bind[$newName] = $value; - } - } - } - - try { - return parent::query($sql, $bind); - } catch (PDOException $e) { - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Executes an SQL statement and return the number of affected rows - * - * @param mixed $sql The SQL statement with placeholders. - * May be a string or Zend_Db_Select. - * @return integer Number of rows that were modified - * or deleted by the SQL statement - */ - public function exec($sql) - { - if ($sql instanceof Zend_Db_Select) { - $sql = $sql->assemble(); - } - - try { - $affected = $this->getConnection()->exec($sql); - - if ($affected === false) { - $errorInfo = $this->getConnection()->errorInfo(); - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception($errorInfo[2]); - } - - return $affected; - } catch (PDOException $e) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Quote a raw string. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value) || is_float($value)) { - return $value; - } - // Fix for null-byte injection - $value = addcslashes($value, "\000\032"); - $this->_connect(); - return $this->_connection->quote($value); - } - - /** - * Begin a transaction. - */ - protected function _beginTransaction() - { - $this->_connect(); - $this->_connection->beginTransaction(); - } - - /** - * Commit a transaction. - */ - protected function _commit() - { - $this->_connect(); - $this->_connection->commit(); - } - - /** - * Roll-back a transaction. - */ - protected function _rollBack() { - $this->_connect(); - $this->_connection->rollBack(); - } - - /** - * Set the PDO fetch mode. - * - * @todo Support FETCH_CLASS and FETCH_INTO. - * - * @param int $mode A PDO fetch mode. - * @return void - * @throws Zend_Db_Adapter_Exception - */ - public function setFetchMode($mode) - { - //check for PDO extension - if (!extension_loaded('pdo')) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded'); - } - switch ($mode) { - case PDO::FETCH_LAZY: - case PDO::FETCH_ASSOC: - case PDO::FETCH_NUM: - case PDO::FETCH_BOTH: - case PDO::FETCH_NAMED: - case PDO::FETCH_OBJ: - $this->_fetchMode = $mode; - break; - default: - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Invalid fetch mode '$mode' specified"); - break; - } - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - switch ($type) { - case 'positional': - case 'named': - default: - return true; - } - } - - /** - * Retrieve server version in PHP style - * - * @return string - */ - public function getServerVersion() - { - $this->_connect(); - try { - $version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION); - } catch (PDOException $e) { - // In case of the driver doesn't support getting attributes - return null; - } - $matches = null; - if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) { - return $matches[1]; - } else { - return null; - } - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Ibm.php b/lib/Zend/Db/Adapter/Pdo/Ibm.php deleted file mode 100644 index 35552e49260..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Ibm.php +++ /dev/null @@ -1,360 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INTEGER' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'DEC' => Zend_Db::FLOAT_TYPE, - 'REAL' => Zend_Db::FLOAT_TYPE, - 'NUMERIC' => Zend_Db::FLOAT_TYPE, - 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE, - 'FLOAT' => Zend_Db::FLOAT_TYPE - ); - - /** - * Creates a PDO object and connects to the database. - * - * The IBM data server is set. - * Current options are DB2 or IDS - * @todo also differentiate between z/OS and i/5 - * - * @return void - * @throws Zend_Db_Adapter_Exception - */ - public function _connect() - { - if ($this->_connection) { - return; - } - parent::_connect(); - - $this->getConnection()->setAttribute(Zend_Db::ATTR_STRINGIFY_FETCHES, true); - - try { - if ($this->_serverType === null) { - $server = substr($this->getConnection()->getAttribute(PDO::ATTR_SERVER_INFO), 0, 3); - - switch ($server) { - case 'DB2': - $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Db2($this); - - // Add DB2-specific numeric types - $this->_numericDataTypes['DECFLOAT'] = Zend_Db::FLOAT_TYPE; - $this->_numericDataTypes['DOUBLE'] = Zend_Db::FLOAT_TYPE; - $this->_numericDataTypes['NUM'] = Zend_Db::FLOAT_TYPE; - - break; - case 'IDS': - $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Ids($this); - - // Add IDS-specific numeric types - $this->_numericDataTypes['SERIAL'] = Zend_Db::INT_TYPE; - $this->_numericDataTypes['SERIAL8'] = Zend_Db::BIGINT_TYPE; - $this->_numericDataTypes['INT8'] = Zend_Db::BIGINT_TYPE; - $this->_numericDataTypes['SMALLFLOAT'] = Zend_Db::FLOAT_TYPE; - $this->_numericDataTypes['MONEY'] = Zend_Db::FLOAT_TYPE; - - break; - } - } - } catch (PDOException $e) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - $error = strpos($e->getMessage(), 'driver does not support that attribute'); - if ($error) { - throw new Zend_Db_Adapter_Exception("PDO_IBM driver extension is downlevel. Please use driver release version 1.2.1 or later", 0, $e); - } else { - throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e); - } - } - } - - /** - * Creates a PDO DSN for the adapter from $this->_config settings. - * - * @return string - */ - protected function _dsn() - { - $this->_checkRequiredOptions($this->_config); - - // check if using full connection string - if (array_key_exists('host', $this->_config)) { - $dsn = ';DATABASE=' . $this->_config['dbname'] - . ';HOSTNAME=' . $this->_config['host'] - . ';PORT=' . $this->_config['port'] - // PDO_IBM supports only DB2 TCPIP protocol - . ';PROTOCOL=' . 'TCPIP;'; - } else { - // catalogued connection - $dsn = $this->_config['dbname']; - } - return $this->_pdoType . ': ' . $dsn; - } - - /** - * Checks required options - * - * @param array $config - * @throws Zend_Db_Adapter_Exception - * @return void - */ - protected function _checkRequiredOptions(array $config) - { - parent::_checkRequiredOptions($config); - - if (array_key_exists('host', $this->_config) && - !array_key_exists('port', $config)) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration must have a key for 'port' when 'host' is specified"); - } - } - - /** - * Prepares an SQL statement. - * - * @param string $sql The SQL statement with placeholders. - * @param array $bind An array of data to bind to the placeholders. - * @return PDOStatement - */ - public function prepare($sql) - { - $this->_connect(); - $stmtClass = $this->_defaultStmtClass; - $stmt = new $stmtClass($this, $sql); - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $this->_connect(); - return $this->_serverType->listTables(); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $this->_connect(); - return $this->_serverType->describeTable($tableName, $schemaName); - } - - /** - * Inserts a table row with specified data. - * Special handling for PDO_IBM - * remove empty slots - * - * @param mixed $table The table to insert data into. - * @param array $bind Column-value pairs. - * @return int The number of affected rows. - */ - public function insert($table, array $bind) - { - $this->_connect(); - $newbind = array(); - if (is_array($bind)) { - foreach ($bind as $name => $value) { - if($value !== null) { - $newbind[$name] = $value; - } - } - } - - return parent::insert($table, $newbind); - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $this->_connect(); - return $this->_serverType->limit($sql, $count, $offset); - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT - * column. - * - * @param string $tableName OPTIONAL - * @param string $primaryKey OPTIONAL - * @return integer - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - $this->_connect(); - - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= "_$primaryKey"; - } - $sequenceName .= '_seq'; - return $this->lastSequenceId($sequenceName); - } - - $id = $this->getConnection()->lastInsertId(); - - return $id; - } - - /** - * Return the most recent value from the specified sequence in the database. - * - * @param string $sequenceName - * @return integer - */ - public function lastSequenceId($sequenceName) - { - $this->_connect(); - return $this->_serverType->lastSequenceId($sequenceName); - } - - /** - * Generate a new value from the specified sequence in the database, - * and return it. - * - * @param string $sequenceName - * @return integer - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - return $this->_serverType->nextSequenceId($sequenceName); - } - - /** - * Retrieve server version in PHP style - * Pdo_Idm doesn't support getAttribute(PDO::ATTR_SERVER_VERSION) - * @return string - */ - public function getServerVersion() - { - try { - $stmt = $this->query('SELECT service_level, fixpack_num FROM TABLE (sysproc.env_get_inst_info()) as INSTANCEINFO'); - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - if (count($result)) { - $matches = null; - if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $result[0][0], $matches)) { - return $matches[1]; - } else { - return null; - } - } - return null; - } catch (PDOException $e) { - return null; - } - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Ibm/Db2.php b/lib/Zend/Db/Adapter/Pdo/Ibm/Db2.php deleted file mode 100644 index 7898cc8c5c7..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Ibm/Db2.php +++ /dev/null @@ -1,228 +0,0 @@ -_adapter = $adapter; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $sql = "SELECT tabname " - . "FROM SYSCAT.TABLES "; - return $this->_adapter->fetchCol($sql); - } - - /** - * DB2 catalog lookup for describe table - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $sql = "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno, - c.typename, c.default, c.nulls, c.length, c.scale, - c.identity, tc.type AS tabconsttype, k.colseq - FROM syscat.columns c - LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc - ON (k.tabschema = tc.tabschema - AND k.tabname = tc.tabname - AND tc.type = 'P')) - ON (c.tabschema = k.tabschema - AND c.tabname = k.tabname - AND c.colname = k.colname) - WHERE " - . $this->_adapter->quoteInto('UPPER(c.tabname) = UPPER(?)', $tableName); - if ($schemaName) { - $sql .= $this->_adapter->quoteInto(' AND UPPER(c.tabschema) = UPPER(?)', $schemaName); - } - $sql .= " ORDER BY c.colno"; - - $desc = array(); - $stmt = $this->_adapter->query($sql); - - /** - * To avoid case issues, fetch using FETCH_NUM - */ - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - /** - * The ordering of columns is defined by the query so we can map - * to variables to improve readability - */ - $tabschema = 0; - $tabname = 1; - $colname = 2; - $colno = 3; - $typename = 4; - $default = 5; - $nulls = 6; - $length = 7; - $scale = 8; - $identityCol = 9; - $tabconstype = 10; - $colseq = 11; - - foreach ($result as $key => $row) { - list ($primary, $primaryPosition, $identity) = array(false, null, false); - if ($row[$tabconstype] == 'P') { - $primary = true; - $primaryPosition = $row[$colseq]; - } - /** - * In IBM DB2, an column can be IDENTITY - * even if it is not part of the PRIMARY KEY. - */ - if ($row[$identityCol] == 'Y') { - $identity = true; - } - - $desc[$this->_adapter->foldCase($row[$colname])] = array( - 'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]), - 'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]), - 'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]), - 'COLUMN_POSITION' => $row[$colno]+1, - 'DATA_TYPE' => $row[$typename], - 'DEFAULT' => $row[$default], - 'NULLABLE' => (bool) ($row[$nulls] == 'Y'), - 'LENGTH' => $row[$length], - 'SCALE' => $row[$scale], - 'PRECISION' => ($row[$typename] == 'DECIMAL' ? $row[$length] : 0), - 'UNSIGNED' => false, - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - - return $desc; - } - - /** - * Adds a DB2-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @throws Zend_Db_Adapter_Exception - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } else { - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - if ($offset == 0 && $count > 0) { - $limit_sql = $sql . " FETCH FIRST $count ROWS ONLY"; - return $limit_sql; - } - /** - * DB2 does not implement the LIMIT clause as some RDBMS do. - * We have to simulate it with subqueries and ROWNUM. - * Unfortunately because we use the column wildcard "*", - * this puts an extra column into the query result set. - */ - $limit_sql = "SELECT z2.* - FROM ( - SELECT ROW_NUMBER() OVER() AS \"ZEND_DB_ROWNUM\", z1.* - FROM ( - " . $sql . " - ) z1 - ) z2 - WHERE z2.zend_db_rownum BETWEEN " . ($offset+1) . " AND " . ($offset+$count); - } - return $limit_sql; - } - - /** - * DB2-specific last sequence id - * - * @param string $sequenceName - * @return integer - */ - public function lastSequenceId($sequenceName) - { - $sql = 'SELECT PREVVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1'; - $value = $this->_adapter->fetchOne($sql); - return $value; - } - - /** - * DB2-specific sequence id value - * - * @param string $sequenceName - * @return integer - */ - public function nextSequenceId($sequenceName) - { - $sql = 'SELECT NEXTVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1'; - $value = $this->_adapter->fetchOne($sql); - return $value; - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Ibm/Ids.php b/lib/Zend/Db/Adapter/Pdo/Ibm/Ids.php deleted file mode 100644 index beee2f4de68..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Ibm/Ids.php +++ /dev/null @@ -1,301 +0,0 @@ -_adapter = $adapter; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $sql = "SELECT tabname " - . "FROM systables "; - - return $this->_adapter->fetchCol($sql); - } - - /** - * IDS catalog lookup for describe table - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - // this is still a work in progress - - $sql= "SELECT DISTINCT t.owner, t.tabname, c.colname, c.colno, c.coltype, - d.default, c.collength, t.tabid - FROM syscolumns c - JOIN systables t ON c.tabid = t.tabid - LEFT JOIN sysdefaults d ON c.tabid = d.tabid AND c.colno = d.colno - WHERE " - . $this->_adapter->quoteInto('UPPER(t.tabname) = UPPER(?)', $tableName); - if ($schemaName) { - $sql .= $this->_adapter->quoteInto(' AND UPPER(t.owner) = UPPER(?)', $schemaName); - } - $sql .= " ORDER BY c.colno"; - - $desc = array(); - $stmt = $this->_adapter->query($sql); - - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - /** - * The ordering of columns is defined by the query so we can map - * to variables to improve readability - */ - $tabschema = 0; - $tabname = 1; - $colname = 2; - $colno = 3; - $typename = 4; - $default = 5; - $length = 6; - $tabid = 7; - - $primaryCols = null; - - foreach ($result as $key => $row) { - $primary = false; - $primaryPosition = null; - - if (!$primaryCols) { - $primaryCols = $this->_getPrimaryInfo($row[$tabid]); - } - - if (array_key_exists($row[$colno], $primaryCols)) { - $primary = true; - $primaryPosition = $primaryCols[$row[$colno]]; - } - - $identity = false; - if ($row[$typename] == 6 + 256 || - $row[$typename] == 18 + 256) { - $identity = true; - } - - $desc[$this->_adapter->foldCase($row[$colname])] = array ( - 'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]), - 'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]), - 'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]), - 'COLUMN_POSITION' => $row[$colno], - 'DATA_TYPE' => $this->_getDataType($row[$typename]), - 'DEFAULT' => $row[$default], - 'NULLABLE' => (bool) !($row[$typename] - 256 >= 0), - 'LENGTH' => $row[$length], - 'SCALE' => ($row[$typename] == 5 ? $row[$length]&255 : 0), - 'PRECISION' => ($row[$typename] == 5 ? (int)($row[$length]/256) : 0), - 'UNSIGNED' => false, - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - - return $desc; - } - - /** - * Map number representation of a data type - * to a string - * - * @param int $typeNo - * @return string - */ - protected function _getDataType($typeNo) - { - $typemap = array( - 0 => "CHAR", - 1 => "SMALLINT", - 2 => "INTEGER", - 3 => "FLOAT", - 4 => "SMALLFLOAT", - 5 => "DECIMAL", - 6 => "SERIAL", - 7 => "DATE", - 8 => "MONEY", - 9 => "NULL", - 10 => "DATETIME", - 11 => "BYTE", - 12 => "TEXT", - 13 => "VARCHAR", - 14 => "INTERVAL", - 15 => "NCHAR", - 16 => "NVARCHAR", - 17 => "INT8", - 18 => "SERIAL8", - 19 => "SET", - 20 => "MULTISET", - 21 => "LIST", - 22 => "Unnamed ROW", - 40 => "Variable-length opaque type", - 4118 => "Named ROW" - ); - - if ($typeNo - 256 >= 0) { - $typeNo = $typeNo - 256; - } - - return $typemap[$typeNo]; - } - - /** - * Helper method to retrieve primary key column - * and column location - * - * @param int $tabid - * @return array - */ - protected function _getPrimaryInfo($tabid) - { - $sql = "SELECT i.part1, i.part2, i.part3, i.part4, i.part5, i.part6, - i.part7, i.part8, i.part9, i.part10, i.part11, i.part12, - i.part13, i.part14, i.part15, i.part16 - FROM sysindexes i - JOIN sysconstraints c ON c.idxname = i.idxname - WHERE i.tabid = " . $tabid . " AND c.constrtype = 'P'"; - - $stmt = $this->_adapter->query($sql); - $results = $stmt->fetchAll(); - - $cols = array(); - - // this should return only 1 row - // unless there is no primary key, - // in which case, the empty array is returned - if ($results) { - $row = $results[0]; - } else { - return $cols; - } - - $position = 0; - foreach ($row as $key => $colno) { - $position++; - if ($colno == 0) { - return $cols; - } else { - $cols[$colno] = $position; - } - } - } - - /** - * Adds an IDS-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @throws Zend_Db_Adapter_Exception - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } else if ($count == 0) { - $limit_sql = str_ireplace("SELECT", "SELECT * FROM (SELECT", $sql); - $limit_sql .= ") WHERE 0 = 1"; - } else { - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - if ($offset == 0) { - $limit_sql = str_ireplace("SELECT", "SELECT FIRST $count", $sql); - } else { - $limit_sql = str_ireplace("SELECT", "SELECT SKIP $offset LIMIT $count", $sql); - } - } - return $limit_sql; - } - - /** - * IDS-specific last sequence id - * - * @param string $sequenceName - * @return integer - */ - public function lastSequenceId($sequenceName) - { - $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.CURRVAL FROM ' - .'systables WHERE tabid = 1'; - $value = $this->_adapter->fetchOne($sql); - return $value; - } - - /** - * IDS-specific sequence id value - * - * @param string $sequenceName - * @return integer - */ - public function nextSequenceId($sequenceName) - { - $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.NEXTVAL FROM ' - .'systables WHERE tabid = 1'; - $value = $this->_adapter->fetchOne($sql); - return $value; - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Mssql.php b/lib/Zend/Db/Adapter/Pdo/Mssql.php deleted file mode 100644 index df8ba69a29a..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Mssql.php +++ /dev/null @@ -1,423 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INT' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'TINYINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'FLOAT' => Zend_Db::FLOAT_TYPE, - 'MONEY' => Zend_Db::FLOAT_TYPE, - 'NUMERIC' => Zend_Db::FLOAT_TYPE, - 'REAL' => Zend_Db::FLOAT_TYPE, - 'SMALLMONEY' => Zend_Db::FLOAT_TYPE - ); - - /** - * Creates a PDO DSN for the adapter from $this->_config settings. - * - * @return string - */ - protected function _dsn() - { - // baseline of DSN parts - $dsn = $this->_config; - - // don't pass the username and password in the DSN - unset($dsn['username']); - unset($dsn['password']); - unset($dsn['options']); - unset($dsn['persistent']); - unset($dsn['driver_options']); - - if (isset($dsn['port'])) { - $seperator = ':'; - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $seperator = ','; - } - $dsn['host'] .= $seperator . $dsn['port']; - unset($dsn['port']); - } - - // this driver supports multiple DSN prefixes - // @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php - if (isset($dsn['pdoType'])) { - switch (strtolower($dsn['pdoType'])) { - case 'freetds': - case 'sybase': - $this->_pdoType = 'sybase'; - break; - case 'mssql': - $this->_pdoType = 'mssql'; - break; - case 'dblib': - default: - $this->_pdoType = 'dblib'; - break; - } - unset($dsn['pdoType']); - } - - // use all remaining parts in the DSN - foreach ($dsn as $key => $val) { - $dsn[$key] = "$key=$val"; - } - - $dsn = $this->_pdoType . ':' . implode(';', $dsn); - return $dsn; - } - - /** - * @return void - */ - protected function _connect() - { - if ($this->_connection) { - return; - } - parent::_connect(); - $this->_connection->exec('SET QUOTED_IDENTIFIER ON'); - } - - /** - * Begin a transaction. - * - * It is necessary to override the abstract PDO transaction functions here, as - * the PDO driver for MSSQL does not support transactions. - */ - protected function _beginTransaction() - { - $this->_connect(); - $this->_connection->exec('BEGIN TRANSACTION'); - return true; - } - - /** - * Commit a transaction. - * - * It is necessary to override the abstract PDO transaction functions here, as - * the PDO driver for MSSQL does not support transactions. - */ - protected function _commit() - { - $this->_connect(); - $this->_connection->exec('COMMIT TRANSACTION'); - return true; - } - - /** - * Roll-back a transaction. - * - * It is necessary to override the abstract PDO transaction functions here, as - * the PDO driver for MSSQL does not support transactions. - */ - protected function _rollBack() { - $this->_connect(); - $this->_connection->exec('ROLLBACK TRANSACTION'); - return true; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name"; - return $this->fetchCol($sql); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * PRIMARY_AUTO => integer; position of auto-generated column in primary key - * - * @todo Discover column primary key position. - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - if ($schemaName != null) { - if (strpos($schemaName, '.') !== false) { - $result = explode('.', $schemaName); - $schemaName = $result[1]; - } - } - /** - * Discover metadata information about this table. - */ - $sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true); - if ($schemaName != null) { - $sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true); - } - - $stmt = $this->query($sql); - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $table_name = 2; - $column_name = 3; - $type_name = 5; - $precision = 6; - $length = 7; - $scale = 8; - $nullable = 10; - $column_def = 12; - $column_position = 16; - - /** - * Discover primary key column(s) for this table. - */ - $sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true); - if ($schemaName != null) { - $sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true); - } - - $stmt = $this->query($sql); - $primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM); - $primaryKeyColumn = array(); - $pkey_column_name = 3; - $pkey_key_seq = 4; - foreach ($primaryKeysResult as $pkeysRow) { - $primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq]; - } - - $desc = array(); - $p = 1; - foreach ($result as $key => $row) { - $identity = false; - $words = explode(' ', $row[$type_name], 2); - if (isset($words[0])) { - $type = $words[0]; - if (isset($words[1])) { - $identity = (bool) preg_match('/identity/', $words[1]); - } - } - - $isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn); - if ($isPrimary) { - $primaryPosition = $primaryKeyColumn[$row[$column_name]]; - } else { - $primaryPosition = null; - } - - $desc[$this->foldCase($row[$column_name])] = array( - 'SCHEMA_NAME' => null, // @todo - 'TABLE_NAME' => $this->foldCase($row[$table_name]), - 'COLUMN_NAME' => $this->foldCase($row[$column_name]), - 'COLUMN_POSITION' => (int) $row[$column_position], - 'DATA_TYPE' => $type, - 'DEFAULT' => $row[$column_def], - 'NULLABLE' => (bool) $row[$nullable], - 'LENGTH' => $row[$length], - 'SCALE' => $row[$scale], - 'PRECISION' => $row[$precision], - 'UNSIGNED' => null, // @todo - 'PRIMARY' => $isPrimary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - return $desc; - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @throws Zend_Db_Adapter_Exception - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - $sql = preg_replace( - '/^SELECT\s+(DISTINCT\s)?/i', - 'SELECT $1TOP ' . ($count+$offset) . ' ', - $sql - ); - - if ($offset > 0) { - $orderby = stristr($sql, 'ORDER BY'); - - if ($orderby !== false) { - $orderParts = explode(',', substr($orderby, 8)); - $pregReplaceCount = null; - $orderbyInverseParts = array(); - foreach ($orderParts as $orderPart) { - $orderPart = rtrim($orderPart); - $inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount); - if ($pregReplaceCount) { - $orderbyInverseParts[] = $inv; - continue; - } - $inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount); - if ($pregReplaceCount) { - $orderbyInverseParts[] = $inv; - continue; - } else { - $orderbyInverseParts[] = $orderPart . ' DESC'; - } - } - - $orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts); - } - - - - - $sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl'; - if ($orderby !== false) { - $sql .= ' ' . $orderbyInverse . ' '; - } - $sql .= ') AS outer_tbl'; - if ($orderby !== false) { - $sql .= ' ' . $orderby; - } - } - - return $sql; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * Microsoft SQL Server does not support sequences, so the arguments to - * this method are ignored. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - * @throws Zend_Db_Adapter_Exception - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - $sql = 'SELECT SCOPE_IDENTITY()'; - return (int)$this->fetchOne($sql); - } - - /** - * Retrieve server version in PHP style - * Pdo_Mssql doesn't support getAttribute(PDO::ATTR_SERVER_VERSION) - * @return string - */ - public function getServerVersion() - { - try { - $stmt = $this->query("SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR)"); - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - if (count($result)) { - return $result[0][0]; - } - return null; - } catch (PDOException $e) { - return null; - } - } -} diff --git a/lib/Zend/Db/Adapter/Pdo/Mysql.php b/lib/Zend/Db/Adapter/Pdo/Mysql.php deleted file mode 100644 index 055a7a26987..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Mysql.php +++ /dev/null @@ -1,272 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INT' => Zend_Db::INT_TYPE, - 'INTEGER' => Zend_Db::INT_TYPE, - 'MEDIUMINT' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'TINYINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'SERIAL' => Zend_Db::BIGINT_TYPE, - 'DEC' => Zend_Db::FLOAT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'DOUBLE' => Zend_Db::FLOAT_TYPE, - 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE, - 'FIXED' => Zend_Db::FLOAT_TYPE, - 'FLOAT' => Zend_Db::FLOAT_TYPE - ); - - /** - * Override _dsn() and ensure that charset is incorporated in mysql - * @see Zend_Db_Adapter_Pdo_Abstract::_dsn() - */ - protected function _dsn() - { - $dsn = parent::_dsn(); - if (isset($this->_config['charset'])) { - $dsn .= ';charset=' . $this->_config['charset']; - } - return $dsn; - } - - /** - * Creates a PDO object and connects to the database. - * - * @return void - * @throws Zend_Db_Adapter_Exception - */ - protected function _connect() - { - if ($this->_connection) { - return; - } - - if (!empty($this->_config['charset']) - && version_compare(PHP_VERSION, '5.3.6', '<') - ) { - $initCommand = "SET NAMES '" . $this->_config['charset'] . "'"; - $this->_config['driver_options'][1002] = $initCommand; // 1002 = PDO::MYSQL_ATTR_INIT_COMMAND - } - - parent::_connect(); - } - - /** - * @return string - */ - public function getQuoteIdentifierSymbol() - { - return "`"; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - return $this->fetchCol('SHOW TABLES'); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - // @todo use INFORMATION_SCHEMA someday when MySQL's - // implementation has reasonably good performance and - // the version with this improvement is in wide use. - - if ($schemaName) { - $sql = 'DESCRIBE ' . $this->quoteIdentifier("$schemaName.$tableName", true); - } else { - $sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, true); - } - $stmt = $this->query($sql); - - // Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $field = 0; - $type = 1; - $null = 2; - $key = 3; - $default = 4; - $extra = 5; - - $desc = array(); - $i = 1; - $p = 1; - foreach ($result as $row) { - list($length, $scale, $precision, $unsigned, $primary, $primaryPosition, $identity) - = array(null, null, null, null, false, null, false); - if (preg_match('/unsigned/', $row[$type])) { - $unsigned = true; - } - if (preg_match('/^((?:var)?char)\((\d+)\)/', $row[$type], $matches)) { - $row[$type] = $matches[1]; - $length = $matches[2]; - } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row[$type], $matches)) { - $row[$type] = 'decimal'; - $precision = $matches[1]; - $scale = $matches[2]; - } else if (preg_match('/^float\((\d+),(\d+)\)/', $row[$type], $matches)) { - $row[$type] = 'float'; - $precision = $matches[1]; - $scale = $matches[2]; - } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row[$type], $matches)) { - $row[$type] = $matches[1]; - // The optional argument of a MySQL int type is not precision - // or length; it is only a hint for display width. - } - if (strtoupper($row[$key]) == 'PRI') { - $primary = true; - $primaryPosition = $p; - if ($row[$extra] == 'auto_increment') { - $identity = true; - } else { - $identity = false; - } - ++$p; - } - $desc[$this->foldCase($row[$field])] = array( - 'SCHEMA_NAME' => null, // @todo - 'TABLE_NAME' => $this->foldCase($tableName), - 'COLUMN_NAME' => $this->foldCase($row[$field]), - 'COLUMN_POSITION' => $i, - 'DATA_TYPE' => $row[$type], - 'DEFAULT' => $row[$default], - 'NULLABLE' => (bool) ($row[$null] == 'YES'), - 'LENGTH' => $length, - 'SCALE' => $scale, - 'PRECISION' => $precision, - 'UNSIGNED' => $unsigned, - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - ++$i; - } - return $desc; - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @throws Zend_Db_Adapter_Exception - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - $sql .= " LIMIT $count"; - if ($offset > 0) { - $sql .= " OFFSET $offset"; - } - - return $sql; - } - -} diff --git a/lib/Zend/Db/Adapter/Pdo/Oci.php b/lib/Zend/Db/Adapter/Pdo/Oci.php deleted file mode 100644 index c52cfbe599f..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Oci.php +++ /dev/null @@ -1,378 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'BINARY_DOUBLE' => Zend_Db::FLOAT_TYPE, - 'BINARY_FLOAT' => Zend_Db::FLOAT_TYPE, - 'NUMBER' => Zend_Db::FLOAT_TYPE - ); - - /** - * Creates a PDO DSN for the adapter from $this->_config settings. - * - * @return string - */ - protected function _dsn() - { - // baseline of DSN parts - $dsn = $this->_config; - - if (isset($dsn['host'])) { - $tns = 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' . - '(HOST=' . $dsn['host'] . ')'; - - if (isset($dsn['port'])) { - $tns .= '(PORT=' . $dsn['port'] . ')'; - } else { - $tns .= '(PORT=1521)'; - } - - $tns .= '))(CONNECT_DATA=(SID=' . $dsn['dbname'] . ')))'; - } else { - $tns = 'dbname=' . $dsn['dbname']; - } - - if (isset($dsn['charset'])) { - $tns .= ';charset=' . $dsn['charset']; - } - - return $this->_pdoType . ':' . $tns; - } - - /** - * Quote a raw string. - * Most PDO drivers have an implementation for the quote() method, - * but the Oracle OCI driver must use the same implementation as the - * Zend_Db_Adapter_Abstract class. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value) || is_float($value)) { - return $value; - } - $value = str_replace("'", "''", $value); - return "'" . addcslashes($value, "\000\n\r\\\032") . "'"; - } - - /** - * Quote a table identifier and alias. - * - * @param string|array|Zend_Db_Expr $ident The identifier or expression. - * @param string $alias An alias for the table. - * @return string The quoted identifier and alias. - */ - public function quoteTableAs($ident, $alias = null, $auto = false) - { - // Oracle doesn't allow the 'AS' keyword between the table identifier/expression and alias. - return $this->_quoteIdentifierAs($ident, $alias, $auto, ' '); - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $data = $this->fetchCol('SELECT table_name FROM all_tables'); - return $data; - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $version = $this->getServerVersion(); - if (($version === null) || version_compare($version, '9.0.0', '>=')) { - $sql = "SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE, - TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH, - TC.DATA_SCALE, TC.DATA_PRECISION, C.CONSTRAINT_TYPE, CC.POSITION - FROM ALL_TAB_COLUMNS TC - LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C - ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P')) - ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME - WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME)"; - $bind[':TBNAME'] = $tableName; - if ($schemaName) { - $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)'; - $bind[':SCNAME'] = $schemaName; - } - $sql .= ' ORDER BY TC.COLUMN_ID'; - } else { - $subSql="SELECT AC.OWNER, AC.TABLE_NAME, ACC.COLUMN_NAME, AC.CONSTRAINT_TYPE, ACC.POSITION - from ALL_CONSTRAINTS AC, ALL_CONS_COLUMNS ACC - WHERE ACC.CONSTRAINT_NAME = AC.CONSTRAINT_NAME - AND ACC.TABLE_NAME = AC.TABLE_NAME - AND ACC.OWNER = AC.OWNER - AND AC.CONSTRAINT_TYPE = 'P' - AND UPPER(AC.TABLE_NAME) = UPPER(:TBNAME)"; - $bind[':TBNAME'] = $tableName; - if ($schemaName) { - $subSql .= ' AND UPPER(ACC.OWNER) = UPPER(:SCNAME)'; - $bind[':SCNAME'] = $schemaName; - } - $sql="SELECT TC.TABLE_NAME, TC.OWNER, TC.COLUMN_NAME, TC.DATA_TYPE, - TC.DATA_DEFAULT, TC.NULLABLE, TC.COLUMN_ID, TC.DATA_LENGTH, - TC.DATA_SCALE, TC.DATA_PRECISION, CC.CONSTRAINT_TYPE, CC.POSITION - FROM ALL_TAB_COLUMNS TC, ($subSql) CC - WHERE UPPER(TC.TABLE_NAME) = UPPER(:TBNAME) - AND TC.OWNER = CC.OWNER(+) AND TC.TABLE_NAME = CC.TABLE_NAME(+) AND TC.COLUMN_NAME = CC.COLUMN_NAME(+)"; - if ($schemaName) { - $sql .= ' AND UPPER(TC.OWNER) = UPPER(:SCNAME)'; - } - $sql .= ' ORDER BY TC.COLUMN_ID'; - } - - $stmt = $this->query($sql, $bind); - - /** - * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection - */ - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $table_name = 0; - $owner = 1; - $column_name = 2; - $data_type = 3; - $data_default = 4; - $nullable = 5; - $column_id = 6; - $data_length = 7; - $data_scale = 8; - $data_precision = 9; - $constraint_type = 10; - $position = 11; - - $desc = array(); - foreach ($result as $key => $row) { - list ($primary, $primaryPosition, $identity) = array(false, null, false); - if ($row[$constraint_type] == 'P') { - $primary = true; - $primaryPosition = $row[$position]; - /** - * Oracle does not support auto-increment keys. - */ - $identity = false; - } - $desc[$this->foldCase($row[$column_name])] = array( - 'SCHEMA_NAME' => $this->foldCase($row[$owner]), - 'TABLE_NAME' => $this->foldCase($row[$table_name]), - 'COLUMN_NAME' => $this->foldCase($row[$column_name]), - 'COLUMN_POSITION' => $row[$column_id], - 'DATA_TYPE' => $row[$data_type], - 'DEFAULT' => $row[$data_default], - 'NULLABLE' => (bool) ($row[$nullable] == 'Y'), - 'LENGTH' => $row[$data_length], - 'SCALE' => $row[$data_scale], - 'PRECISION' => $row[$data_precision], - 'UNSIGNED' => null, // @todo - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - return $desc; - } - - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return integer - */ - public function lastSequenceId($sequenceName) - { - $this->_connect(); - $value = $this->fetchOne('SELECT '.$this->quoteIdentifier($sequenceName, true).'.CURRVAL FROM dual'); - return $value; - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return integer - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - $value = $this->fetchOne('SELECT '.$this->quoteIdentifier($sequenceName, true).'.NEXTVAL FROM dual'); - return $value; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * Oracle does not support IDENTITY columns, so if the sequence is not - * specified, this method returns null. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - * @throws Zend_Db_Adapter_Oracle_Exception - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= $this->foldCase("_$primaryKey"); - } - $sequenceName .= $this->foldCase('_seq'); - return $this->lastSequenceId($sequenceName); - } - // No support for IDENTITY columns; return null - return null; - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset - * @throws Zend_Db_Adapter_Exception - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - /** - * Oracle does not implement the LIMIT clause as some RDBMS do. - * We have to simulate it with subqueries and ROWNUM. - * Unfortunately because we use the column wildcard "*", - * this puts an extra column into the query result set. - */ - $limit_sql = "SELECT z2.* - FROM ( - SELECT z1.*, ROWNUM AS \"zend_db_rownum\" - FROM ( - " . $sql . " - ) z1 - ) z2 - WHERE z2.\"zend_db_rownum\" BETWEEN " . ($offset+1) . " AND " . ($offset+$count); - return $limit_sql; - } - -} diff --git a/lib/Zend/Db/Adapter/Pdo/Pgsql.php b/lib/Zend/Db/Adapter/Pdo/Pgsql.php deleted file mode 100644 index db41ca292b9..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Pgsql.php +++ /dev/null @@ -1,336 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INTEGER' => Zend_Db::INT_TYPE, - 'SERIAL' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'BIGSERIAL' => Zend_Db::BIGINT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE, - 'NUMERIC' => Zend_Db::FLOAT_TYPE, - 'REAL' => Zend_Db::FLOAT_TYPE - ); - - /** - * Creates a PDO object and connects to the database. - * - * @return void - * @throws Zend_Db_Adapter_Exception - */ - protected function _connect() - { - if ($this->_connection) { - return; - } - - parent::_connect(); - - if (!empty($this->_config['charset'])) { - $sql = "SET NAMES '" . $this->_config['charset'] . "'"; - $this->_connection->exec($sql); - } - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - // @todo use a better query with joins instead of subqueries - $sql = "SELECT c.relname AS table_name " - . "FROM pg_class c, pg_user u " - . "WHERE c.relowner = u.usesysid AND c.relkind = 'r' " - . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) " - . "AND c.relname !~ '^(pg_|sql_)' " - . "UNION " - . "SELECT c.relname AS table_name " - . "FROM pg_class c " - . "WHERE c.relkind = 'r' " - . "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) " - . "AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) " - . "AND c.relname !~ '^pg_'"; - - return $this->fetchCol($sql); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $sql = "SELECT - a.attnum, - n.nspname, - c.relname, - a.attname AS colname, - t.typname AS type, - a.atttypmod, - FORMAT_TYPE(a.atttypid, a.atttypmod) AS complete_type, - d.adsrc AS default_value, - a.attnotnull AS notnull, - a.attlen AS length, - co.contype, - ARRAY_TO_STRING(co.conkey, ',') AS conkey - FROM pg_attribute AS a - JOIN pg_class AS c ON a.attrelid = c.oid - JOIN pg_namespace AS n ON c.relnamespace = n.oid - JOIN pg_type AS t ON a.atttypid = t.oid - LEFT OUTER JOIN pg_constraint AS co ON (co.conrelid = c.oid - AND a.attnum = ANY(co.conkey) AND co.contype = 'p') - LEFT OUTER JOIN pg_attrdef AS d ON d.adrelid = c.oid AND d.adnum = a.attnum - WHERE a.attnum > 0 AND c.relname = ".$this->quote($tableName); - if ($schemaName) { - $sql .= " AND n.nspname = ".$this->quote($schemaName); - } - $sql .= ' ORDER BY a.attnum'; - - $stmt = $this->query($sql); - - // Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $attnum = 0; - $nspname = 1; - $relname = 2; - $colname = 3; - $type = 4; - $atttypemod = 5; - $complete_type = 6; - $default_value = 7; - $notnull = 8; - $length = 9; - $contype = 10; - $conkey = 11; - - $desc = array(); - foreach ($result as $key => $row) { - $defaultValue = $row[$default_value]; - if ($row[$type] == 'varchar' || $row[$type] == 'bpchar' ) { - if (preg_match('/character(?: varying)?(?:\((\d+)\))?/', $row[$complete_type], $matches)) { - if (isset($matches[1])) { - $row[$length] = $matches[1]; - } else { - $row[$length] = null; // unlimited - } - } - if (preg_match("/^'(.*?)'::(?:character varying|bpchar)$/", $defaultValue, $matches)) { - $defaultValue = $matches[1]; - } - } - list($primary, $primaryPosition, $identity) = array(false, null, false); - if ($row[$contype] == 'p') { - $primary = true; - $primaryPosition = array_search($row[$attnum], explode(',', $row[$conkey])) + 1; - $identity = (bool) (preg_match('/^nextval/', $row[$default_value])); - } - $desc[$this->foldCase($row[$colname])] = array( - 'SCHEMA_NAME' => $this->foldCase($row[$nspname]), - 'TABLE_NAME' => $this->foldCase($row[$relname]), - 'COLUMN_NAME' => $this->foldCase($row[$colname]), - 'COLUMN_POSITION' => $row[$attnum], - 'DATA_TYPE' => $row[$type], - 'DEFAULT' => $defaultValue, - 'NULLABLE' => (bool) ($row[$notnull] != 't'), - 'LENGTH' => $row[$length], - 'SCALE' => null, // @todo - 'PRECISION' => null, // @todo - 'UNSIGNED' => null, // @todo - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - return $desc; - } - - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - $sql .= " LIMIT $count"; - if ($offset > 0) { - $sql .= " OFFSET $offset"; - } - - return $sql; - } - - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function lastSequenceId($sequenceName) - { - $this->_connect(); - $sequenceName = str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName); - $value = $this->fetchOne("SELECT CURRVAL(" - . $this->quote($this->quoteIdentifier($sequenceName, true)) - . ")"); - return $value; - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return string - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - $sequenceName = str_replace($this->getQuoteIdentifierSymbol(), '', (string) $sequenceName); - $value = $this->fetchOne("SELECT NEXTVAL(" - . $this->quote($this->quoteIdentifier($sequenceName, true)) - . ")"); - return $value; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= "_$primaryKey"; - } - $sequenceName .= '_seq'; - return $this->lastSequenceId($sequenceName); - } - return $this->_connection->lastInsertId($tableName); - } - -} diff --git a/lib/Zend/Db/Adapter/Pdo/Sqlite.php b/lib/Zend/Db/Adapter/Pdo/Sqlite.php deleted file mode 100644 index 8d854e34212..00000000000 --- a/lib/Zend/Db/Adapter/Pdo/Sqlite.php +++ /dev/null @@ -1,297 +0,0 @@ - Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INTEGER' => Zend_Db::BIGINT_TYPE, - 'REAL' => Zend_Db::FLOAT_TYPE - ); - - /** - * Constructor. - * - * $config is an array of key/value pairs containing configuration - * options. Note that the SQLite options are different than most of - * the other PDO adapters in that no username or password are needed. - * Also, an extra config key "sqlite2" specifies compatibility mode. - * - * dbname => (string) The name of the database to user (required, - * use :memory: for memory-based database) - * - * sqlite2 => (boolean) PDO_SQLITE defaults to SQLite 3. For compatibility - * with an older SQLite 2 database, set this to TRUE. - * - * @param array $config An array of configuration keys. - */ - public function __construct(array $config = array()) - { - if (isset($config['sqlite2']) && $config['sqlite2']) { - $this->_pdoType = 'sqlite2'; - } - - // SQLite uses no username/password. Stub to satisfy parent::_connect() - $this->_config['username'] = null; - $this->_config['password'] = null; - - return parent::__construct($config); - } - - /** - * Check for config options that are mandatory. - * Throw exceptions if any are missing. - * - * @param array $config - * @throws Zend_Db_Adapter_Exception - */ - protected function _checkRequiredOptions(array $config) - { - // we need at least a dbname - if (! array_key_exists('dbname', $config)) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance"); - } - } - - /** - * DSN builder - */ - protected function _dsn() - { - return $this->_pdoType .':'. $this->_config['dbname']; - } - - /** - * Special configuration for SQLite behavior: make sure that result sets - * contain keys like 'column' instead of 'table.column'. - * - * @throws Zend_Db_Adapter_Exception - */ - protected function _connect() - { - /** - * if we already have a PDO object, no need to re-connect. - */ - if ($this->_connection) { - return; - } - - parent::_connect(); - - $retval = $this->_connection->exec('PRAGMA full_column_names=0'); - if ($retval === false) { - $error = $this->_connection->errorInfo(); - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception($error[2]); - } - - $retval = $this->_connection->exec('PRAGMA short_column_names=1'); - if ($retval === false) { - $error = $this->_connection->errorInfo(); - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception($error[2]); - } - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $sql = "SELECT name FROM sqlite_master WHERE type='table' " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type='table' ORDER BY name"; - - return $this->fetchCol($sql); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - $sql = 'PRAGMA '; - - if ($schemaName) { - $sql .= $this->quoteIdentifier($schemaName) . '.'; - } - - $sql .= 'table_info('.$this->quoteIdentifier($tableName).')'; - - $stmt = $this->query($sql); - - /** - * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection - */ - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - $cid = 0; - $name = 1; - $type = 2; - $notnull = 3; - $dflt_value = 4; - $pk = 5; - - $desc = array(); - - $p = 1; - foreach ($result as $key => $row) { - list($length, $scale, $precision, $primary, $primaryPosition, $identity) = - array(null, null, null, false, null, false); - if (preg_match('/^((?:var)?char)\((\d+)\)/i', $row[$type], $matches)) { - $row[$type] = $matches[1]; - $length = $matches[2]; - } else if (preg_match('/^decimal\((\d+),(\d+)\)/i', $row[$type], $matches)) { - $row[$type] = 'DECIMAL'; - $precision = $matches[1]; - $scale = $matches[2]; - } - if ((bool) $row[$pk]) { - $primary = true; - $primaryPosition = $p; - /** - * SQLite INTEGER primary key is always auto-increment. - */ - $identity = (bool) ($row[$type] == 'INTEGER'); - ++$p; - } - $desc[$this->foldCase($row[$name])] = array( - 'SCHEMA_NAME' => $this->foldCase($schemaName), - 'TABLE_NAME' => $this->foldCase($tableName), - 'COLUMN_NAME' => $this->foldCase($row[$name]), - 'COLUMN_POSITION' => $row[$cid]+1, - 'DATA_TYPE' => $row[$type], - 'DEFAULT' => $row[$dflt_value], - 'NULLABLE' => ! (bool) $row[$notnull], - 'LENGTH' => $length, - 'SCALE' => $scale, - 'PRECISION' => $precision, - 'UNSIGNED' => null, // Sqlite3 does not support unsigned data - 'PRIMARY' => $primary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity - ); - } - return $desc; - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - $sql .= " LIMIT $count"; - if ($offset > 0) { - $sql .= " OFFSET $offset"; - } - - return $sql; - } - -} diff --git a/lib/Zend/Db/Adapter/Sqlsrv.php b/lib/Zend/Db/Adapter/Sqlsrv.php deleted file mode 100644 index a221714c391..00000000000 --- a/lib/Zend/Db/Adapter/Sqlsrv.php +++ /dev/null @@ -1,679 +0,0 @@ - (string) Connect to the database as this username. - * password => (string) Password associated with the username. - * dbname => The name of the local SQL Server instance - * - * @var array - */ - protected $_config = array( - 'dbname' => null, - 'username' => null, - 'password' => null, - ); - - /** - * Last insert id from INSERT query - * - * @var int - */ - protected $_lastInsertId; - - /** - * Query used to fetch last insert id - * - * @var string - */ - protected $_lastInsertSQL = 'SELECT SCOPE_IDENTITY() as Current_Identity'; - - /** - * Keys are UPPERCASE SQL datatypes or the constants - * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE. - * - * Values are: - * 0 = 32-bit integer - * 1 = 64-bit integer - * 2 = float or decimal - * - * @var array Associative array of datatypes to values 0, 1, or 2. - */ - protected $_numericDataTypes = array( - Zend_Db::INT_TYPE => Zend_Db::INT_TYPE, - Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE, - Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE, - 'INT' => Zend_Db::INT_TYPE, - 'SMALLINT' => Zend_Db::INT_TYPE, - 'TINYINT' => Zend_Db::INT_TYPE, - 'BIGINT' => Zend_Db::BIGINT_TYPE, - 'DECIMAL' => Zend_Db::FLOAT_TYPE, - 'FLOAT' => Zend_Db::FLOAT_TYPE, - 'MONEY' => Zend_Db::FLOAT_TYPE, - 'NUMERIC' => Zend_Db::FLOAT_TYPE, - 'REAL' => Zend_Db::FLOAT_TYPE, - 'SMALLMONEY' => Zend_Db::FLOAT_TYPE, - ); - - /** - * Default class name for a DB statement. - * - * @var string - */ - protected $_defaultStmtClass = 'Zend_Db_Statement_Sqlsrv'; - - /** - * Creates a connection resource. - * - * @return void - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - protected function _connect() - { - if (is_resource($this->_connection)) { - // connection already exists - return; - } - - if (!extension_loaded('sqlsrv')) { - /** - * @see Zend_Db_Adapter_Sqlsrv_Exception - */ - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception('The Sqlsrv extension is required for this adapter but the extension is not loaded'); - } - - $serverName = $this->_config['host']; - if (isset($this->_config['port'])) { - $port = (integer) $this->_config['port']; - $serverName .= ', ' . $port; - } - - $connectionInfo = array( - 'Database' => $this->_config['dbname'], - ); - - if (isset($this->_config['username']) && isset($this->_config['password'])) - { - $connectionInfo += array( - 'UID' => $this->_config['username'], - 'PWD' => $this->_config['password'], - ); - } - // else - windows authentication - - if (!empty($this->_config['driver_options'])) { - foreach ($this->_config['driver_options'] as $option => $value) { - // A value may be a constant. - if (is_string($value)) { - $constantName = strtoupper($value); - if (defined($constantName)) { - $connectionInfo[$option] = constant($constantName); - } else { - $connectionInfo[$option] = $value; - } - } - } - } - - $this->_connection = sqlsrv_connect($serverName, $connectionInfo); - - if (!$this->_connection) { - /** - * @see Zend_Db_Adapter_Sqlsrv_Exception - */ - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors()); - } - } - - /** - * Check for config options that are mandatory. - * Throw exceptions if any are missing. - * - * @param array $config - * @throws Zend_Db_Adapter_Exception - */ - protected function _checkRequiredOptions(array $config) - { - // we need at least a dbname - if (! array_key_exists('dbname', $config)) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance"); - } - - if (! array_key_exists('password', $config) && array_key_exists('username', $config)) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials. - If Windows Authentication is desired, both keys 'username' and 'password' should be ommited from config."); - } - - if (array_key_exists('password', $config) && !array_key_exists('username', $config)) { - /** - * @see Zend_Db_Adapter_Exception - */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials. - If Windows Authentication is desired, both keys 'username' and 'password' should be ommited from config."); - } - } - - /** - * Set the transaction isoltion level. - * - * @param integer|null $level A fetch mode from SQLSRV_TXN_*. - * @return true - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - public function setTransactionIsolationLevel($level = null) - { - $this->_connect(); - $sql = null; - - // Default transaction level in sql server - if ($level === null) - { - $level = SQLSRV_TXN_READ_COMMITTED; - } - - switch ($level) { - case SQLSRV_TXN_READ_UNCOMMITTED: - $sql = "READ UNCOMMITTED"; - break; - case SQLSRV_TXN_READ_COMMITTED: - $sql = "READ COMMITTED"; - break; - case SQLSRV_TXN_REPEATABLE_READ: - $sql = "REPEATABLE READ"; - break; - case SQLSRV_TXN_SNAPSHOT: - $sql = "SNAPSHOT"; - break; - case SQLSRV_TXN_SERIALIZABLE: - $sql = "SERIALIZABLE"; - break; - default: - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception("Invalid transaction isolation level mode '$level' specified"); - } - - if (!sqlsrv_query($this->_connection, "SET TRANSACTION ISOLATION LEVEL $sql;")) { - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception("Transaction cannot be changed to '$level'"); - } - - return true; - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return (is_resource($this->_connection) - && (get_resource_type($this->_connection) == 'SQL Server Connection') - ); - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - if ($this->isConnected()) { - sqlsrv_close($this->_connection); - } - $this->_connection = null; - } - - /** - * Returns an SQL statement for preparation. - * - * @param string $sql The SQL statement with placeholders. - * @return Zend_Db_Statement_Sqlsrv - */ - public function prepare($sql) - { - $this->_connect(); - $stmtClass = $this->_defaultStmtClass; - - if (!class_exists($stmtClass)) { - /** - * @see Zend_Loader - */ - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($stmtClass); - } - - $stmt = new $stmtClass($this, $sql); - $stmt->setFetchMode($this->_fetchMode); - return $stmt; - } - - /** - * Quote a raw string. - * - * @param string $value Raw string - * @return string Quoted string - */ - protected function _quote($value) - { - if (is_int($value)) { - return $value; - } elseif (is_float($value)) { - return sprintf('%F', $value); - } - - $value = addcslashes($value, "\000\032"); - return "'" . str_replace("'", "''", $value) . "'"; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - if ($tableName) { - $tableName = $this->quote($tableName); - $sql = 'SELECT IDENT_CURRENT (' . $tableName . ') as Current_Identity'; - return (string) $this->fetchOne($sql); - } - - if ($this->_lastInsertId > 0) { - return (string) $this->_lastInsertId; - } - - $sql = $this->_lastInsertSQL; - return (string) $this->fetchOne($sql); - } - - /** - * Inserts a table row with specified data. - * - * @param mixed $table The table to insert data into. - * @param array $bind Column-value pairs. - * @return int The number of affected rows. - */ - public function insert($table, array $bind) - { - // extract and quote col names from the array keys - $cols = array(); - $vals = array(); - foreach ($bind as $col => $val) { - $cols[] = $this->quoteIdentifier($col, true); - if ($val instanceof Zend_Db_Expr) { - $vals[] = $val->__toString(); - unset($bind[$col]); - } else { - $vals[] = '?'; - } - } - - // build the statement - $sql = "INSERT INTO " - . $this->quoteIdentifier($table, true) - . ' (' . implode(', ', $cols) . ') ' - . 'VALUES (' . implode(', ', $vals) . ')' - . ' ' . $this->_lastInsertSQL; - - // execute the statement and return the number of affected rows - $stmt = $this->query($sql, array_values($bind)); - $result = $stmt->rowCount(); - - $stmt->nextRowset(); - - $this->_lastInsertId = $stmt->fetchColumn(); - - return $result; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - $this->_connect(); - $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name"; - return $this->fetchCol($sql); - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * IDENTITY => integer; true if column is auto-generated with unique values - * - * @todo Discover integer unsigned property. - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - /** - * Discover metadata information about this table. - */ - $sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true); - $stmt = $this->query($sql); - $result = $stmt->fetchAll(Zend_Db::FETCH_NUM); - - // ZF-7698 - $stmt->closeCursor(); - - if (count($result) == 0) { - return array(); - } - - $owner = 1; - $table_name = 2; - $column_name = 3; - $type_name = 5; - $precision = 6; - $length = 7; - $scale = 8; - $nullable = 10; - $column_def = 12; - $column_position = 16; - - /** - * Discover primary key column(s) for this table. - */ - $tableOwner = $result[0][$owner]; - $sql = "exec sp_pkeys @table_owner = " . $tableOwner - . ", @table_name = " . $this->quoteIdentifier($tableName, true); - $stmt = $this->query($sql); - - $primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM); - $primaryKeyColumn = array(); - - // Per http://msdn.microsoft.com/en-us/library/ms189813.aspx, - // results from sp_keys stored procedure are: - // 0=TABLE_QUALIFIER 1=TABLE_OWNER 2=TABLE_NAME 3=COLUMN_NAME 4=KEY_SEQ 5=PK_NAME - - $pkey_column_name = 3; - $pkey_key_seq = 4; - foreach ($primaryKeysResult as $pkeysRow) { - $primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq]; - } - - $desc = array(); - $p = 1; - foreach ($result as $key => $row) { - $identity = false; - $words = explode(' ', $row[$type_name], 2); - if (isset($words[0])) { - $type = $words[0]; - if (isset($words[1])) { - $identity = (bool) preg_match('/identity/', $words[1]); - } - } - - $isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn); - if ($isPrimary) { - $primaryPosition = $primaryKeyColumn[$row[$column_name]]; - } else { - $primaryPosition = null; - } - - $desc[$this->foldCase($row[$column_name])] = array( - 'SCHEMA_NAME' => null, // @todo - 'TABLE_NAME' => $this->foldCase($row[$table_name]), - 'COLUMN_NAME' => $this->foldCase($row[$column_name]), - 'COLUMN_POSITION' => (int) $row[$column_position], - 'DATA_TYPE' => $type, - 'DEFAULT' => $row[$column_def], - 'NULLABLE' => (bool) $row[$nullable], - 'LENGTH' => $row[$length], - 'SCALE' => $row[$scale], - 'PRECISION' => $row[$precision], - 'UNSIGNED' => null, // @todo - 'PRIMARY' => $isPrimary, - 'PRIMARY_POSITION' => $primaryPosition, - 'IDENTITY' => $identity, - ); - } - - return $desc; - } - - /** - * Leave autocommit mode and begin a transaction. - * - * @return void - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - protected function _beginTransaction() - { - if (!sqlsrv_begin_transaction($this->_connection)) { - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors()); - } - } - - /** - * Commit a transaction and return to autocommit mode. - * - * @return void - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - protected function _commit() - { - if (!sqlsrv_commit($this->_connection)) { - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors()); - } - } - - /** - * Roll back a transaction and return to autocommit mode. - * - * @return void - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - protected function _rollBack() - { - if (!sqlsrv_rollback($this->_connection)) { - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception(sqlsrv_errors()); - } - } - - /** - * Set the fetch mode. - * - * @todo Support FETCH_CLASS and FETCH_INTO. - * - * @param integer $mode A fetch mode. - * @return void - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - public function setFetchMode($mode) - { - switch ($mode) { - case Zend_Db::FETCH_NUM: // seq array - case Zend_Db::FETCH_ASSOC: // assoc array - case Zend_Db::FETCH_BOTH: // seq+assoc array - case Zend_Db::FETCH_OBJ: // object - $this->_fetchMode = $mode; - break; - case Zend_Db::FETCH_BOUND: // bound to PHP variable - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception('FETCH_BOUND is not supported yet'); - break; - default: - #require_once 'Zend/Db/Adapter/Sqlsrv/Exception.php'; - throw new Zend_Db_Adapter_Sqlsrv_Exception("Invalid fetch mode '$mode' specified"); - break; - } - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param string $sql - * @param integer $count - * @param integer $offset OPTIONAL - * @return string - * @throws Zend_Db_Adapter_Sqlsrv_Exception - */ - public function limit($sql, $count, $offset = 0) - { - $count = intval($count); - if ($count <= 0) { - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid"); - } - - $offset = intval($offset); - if ($offset < 0) { - /** @see Zend_Db_Adapter_Exception */ - #require_once 'Zend/Db/Adapter/Exception.php'; - throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid"); - } - - if ($offset == 0) { - $sql = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . $count . ' ', $sql); - } else { - $orderby = stristr($sql, 'ORDER BY'); - - if (!$orderby) { - $over = 'ORDER BY (SELECT 0)'; - } else { - $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby); - } - - // Remove ORDER BY clause from $sql - $sql = preg_replace('/\s+ORDER BY(.*)/', '', $sql); - - // Add ORDER BY clause as an argument for ROW_NUMBER() - $sql = "SELECT ROW_NUMBER() OVER ($over) AS \"ZEND_DB_ROWNUM\", * FROM ($sql) AS inner_tbl"; - - $start = $offset + 1; - - if ($count == PHP_INT_MAX) { - $sql = "WITH outer_tbl AS ($sql) SELECT * FROM outer_tbl WHERE \"ZEND_DB_ROWNUM\" >= $start"; - } - else { - $end = $offset + $count; - $sql = "WITH outer_tbl AS ($sql) SELECT * FROM outer_tbl WHERE \"ZEND_DB_ROWNUM\" BETWEEN $start AND $end"; - } - } - - return $sql; - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - if ($type == 'positional') { - return true; - } - - // if its 'named' or anything else - return false; - } - - /** - * Retrieve server version in PHP style - * - * @return string - */ - public function getServerVersion() - { - $this->_connect(); - $serverInfo = sqlsrv_server_info($this->_connection); - - if ($serverInfo !== false) { - return $serverInfo['SQLServerVersion']; - } - - return null; - } -} diff --git a/lib/Zend/Db/Adapter/Sqlsrv/Exception.php b/lib/Zend/Db/Adapter/Sqlsrv/Exception.php deleted file mode 100644 index bf2def22e2e..00000000000 --- a/lib/Zend/Db/Adapter/Sqlsrv/Exception.php +++ /dev/null @@ -1,63 +0,0 @@ -_expression = (string) $expression; - } - - /** - * @return string The string of the SQL expression stored in this object. - */ - public function __toString() - { - return $this->_expression; - } - -} diff --git a/lib/Zend/Db/Profiler.php b/lib/Zend/Db/Profiler.php deleted file mode 100644 index 601ebf14425..00000000000 --- a/lib/Zend/Db/Profiler.php +++ /dev/null @@ -1,473 +0,0 @@ -setEnabled($enabled); - } - - /** - * Enable or disable the profiler. If $enable is false, the profiler - * is disabled and will not log any queries sent to it. - * - * @param boolean $enable - * @return Zend_Db_Profiler Provides a fluent interface - */ - public function setEnabled($enable) - { - $this->_enabled = (boolean) $enable; - - return $this; - } - - /** - * Get the current state of enable. If True is returned, - * the profiler is enabled. - * - * @return boolean - */ - public function getEnabled() - { - return $this->_enabled; - } - - /** - * Sets a minimum number of seconds for saving query profiles. If this - * is set, only those queries whose elapsed time is equal or greater than - * $minimumSeconds will be saved. To save all queries regardless of - * elapsed time, set $minimumSeconds to null. - * - * @param integer $minimumSeconds OPTIONAL - * @return Zend_Db_Profiler Provides a fluent interface - */ - public function setFilterElapsedSecs($minimumSeconds = null) - { - if (null === $minimumSeconds) { - $this->_filterElapsedSecs = null; - } else { - $this->_filterElapsedSecs = (integer) $minimumSeconds; - } - - return $this; - } - - /** - * Returns the minimum number of seconds for saving query profiles, or null if - * query profiles are saved regardless of elapsed time. - * - * @return integer|null - */ - public function getFilterElapsedSecs() - { - return $this->_filterElapsedSecs; - } - - /** - * Sets the types of query profiles to save. Set $queryType to one of - * the Zend_Db_Profiler::* constants to only save profiles for that type of - * query. To save more than one type, logical OR them together. To - * save all queries regardless of type, set $queryType to null. - * - * @param integer $queryTypes OPTIONAL - * @return Zend_Db_Profiler Provides a fluent interface - */ - public function setFilterQueryType($queryTypes = null) - { - $this->_filterTypes = $queryTypes; - - return $this; - } - - /** - * Returns the types of query profiles saved, or null if queries are saved regardless - * of their types. - * - * @return integer|null - * @see Zend_Db_Profiler::setFilterQueryType() - */ - public function getFilterQueryType() - { - return $this->_filterTypes; - } - - /** - * Clears the history of any past query profiles. This is relentless - * and will even clear queries that were started and may not have - * been marked as ended. - * - * @return Zend_Db_Profiler Provides a fluent interface - */ - public function clear() - { - $this->_queryProfiles = array(); - - return $this; - } - - /** - * Clone a profiler query - * - * @param Zend_Db_Profiler_Query $query - * @return integer or null - */ - public function queryClone(Zend_Db_Profiler_Query $query) - { - $this->_queryProfiles[] = clone $query; - - end($this->_queryProfiles); - - return key($this->_queryProfiles); - } - - /** - * Starts a query. Creates a new query profile object (Zend_Db_Profiler_Query) - * and returns the "query profiler handle". Run the query, then call - * queryEnd() and pass it this handle to make the query as ended and - * record the time. If the profiler is not enabled, this takes no - * action and immediately returns null. - * - * @param string $queryText SQL statement - * @param integer $queryType OPTIONAL Type of query, one of the Zend_Db_Profiler::* constants - * @return integer|null - */ - public function queryStart($queryText, $queryType = null) - { - if (!$this->_enabled) { - return null; - } - - // make sure we have a query type - if (null === $queryType) { - switch (strtolower(substr(ltrim($queryText), 0, 6))) { - case 'insert': - $queryType = self::INSERT; - break; - case 'update': - $queryType = self::UPDATE; - break; - case 'delete': - $queryType = self::DELETE; - break; - case 'select': - $queryType = self::SELECT; - break; - default: - $queryType = self::QUERY; - break; - } - } - - /** - * @see Zend_Db_Profiler_Query - */ - #require_once 'Zend/Db/Profiler/Query.php'; - $this->_queryProfiles[] = new Zend_Db_Profiler_Query($queryText, $queryType); - - end($this->_queryProfiles); - - return key($this->_queryProfiles); - } - - /** - * Ends a query. Pass it the handle that was returned by queryStart(). - * This will mark the query as ended and save the time. - * - * @param integer $queryId - * @throws Zend_Db_Profiler_Exception - * @return string Inform that a query is stored or ignored. - */ - public function queryEnd($queryId) - { - // Don't do anything if the Zend_Db_Profiler is not enabled. - if (!$this->_enabled) { - return self::IGNORED; - } - - // Check for a valid query handle. - if (!isset($this->_queryProfiles[$queryId])) { - /** - * @see Zend_Db_Profiler_Exception - */ - #require_once 'Zend/Db/Profiler/Exception.php'; - throw new Zend_Db_Profiler_Exception("Profiler has no query with handle '$queryId'."); - } - - $qp = $this->_queryProfiles[$queryId]; - - // Ensure that the query profile has not already ended - if ($qp->hasEnded()) { - /** - * @see Zend_Db_Profiler_Exception - */ - #require_once 'Zend/Db/Profiler/Exception.php'; - throw new Zend_Db_Profiler_Exception("Query with profiler handle '$queryId' has already ended."); - } - - // End the query profile so that the elapsed time can be calculated. - $qp->end(); - - /** - * If filtering by elapsed time is enabled, only keep the profile if - * it ran for the minimum time. - */ - if (null !== $this->_filterElapsedSecs && $qp->getElapsedSecs() < $this->_filterElapsedSecs) { - unset($this->_queryProfiles[$queryId]); - return self::IGNORED; - } - - /** - * If filtering by query type is enabled, only keep the query if - * it was one of the allowed types. - */ - if (null !== $this->_filterTypes && !($qp->getQueryType() & $this->_filterTypes)) { - unset($this->_queryProfiles[$queryId]); - return self::IGNORED; - } - - return self::STORED; - } - - /** - * Get a profile for a query. Pass it the same handle that was returned - * by queryStart() and it will return a Zend_Db_Profiler_Query object. - * - * @param integer $queryId - * @throws Zend_Db_Profiler_Exception - * @return Zend_Db_Profiler_Query - */ - public function getQueryProfile($queryId) - { - if (!array_key_exists($queryId, $this->_queryProfiles)) { - /** - * @see Zend_Db_Profiler_Exception - */ - #require_once 'Zend/Db/Profiler/Exception.php'; - throw new Zend_Db_Profiler_Exception("Query handle '$queryId' not found in profiler log."); - } - - return $this->_queryProfiles[$queryId]; - } - - /** - * Get an array of query profiles (Zend_Db_Profiler_Query objects). If $queryType - * is set to one of the Zend_Db_Profiler::* constants then only queries of that - * type will be returned. Normally, queries that have not yet ended will - * not be returned unless $showUnfinished is set to True. If no - * queries were found, False is returned. The returned array is indexed by the query - * profile handles. - * - * @param integer $queryType - * @param boolean $showUnfinished - * @return array|false - */ - public function getQueryProfiles($queryType = null, $showUnfinished = false) - { - $queryProfiles = array(); - foreach ($this->_queryProfiles as $key => $qp) { - if ($queryType === null) { - $condition = true; - } else { - $condition = ($qp->getQueryType() & $queryType); - } - - if (($qp->hasEnded() || $showUnfinished) && $condition) { - $queryProfiles[$key] = $qp; - } - } - - if (empty($queryProfiles)) { - $queryProfiles = false; - } - - return $queryProfiles; - } - - /** - * Get the total elapsed time (in seconds) of all of the profiled queries. - * Only queries that have ended will be counted. If $queryType is set to - * one or more of the Zend_Db_Profiler::* constants, the elapsed time will be calculated - * only for queries of the given type(s). - * - * @param integer $queryType OPTIONAL - * @return float - */ - public function getTotalElapsedSecs($queryType = null) - { - $elapsedSecs = 0; - foreach ($this->_queryProfiles as $key => $qp) { - if (null === $queryType) { - $condition = true; - } else { - $condition = ($qp->getQueryType() & $queryType); - } - if (($qp->hasEnded()) && $condition) { - $elapsedSecs += $qp->getElapsedSecs(); - } - } - return $elapsedSecs; - } - - /** - * Get the total number of queries that have been profiled. Only queries that have ended will - * be counted. If $queryType is set to one of the Zend_Db_Profiler::* constants, only queries of - * that type will be counted. - * - * @param integer $queryType OPTIONAL - * @return integer - */ - public function getTotalNumQueries($queryType = null) - { - if (null === $queryType) { - return count($this->_queryProfiles); - } - - $numQueries = 0; - foreach ($this->_queryProfiles as $qp) { - if ($qp->hasEnded() && ($qp->getQueryType() & $queryType)) { - $numQueries++; - } - } - - return $numQueries; - } - - /** - * Get the Zend_Db_Profiler_Query object for the last query that was run, regardless if it has - * ended or not. If the query has not ended, its end time will be null. If no queries have - * been profiled, false is returned. - * - * @return Zend_Db_Profiler_Query|false - */ - public function getLastQueryProfile() - { - if (empty($this->_queryProfiles)) { - return false; - } - - end($this->_queryProfiles); - - return current($this->_queryProfiles); - } - -} - diff --git a/lib/Zend/Db/Profiler/Exception.php b/lib/Zend/Db/Profiler/Exception.php deleted file mode 100644 index 47146e1ba50..00000000000 --- a/lib/Zend/Db/Profiler/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ -_label = $label; - if(!$this->_label) { - $this->_label = 'Zend_Db_Profiler_Firebug'; - } - } - - /** - * Enable or disable the profiler. If $enable is false, the profiler - * is disabled and will not log any queries sent to it. - * - * @param boolean $enable - * @return Zend_Db_Profiler Provides a fluent interface - */ - public function setEnabled($enable) - { - parent::setEnabled($enable); - - if ($this->getEnabled()) { - - if (!$this->_message) { - $this->_message = new Zend_Wildfire_Plugin_FirePhp_TableMessage($this->_label); - $this->_message->setBuffered(true); - $this->_message->setHeader(array('Time','Event','Parameters')); - $this->_message->setDestroy(true); - $this->_message->setOption('includeLineNumbers', false); - Zend_Wildfire_Plugin_FirePhp::getInstance()->send($this->_message); - } - - } else { - - if ($this->_message) { - $this->_message->setDestroy(true); - $this->_message = null; - } - - } - - return $this; - } - - /** - * Intercept the query end and log the profiling data. - * - * @param integer $queryId - * @throws Zend_Db_Profiler_Exception - * @return void - */ - public function queryEnd($queryId) - { - $state = parent::queryEnd($queryId); - - if (!$this->getEnabled() || $state == self::IGNORED) { - return; - } - - $this->_message->setDestroy(false); - - $profile = $this->getQueryProfile($queryId); - - $this->_totalElapsedTime += $profile->getElapsedSecs(); - - $this->_message->addRow(array((string)round((float) $profile->getElapsedSecs(),5), - $profile->getQuery(), - ($params=$profile->getQueryParams())?$params:null)); - - $this->updateMessageLabel(); - } - - /** - * Update the label of the message holding the profile info. - * - * @return void - */ - protected function updateMessageLabel() - { - if (!$this->_message) { - return; - } - $this->_message->setLabel(str_replace(array('%label%', - '%totalCount%', - '%totalDuration%'), - array($this->_label, - $this->getTotalNumQueries(), - (string)round($this->_totalElapsedTime,5)), - $this->_label_template)); - } -} diff --git a/lib/Zend/Db/Profiler/Query.php b/lib/Zend/Db/Profiler/Query.php deleted file mode 100644 index 97a7fef1fe7..00000000000 --- a/lib/Zend/Db/Profiler/Query.php +++ /dev/null @@ -1,213 +0,0 @@ -_query = $query; - $this->_queryType = $queryType; - // by default, and for backward-compatibility, start the click ticking - $this->start(); - } - - /** - * Clone handler for the query object. - * @return void - */ - public function __clone() - { - $this->_boundParams = array(); - $this->_endedMicrotime = null; - $this->start(); - } - - /** - * Starts the elapsed time click ticking. - * This can be called subsequent to object creation, - * to restart the clock. For instance, this is useful - * right before executing a prepared query. - * - * @return void - */ - public function start() - { - $this->_startedMicrotime = microtime(true); - } - - /** - * Ends the query and records the time so that the elapsed time can be determined later. - * - * @return void - */ - public function end() - { - $this->_endedMicrotime = microtime(true); - } - - /** - * Returns true if and only if the query has ended. - * - * @return boolean - */ - public function hasEnded() - { - return $this->_endedMicrotime !== null; - } - - /** - * Get the original SQL text of the query. - * - * @return string - */ - public function getQuery() - { - return $this->_query; - } - - /** - * Get the type of this query (one of the Zend_Db_Profiler::* constants) - * - * @return integer - */ - public function getQueryType() - { - return $this->_queryType; - } - - /** - * @param string $param - * @param mixed $variable - * @return void - */ - public function bindParam($param, $variable) - { - $this->_boundParams[$param] = $variable; - } - - /** - * @param array $param - * @return void - */ - public function bindParams(array $params) - { - if (array_key_exists(0, $params)) { - array_unshift($params, null); - unset($params[0]); - } - foreach ($params as $param => $value) { - $this->bindParam($param, $value); - } - } - - /** - * @return array - */ - public function getQueryParams() - { - return $this->_boundParams; - } - - /** - * Get the elapsed time (in seconds) that the query ran. - * If the query has not yet ended, false is returned. - * - * @return float|false - */ - public function getElapsedSecs() - { - if (null === $this->_endedMicrotime) { - return false; - } - - return $this->_endedMicrotime - $this->_startedMicrotime; - } - - /** - * Get the time (in seconds) when the profiler started running. - * - * @return bool|float - */ - public function getStartedMicrotime() - { - if(null === $this->_startedMicrotime) { - return false; - } - - return $this->_startedMicrotime; - } -} - diff --git a/lib/Zend/Db/Select.php b/lib/Zend/Db/Select.php deleted file mode 100644 index 25df46f3dee..00000000000 --- a/lib/Zend/Db/Select.php +++ /dev/null @@ -1,1358 +0,0 @@ - false, - self::COLUMNS => array(), - self::UNION => array(), - self::FROM => array(), - self::WHERE => array(), - self::GROUP => array(), - self::HAVING => array(), - self::ORDER => array(), - self::LIMIT_COUNT => null, - self::LIMIT_OFFSET => null, - self::FOR_UPDATE => false - ); - - /** - * Specify legal join types. - * - * @var array - */ - protected static $_joinTypes = array( - self::INNER_JOIN, - self::LEFT_JOIN, - self::RIGHT_JOIN, - self::FULL_JOIN, - self::CROSS_JOIN, - self::NATURAL_JOIN, - ); - - /** - * Specify legal union types. - * - * @var array - */ - protected static $_unionTypes = array( - self::SQL_UNION, - self::SQL_UNION_ALL - ); - - /** - * The component parts of a SELECT statement. - * Initialized to the $_partsInit array in the constructor. - * - * @var array - */ - protected $_parts = array(); - - /** - * Tracks which columns are being select from each table and join. - * - * @var array - */ - protected $_tableCols = array(); - - /** - * Class constructor - * - * @param Zend_Db_Adapter_Abstract $adapter - */ - public function __construct(Zend_Db_Adapter_Abstract $adapter) - { - $this->_adapter = $adapter; - $this->_parts = self::$_partsInit; - } - - /** - * Get bind variables - * - * @return array - */ - public function getBind() - { - return $this->_bind; - } - - /** - * Set bind variables - * - * @param mixed $bind - * @return Zend_Db_Select - */ - public function bind($bind) - { - $this->_bind = $bind; - - return $this; - } - - /** - * Makes the query SELECT DISTINCT. - * - * @param bool $flag Whether or not the SELECT is DISTINCT (default true). - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function distinct($flag = true) - { - $this->_parts[self::DISTINCT] = (bool) $flag; - return $this; - } - - /** - * Adds a FROM table and optional columns to the query. - * - * The first parameter $name can be a simple string, in which case the - * correlation name is generated automatically. If you want to specify - * the correlation name, the first parameter must be an associative - * array in which the key is the correlation name, and the value is - * the physical table name. For example, array('alias' => 'table'). - * The correlation name is prepended to all columns fetched for this - * table. - * - * The second parameter can be a single string or Zend_Db_Expr object, - * or else an array of strings or Zend_Db_Expr objects. - * - * The first parameter can be null or an empty string, in which case - * no correlation name is generated or prepended to the columns named - * in the second parameter. - * - * @param array|string|Zend_Db_Expr $name The table name or an associative array - * relating correlation name to table name. - * @param array|string|Zend_Db_Expr $cols The columns to select from this table. - * @param string $schema The schema name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function from($name, $cols = '*', $schema = null) - { - return $this->_join(self::FROM, $name, null, $cols, $schema); - } - - /** - * Specifies the columns used in the FROM clause. - * - * The parameter can be a single string or Zend_Db_Expr object, - * or else an array of strings or Zend_Db_Expr objects. - * - * @param array|string|Zend_Db_Expr $cols The columns to select from this table. - * @param string $correlationName Correlation name of target table. OPTIONAL - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function columns($cols = '*', $correlationName = null) - { - if ($correlationName === null && count($this->_parts[self::FROM])) { - $correlationNameKeys = array_keys($this->_parts[self::FROM]); - $correlationName = current($correlationNameKeys); - } - - if (!array_key_exists($correlationName, $this->_parts[self::FROM])) { - /** - * @see Zend_Db_Select_Exception - */ - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("No table has been specified for the FROM clause"); - } - - $this->_tableCols($correlationName, $cols); - - return $this; - } - - /** - * Adds a UNION clause to the query. - * - * The first parameter has to be an array of Zend_Db_Select or - * sql query strings. - * - * - * $sql1 = $db->select(); - * $sql2 = "SELECT ..."; - * $select = $db->select() - * ->union(array($sql1, $sql2)) - * ->order("id"); - * - * - * @param array $select Array of select clauses for the union. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function union($select = array(), $type = self::SQL_UNION) - { - if (!is_array($select)) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception( - "union() only accepts an array of Zend_Db_Select instances of sql query strings." - ); - } - - if (!in_array($type, self::$_unionTypes)) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Invalid union type '{$type}'"); - } - - foreach ($select as $target) { - $this->_parts[self::UNION][] = array($target, $type); - } - - return $this; - } - - /** - * Adds a JOIN table and columns to the query. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param string $cond Join on this condition. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function join($name, $cond, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->joinInner($name, $cond, $cols, $schema); - } - - /** - * Add an INNER JOIN table and colums to the query - * Rows in both tables are matched according to the expression - * in the $cond argument. The result set is comprised - * of all cases where rows from the left table match - * rows from the right table. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param string $cond Join on this condition. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinInner($name, $cond, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::INNER_JOIN, $name, $cond, $cols, $schema); - } - - /** - * Add a LEFT OUTER JOIN table and colums to the query - * All rows from the left operand table are included, - * matching rows from the right operand table included, - * and the columns from the right operand table are filled - * with NULLs if no row exists matching the left table. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param string $cond Join on this condition. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinLeft($name, $cond, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::LEFT_JOIN, $name, $cond, $cols, $schema); - } - - /** - * Add a RIGHT OUTER JOIN table and colums to the query. - * Right outer join is the complement of left outer join. - * All rows from the right operand table are included, - * matching rows from the left operand table included, - * and the columns from the left operand table are filled - * with NULLs if no row exists matching the right table. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param string $cond Join on this condition. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinRight($name, $cond, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::RIGHT_JOIN, $name, $cond, $cols, $schema); - } - - /** - * Add a FULL OUTER JOIN table and colums to the query. - * A full outer join is like combining a left outer join - * and a right outer join. All rows from both tables are - * included, paired with each other on the same row of the - * result set if they satisfy the join condition, and otherwise - * paired with NULLs in place of columns from the other table. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param string $cond Join on this condition. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinFull($name, $cond, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::FULL_JOIN, $name, $cond, $cols, $schema); - } - - /** - * Add a CROSS JOIN table and colums to the query. - * A cross join is a cartesian product; there is no join condition. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinCross($name, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::CROSS_JOIN, $name, null, $cols, $schema); - } - - /** - * Add a NATURAL JOIN table and colums to the query. - * A natural join assumes an equi-join across any column(s) - * that appear with the same name in both tables. - * Only natural inner joins are supported by this API, - * even though SQL permits natural outer joins as well. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param array|string|Zend_Db_Expr $name The table name. - * @param array|string $cols The columns to select from the joined table. - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function joinNatural($name, $cols = self::SQL_WILDCARD, $schema = null) - { - return $this->_join(self::NATURAL_JOIN, $name, null, $cols, $schema); - } - - /** - * Adds a WHERE condition to the query by AND. - * - * If a value is passed as the second param, it will be quoted - * and replaced into the condition wherever a question-mark - * appears. Array values are quoted and comma-separated. - * - * - * // simplest but non-secure - * $select->where("id = $id"); - * - * // secure (ID is quoted but matched anyway) - * $select->where('id = ?', $id); - * - * // alternatively, with named binding - * $select->where('id = :id'); - * - * - * Note that it is more correct to use named bindings in your - * queries for values other than strings. When you use named - * bindings, don't forget to pass the values when actually - * making a query: - * - * - * $db->fetchAll($select, array('id' => 5)); - * - * - * @param string $cond The WHERE condition. - * @param Zend_Db_Select|Zend_Db_Expr|array|null|int|string|float $value OPTIONAL The value to quote into the condition. - * @param int $type OPTIONAL The type of the given value - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function where($cond, $value = null, $type = null) - { - $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, true); - - return $this; - } - - /** - * Adds a WHERE condition to the query by OR. - * - * Otherwise identical to where(). - * - * @param string $cond The WHERE condition. - * @param Zend_Db_Select|Zend_Db_Expr|array|null|int|string|float $value OPTIONAL The value to quote into the condition. - * @param int $type OPTIONAL The type of the given value - * @return Zend_Db_Select This Zend_Db_Select object. - * - * @see where() - */ - public function orWhere($cond, $value = null, $type = null) - { - $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, false); - - return $this; - } - - /** - * Adds grouping to the query. - * - * @param array|string $spec The column(s) to group by. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function group($spec) - { - if (!is_array($spec)) { - $spec = array($spec); - } - - foreach ($spec as $val) { - if (preg_match(self::REGEX_COLUMN_EXPR, (string) $val)) { - $val = new Zend_Db_Expr($val); - } - $this->_parts[self::GROUP][] = $val; - } - - return $this; - } - - /** - * Adds a HAVING condition to the query by AND. - * - * If a value is passed as the second param, it will be quoted - * and replaced into the condition wherever a question-mark - * appears. See {@link where()} for an example - * - * @param string $cond The HAVING condition. - * @param mixed $value OPTIONAL The value to quote into the condition. - * @param int $type OPTIONAL The type of the given value - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function having($cond, $value = null, $type = null) - { - if ($value !== null) { - $cond = $this->_adapter->quoteInto($cond, $value, $type); - } - - if ($this->_parts[self::HAVING]) { - $this->_parts[self::HAVING][] = self::SQL_AND . " ($cond)"; - } else { - $this->_parts[self::HAVING][] = "($cond)"; - } - - return $this; - } - - /** - * Adds a HAVING condition to the query by OR. - * - * Otherwise identical to orHaving(). - * - * @param string $cond The HAVING condition. - * @param mixed $value OPTIONAL The value to quote into the condition. - * @param int $type OPTIONAL The type of the given value - * @return Zend_Db_Select This Zend_Db_Select object. - * - * @see having() - */ - public function orHaving($cond, $value = null, $type = null) - { - if ($value !== null) { - $cond = $this->_adapter->quoteInto($cond, $value, $type); - } - - if ($this->_parts[self::HAVING]) { - $this->_parts[self::HAVING][] = self::SQL_OR . " ($cond)"; - } else { - $this->_parts[self::HAVING][] = "($cond)"; - } - - return $this; - } - - /** - * Adds a row order to the query. - * - * @param mixed $spec The column(s) and direction to order by. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function order($spec) - { - if (!is_array($spec)) { - $spec = array($spec); - } - - // force 'ASC' or 'DESC' on each order spec, default is ASC. - foreach ($spec as $val) { - if ($val instanceof Zend_Db_Expr) { - $expr = $val->__toString(); - if (empty($expr)) { - continue; - } - $this->_parts[self::ORDER][] = $val; - } else { - if (empty($val)) { - continue; - } - $direction = self::SQL_ASC; - if (preg_match('/(.*\W)(' . self::SQL_ASC . '|' . self::SQL_DESC . ')\b/si', $val, $matches)) { - $val = trim($matches[1]); - $direction = $matches[2]; - } - if (preg_match(self::REGEX_COLUMN_EXPR, (string) $val)) { - $val = new Zend_Db_Expr($val); - } - $this->_parts[self::ORDER][] = array($val, $direction); - } - } - - return $this; - } - - /** - * Sets a limit count and offset to the query. - * - * @param int $count OPTIONAL The number of rows to return. - * @param int $offset OPTIONAL Start returning after this many rows. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function limit($count = null, $offset = null) - { - $this->_parts[self::LIMIT_COUNT] = (int) $count; - $this->_parts[self::LIMIT_OFFSET] = (int) $offset; - return $this; - } - - /** - * Sets the limit and count by page number. - * - * @param int $page Limit results to this page number. - * @param int $rowCount Use this many rows per page. - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function limitPage($page, $rowCount) - { - $page = ($page > 0) ? $page : 1; - $rowCount = ($rowCount > 0) ? $rowCount : 1; - $this->_parts[self::LIMIT_COUNT] = (int) $rowCount; - $this->_parts[self::LIMIT_OFFSET] = (int) $rowCount * ($page - 1); - return $this; - } - - /** - * Makes the query SELECT FOR UPDATE. - * - * @param bool $flag Whether or not the SELECT is FOR UPDATE (default true). - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function forUpdate($flag = true) - { - $this->_parts[self::FOR_UPDATE] = (bool) $flag; - return $this; - } - - /** - * Get part of the structured information for the current query. - * - * @param string $part - * @return mixed - * @throws Zend_Db_Select_Exception - */ - public function getPart($part) - { - $part = strtolower($part); - if (!array_key_exists($part, $this->_parts)) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Invalid Select part '$part'"); - } - return $this->_parts[$part]; - } - - /** - * Executes the current select object and returns the result - * - * @param integer $fetchMode OPTIONAL - * @param mixed $bind An array of data to bind to the placeholders. - * @return PDO_Statement|Zend_Db_Statement - */ - public function query($fetchMode = null, $bind = array()) - { - if (!empty($bind)) { - $this->bind($bind); - } - - $stmt = $this->_adapter->query($this); - if ($fetchMode == null) { - $fetchMode = $this->_adapter->getFetchMode(); - } - $stmt->setFetchMode($fetchMode); - return $stmt; - } - - /** - * Converts this object to an SQL SELECT string. - * - * @return string|null This object as a SELECT string. (or null if a string cannot be produced.) - */ - public function assemble() - { - $sql = self::SQL_SELECT; - foreach (array_keys(self::$_partsInit) as $part) { - $method = '_render' . ucfirst($part); - if (method_exists($this, $method)) { - $sql = $this->$method($sql); - } - } - return $sql; - } - - /** - * Clear parts of the Select object, or an individual part. - * - * @param string $part OPTIONAL - * @return Zend_Db_Select - */ - public function reset($part = null) - { - if ($part == null) { - $this->_parts = self::$_partsInit; - } elseif (array_key_exists($part, self::$_partsInit)) { - $this->_parts[$part] = self::$_partsInit[$part]; - } - return $this; - } - - /** - * Gets the Zend_Db_Adapter_Abstract for this - * particular Zend_Db_Select object. - * - * @return Zend_Db_Adapter_Abstract - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Populate the {@link $_parts} 'join' key - * - * Does the dirty work of populating the join key. - * - * The $name and $cols parameters follow the same logic - * as described in the from() method. - * - * @param null|string $type Type of join; inner, left, and null are currently supported - * @param array|string|Zend_Db_Expr $name Table name - * @param string $cond Join on this condition - * @param array|string $cols The columns to select from the joined table - * @param string $schema The database name to specify, if any. - * @return Zend_Db_Select This Zend_Db_Select object - * @throws Zend_Db_Select_Exception - */ - protected function _join($type, $name, $cond, $cols, $schema = null) - { - if (!in_array($type, self::$_joinTypes) && $type != self::FROM) { - /** - * @see Zend_Db_Select_Exception - */ - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Invalid join type '$type'"); - } - - if (count($this->_parts[self::UNION])) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Invalid use of table with " . self::SQL_UNION); - } - - if (empty($name)) { - $correlationName = $tableName = ''; - } elseif (is_array($name)) { - // Must be array($correlationName => $tableName) or array($ident, ...) - foreach ($name as $_correlationName => $_tableName) { - if (is_string($_correlationName)) { - // We assume the key is the correlation name and value is the table name - $tableName = $_tableName; - $correlationName = $_correlationName; - } else { - // We assume just an array of identifiers, with no correlation name - $tableName = $_tableName; - $correlationName = $this->_uniqueCorrelation($tableName); - } - break; - } - } elseif ($name instanceof Zend_Db_Expr|| $name instanceof Zend_Db_Select) { - $tableName = $name; - $correlationName = $this->_uniqueCorrelation('t'); - } elseif (preg_match('/^(.+)\s+AS\s+(.+)$/i', $name, $m)) { - $tableName = $m[1]; - $correlationName = $m[2]; - } else { - $tableName = $name; - $correlationName = $this->_uniqueCorrelation($tableName); - } - - // Schema from table name overrides schema argument - if (!is_object($tableName) && false !== strpos($tableName, '.')) { - list($schema, $tableName) = explode('.', $tableName); - } - - $lastFromCorrelationName = null; - if (!empty($correlationName)) { - if (array_key_exists($correlationName, $this->_parts[self::FROM])) { - /** - * @see Zend_Db_Select_Exception - */ - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("You cannot define a correlation name '$correlationName' more than once"); - } - - if ($type == self::FROM) { - // append this from after the last from joinType - $tmpFromParts = $this->_parts[self::FROM]; - $this->_parts[self::FROM] = array(); - // move all the froms onto the stack - while ($tmpFromParts) { - $currentCorrelationName = key($tmpFromParts); - if ($tmpFromParts[$currentCorrelationName]['joinType'] != self::FROM) { - break; - } - $lastFromCorrelationName = $currentCorrelationName; - $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts); - } - } else { - $tmpFromParts = array(); - } - $this->_parts[self::FROM][$correlationName] = array( - 'joinType' => $type, - 'schema' => $schema, - 'tableName' => $tableName, - 'joinCondition' => $cond - ); - while ($tmpFromParts) { - $currentCorrelationName = key($tmpFromParts); - $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts); - } - } - - // add to the columns from this joined table - if ($type == self::FROM && $lastFromCorrelationName == null) { - $lastFromCorrelationName = true; - } - $this->_tableCols($correlationName, $cols, $lastFromCorrelationName); - - return $this; - } - - /** - * Handle JOIN... USING... syntax - * - * This is functionality identical to the existing JOIN methods, however - * the join condition can be passed as a single column name. This method - * then completes the ON condition by using the same field for the FROM - * table and the JOIN table. - * - * - * $select = $db->select()->from('table1') - * ->joinUsing('table2', 'column1'); - * - * // SELECT * FROM table1 JOIN table2 ON table1.column1 = table2.column2 - * - * - * These joins are called by the developer simply by adding 'Using' to the - * method name. E.g. - * * joinUsing - * * joinInnerUsing - * * joinFullUsing - * * joinRightUsing - * * joinLeftUsing - * - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function _joinUsing($type, $name, $cond, $cols = '*', $schema = null) - { - if (empty($this->_parts[self::FROM])) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("You can only perform a joinUsing after specifying a FROM table"); - } - - $join = $this->_adapter->quoteIdentifier(key($this->_parts[self::FROM]), true); - $from = $this->_adapter->quoteIdentifier($this->_uniqueCorrelation($name), true); - - $joinCond = array(); - foreach ((array)$cond as $fieldName) { - $cond1 = $from . '.' . $fieldName; - $cond2 = $join . '.' . $fieldName; - $joinCond[] = $cond1 . ' = ' . $cond2; - } - $cond = implode(' '.self::SQL_AND.' ', $joinCond); - - return $this->_join($type, $name, $cond, $cols, $schema); - } - - /** - * Generate a unique correlation name - * - * @param string|array $name A qualified identifier. - * @return string A unique correlation name. - */ - private function _uniqueCorrelation($name) - { - if (is_array($name)) { - $k = key($name); - $c = is_string($k) ? $k : end($name); - } else { - // Extract just the last name of a qualified table name - $dot = strrpos($name,'.'); - $c = ($dot === false) ? $name : substr($name, $dot+1); - } - for ($i = 2; array_key_exists($c, $this->_parts[self::FROM]); ++$i) { - $c = $name . '_' . (string) $i; - } - return $c; - } - - /** - * Adds to the internal table-to-column mapping array. - * - * @param string $tbl The table/join the columns come from. - * @param array|string $cols The list of columns; preferably as - * an array, but possibly as a string containing one column. - * @param bool|string True if it should be prepended, a correlation name if it should be inserted - * @return void - */ - protected function _tableCols($correlationName, $cols, $afterCorrelationName = null) - { - if (!is_array($cols)) { - $cols = array($cols); - } - - if ($correlationName == null) { - $correlationName = ''; - } - - $columnValues = array(); - - foreach (array_filter($cols) as $alias => $col) { - $currentCorrelationName = $correlationName; - if (is_string($col)) { - // Check for a column matching " AS " and extract the alias name - if (preg_match('/^(.+)\s+' . self::SQL_AS . '\s+(.+)$/i', $col, $m)) { - $col = $m[1]; - $alias = $m[2]; - } - // Check for columns that look like functions and convert to Zend_Db_Expr - if (preg_match(self::REGEX_COLUMN_EXPR, (string) $col)) { - $col = new Zend_Db_Expr($col); - } elseif (preg_match('/(.+)\.(.+)/', $col, $m)) { - $currentCorrelationName = $m[1]; - $col = $m[2]; - } - } - $columnValues[] = array($currentCorrelationName, $col, is_string($alias) ? $alias : null); - } - - if ($columnValues) { - - // should we attempt to prepend or insert these values? - if ($afterCorrelationName === true || is_string($afterCorrelationName)) { - $tmpColumns = $this->_parts[self::COLUMNS]; - $this->_parts[self::COLUMNS] = array(); - } else { - $tmpColumns = array(); - } - - // find the correlation name to insert after - if (is_string($afterCorrelationName)) { - while ($tmpColumns) { - $this->_parts[self::COLUMNS][] = $currentColumn = array_shift($tmpColumns); - if ($currentColumn[0] == $afterCorrelationName) { - break; - } - } - } - - // apply current values to current stack - foreach ($columnValues as $columnValue) { - array_push($this->_parts[self::COLUMNS], $columnValue); - } - - // finish ensuring that all previous values are applied (if they exist) - while ($tmpColumns) { - array_push($this->_parts[self::COLUMNS], array_shift($tmpColumns)); - } - } - } - - /** - * Internal function for creating the where clause - * - * @param string $condition - * @param Zend_Db_Select|Zend_Db_Expr|array|null|int|string|float $value optional - * @param string $type optional - * @param boolean $bool true = AND, false = OR - * @return string clause - */ - protected function _where($condition, $value = null, $type = null, $bool = true) - { - if (count($this->_parts[self::UNION])) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Invalid use of where clause with " . self::SQL_UNION); - } - - if ($value !== null) { - $condition = $this->_adapter->quoteInto($condition, $value, $type); - } - - $cond = ""; - if ($this->_parts[self::WHERE]) { - if ($bool === true) { - $cond = self::SQL_AND . ' '; - } else { - $cond = self::SQL_OR . ' '; - } - } - - return $cond . "($condition)"; - } - - /** - * @return array - */ - protected function _getDummyTable() - { - return array(); - } - - /** - * Return a quoted schema name - * - * @param string $schema The schema name OPTIONAL - * @return string|null - */ - protected function _getQuotedSchema($schema = null) - { - if ($schema === null) { - return null; - } - return $this->_adapter->quoteIdentifier($schema, true) . '.'; - } - - /** - * Return a quoted table name - * - * @param string $tableName The table name - * @param string $correlationName The correlation name OPTIONAL - * @return string - */ - protected function _getQuotedTable($tableName, $correlationName = null) - { - return $this->_adapter->quoteTableAs($tableName, $correlationName, true); - } - - /** - * Render DISTINCT clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderDistinct($sql) - { - if ($this->_parts[self::DISTINCT]) { - $sql .= ' ' . self::SQL_DISTINCT; - } - - return $sql; - } - - /** - * Render DISTINCT clause - * - * @param string $sql SQL query - * @return string|null - */ - protected function _renderColumns($sql) - { - if (!count($this->_parts[self::COLUMNS])) { - return null; - } - - $columns = array(); - foreach ($this->_parts[self::COLUMNS] as $columnEntry) { - list($correlationName, $column, $alias) = $columnEntry; - if ($column instanceof Zend_Db_Expr) { - $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true); - } else { - if ($column == self::SQL_WILDCARD) { - $column = new Zend_Db_Expr(self::SQL_WILDCARD); - $alias = null; - } - if (empty($correlationName)) { - $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true); - } else { - $columns[] = $this->_adapter->quoteColumnAs(array($correlationName, $column), $alias, true); - } - } - } - - return $sql . ' ' . implode(', ', $columns); - } - - /** - * Render FROM clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderFrom($sql) - { - /* - * If no table specified, use RDBMS-dependent solution - * for table-less query. e.g. DUAL in Oracle. - */ - if (empty($this->_parts[self::FROM])) { - $this->_parts[self::FROM] = $this->_getDummyTable(); - } - - $from = array(); - - foreach ($this->_parts[self::FROM] as $correlationName => $table) { - $tmp = ''; - - $joinType = ($table['joinType'] == self::FROM) ? self::INNER_JOIN : $table['joinType']; - - // Add join clause (if applicable) - if (! empty($from)) { - $tmp .= ' ' . strtoupper($joinType) . ' '; - } - - $tmp .= $this->_getQuotedSchema($table['schema']); - $tmp .= $this->_getQuotedTable($table['tableName'], $correlationName); - - // Add join conditions (if applicable) - if (!empty($from) && ! empty($table['joinCondition'])) { - $tmp .= ' ' . self::SQL_ON . ' ' . $table['joinCondition']; - } - - // Add the table name and condition add to the list - $from[] = $tmp; - } - - // Add the list of all joins - if (!empty($from)) { - $sql .= ' ' . self::SQL_FROM . ' ' . implode("\n", $from); - } - - return $sql; - } - - /** - * Render UNION query - * - * @param string $sql SQL query - * @return string - */ - protected function _renderUnion($sql) - { - if ($this->_parts[self::UNION]) { - $parts = count($this->_parts[self::UNION]); - foreach ($this->_parts[self::UNION] as $cnt => $union) { - list($target, $type) = $union; - if ($target instanceof Zend_Db_Select) { - $target = $target->assemble(); - } - $sql .= $target; - if ($cnt < $parts - 1) { - $sql .= ' ' . $type . ' '; - } - } - } - - return $sql; - } - - /** - * Render WHERE clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderWhere($sql) - { - if ($this->_parts[self::FROM] && $this->_parts[self::WHERE]) { - $sql .= ' ' . self::SQL_WHERE . ' ' . implode(' ', $this->_parts[self::WHERE]); - } - - return $sql; - } - - /** - * Render GROUP clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderGroup($sql) - { - if ($this->_parts[self::FROM] && $this->_parts[self::GROUP]) { - $group = array(); - foreach ($this->_parts[self::GROUP] as $term) { - $group[] = $this->_adapter->quoteIdentifier($term, true); - } - $sql .= ' ' . self::SQL_GROUP_BY . ' ' . implode(",\n\t", $group); - } - - return $sql; - } - - /** - * Render HAVING clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderHaving($sql) - { - if ($this->_parts[self::FROM] && $this->_parts[self::HAVING]) { - $sql .= ' ' . self::SQL_HAVING . ' ' . implode(' ', $this->_parts[self::HAVING]); - } - - return $sql; - } - - /** - * Render ORDER clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderOrder($sql) - { - if ($this->_parts[self::ORDER]) { - $order = array(); - foreach ($this->_parts[self::ORDER] as $term) { - if (is_array($term)) { - if(is_numeric($term[0]) && strval(intval($term[0])) == $term[0]) { - $order[] = (int)trim($term[0]) . ' ' . $term[1]; - } else { - $order[] = $this->_adapter->quoteIdentifier($term[0], true) . ' ' . $term[1]; - } - } elseif (is_numeric($term) && strval(intval($term)) == $term) { - $order[] = (int)trim($term); - } else { - $order[] = $this->_adapter->quoteIdentifier($term, true); - } - } - $sql .= ' ' . self::SQL_ORDER_BY . ' ' . implode(', ', $order); - } - - return $sql; - } - - /** - * Render LIMIT OFFSET clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderLimitoffset($sql) - { - $count = 0; - $offset = 0; - - if (!empty($this->_parts[self::LIMIT_OFFSET])) { - $offset = (int) $this->_parts[self::LIMIT_OFFSET]; - $count = PHP_INT_MAX; - } - - if (!empty($this->_parts[self::LIMIT_COUNT])) { - $count = (int) $this->_parts[self::LIMIT_COUNT]; - } - - /* - * Add limits clause - */ - if ($count > 0) { - $sql = trim($this->_adapter->limit($sql, $count, $offset)); - } - - return $sql; - } - - /** - * Render FOR UPDATE clause - * - * @param string $sql SQL query - * @return string - */ - protected function _renderForupdate($sql) - { - if ($this->_parts[self::FOR_UPDATE]) { - $sql .= ' ' . self::SQL_FOR_UPDATE; - } - - return $sql; - } - - /** - * Turn magic function calls into non-magic function calls - * for joinUsing syntax - * - * @param string $method - * @param array $args OPTIONAL Zend_Db_Table_Select query modifier - * @return Zend_Db_Select - * @throws Zend_Db_Select_Exception If an invalid method is called. - */ - public function __call($method, array $args) - { - $matches = array(); - - /** - * Recognize methods for Has-Many cases: - * findParent() - * findParentBy() - * Use the non-greedy pattern repeat modifier e.g. \w+? - */ - if (preg_match('/^join([a-zA-Z]*?)Using$/', $method, $matches)) { - $type = strtolower($matches[1]); - if ($type) { - $type .= ' join'; - if (!in_array($type, self::$_joinTypes)) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Unrecognized method '$method()'"); - } - if (in_array($type, array(self::CROSS_JOIN, self::NATURAL_JOIN))) { - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Cannot perform a joinUsing with method '$method()'"); - } - } else { - $type = self::INNER_JOIN; - } - array_unshift($args, $type); - return call_user_func_array(array($this, '_joinUsing'), $args); - } - - #require_once 'Zend/Db/Select/Exception.php'; - throw new Zend_Db_Select_Exception("Unrecognized method '$method()'"); - } - - /** - * Implements magic method. - * - * @return string This object as a SELECT string. - */ - public function __toString() - { - try { - $sql = $this->assemble(); - } catch (Exception $e) { - trigger_error($e->getMessage(), E_USER_WARNING); - $sql = ''; - } - return (string)$sql; - } - -} diff --git a/lib/Zend/Db/Select/Exception.php b/lib/Zend/Db/Select/Exception.php deleted file mode 100644 index 19afeb79551..00000000000 --- a/lib/Zend/Db/Select/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ -_adapter = $adapter; - if ($sql instanceof Zend_Db_Select) { - $sql = $sql->assemble(); - } - $this->_parseParameters($sql); - $this->_prepare($sql); - - $this->_queryId = $this->_adapter->getProfiler()->queryStart($sql); - } - - /** - * Internal method called by abstract statment constructor to setup - * the driver level statement - * - * @return void - */ - protected function _prepare($sql) - { - return; - } - - /** - * @param string $sql - * @return void - */ - protected function _parseParameters($sql) - { - $sql = $this->_stripQuoted($sql); - - // split into text and params - $this->_sqlSplit = preg_split('/(\?|\:[a-zA-Z0-9_]+)/', - $sql, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); - - // map params - $this->_sqlParam = array(); - foreach ($this->_sqlSplit as $key => $val) { - if ($val == '?') { - if ($this->_adapter->supportsParameters('positional') === false) { - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception("Invalid bind-variable position '$val'"); - } - } else if ($val[0] == ':') { - if ($this->_adapter->supportsParameters('named') === false) { - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception("Invalid bind-variable name '$val'"); - } - } - $this->_sqlParam[] = $val; - } - - // set up for binding - $this->_bindParam = array(); - } - - /** - * Remove parts of a SQL string that contain quoted strings - * of values or identifiers. - * - * @param string $sql - * @return string - */ - protected function _stripQuoted($sql) - { - - // get the character for value quoting - // this should be ' - $q = $this->_adapter->quote('a'); - $q = $q[0]; - // get the value used as an escaped quote, - // e.g. \' or '' - $qe = $this->_adapter->quote($q); - $qe = substr($qe, 1, 2); - $qe = preg_quote($qe, '/'); - $escapeChar = substr($qe,0,1); - // remove 'foo\'bar' - if (!empty($q)) { - $escapeChar = preg_quote($escapeChar, '/'); - // this segfaults only after 65,000 characters instead of 9,000 - $sql = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', $sql); - } - - // get a version of the SQL statement with all quoted - // values and delimited identifiers stripped out - // remove "foo\"bar" - $sql = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', $sql); - - // get the character for delimited id quotes, - // this is usually " but in MySQL is ` - $d = $this->_adapter->quoteIdentifier('a'); - $d = $d[0]; - // get the value used as an escaped delimited id quote, - // e.g. \" or "" or \` - $de = $this->_adapter->quoteIdentifier($d); - $de = substr($de, 1, 2); - $de = preg_quote($de, '/'); - // Note: $de and $d where never used..., now they are: - $sql = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', $sql); - return $sql; - } - - /** - * Bind a column of the statement result set to a PHP variable. - * - * @param string $column Name the column in the result set, either by - * position or by name. - * @param mixed $param Reference to the PHP variable containing the value. - * @param mixed $type OPTIONAL - * @return bool - */ - public function bindColumn($column, &$param, $type = null) - { - $this->_bindColumn[$column] =& $param; - return true; - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - */ - public function bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - if (!is_int($parameter) && !is_string($parameter)) { - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception('Invalid bind-variable position'); - } - - $position = null; - if (($intval = (int) $parameter) > 0 && $this->_adapter->supportsParameters('positional')) { - if ($intval >= 1 || $intval <= count($this->_sqlParam)) { - $position = $intval; - } - } else if ($this->_adapter->supportsParameters('named')) { - if ($parameter[0] != ':') { - $parameter = ':' . $parameter; - } - if (in_array($parameter, $this->_sqlParam) !== false) { - $position = $parameter; - } - } - - if ($position === null) { - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception("Invalid bind-variable position '$parameter'"); - } - - // Finally we are assured that $position is valid - $this->_bindParam[$position] =& $variable; - return $this->_bindParam($position, $variable, $type, $length, $options); - } - - /** - * Binds a value to a parameter. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $value Scalar value to bind to the parameter. - * @param mixed $type OPTIONAL Datatype of the parameter. - * @return bool - */ - public function bindValue($parameter, $value, $type = null) - { - return $this->bindParam($parameter, $value, $type); - } - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - */ - public function execute(array $params = null) - { - /* - * Simple case - no query profiler to manage. - */ - if ($this->_queryId === null) { - return $this->_execute($params); - } - - /* - * Do the same thing, but with query profiler - * management before and after the execute. - */ - $prof = $this->_adapter->getProfiler(); - $qp = $prof->getQueryProfile($this->_queryId); - if ($qp->hasEnded()) { - $this->_queryId = $prof->queryClone($qp); - $qp = $prof->getQueryProfile($this->_queryId); - } - if ($params !== null) { - $qp->bindParams($params); - } else { - $qp->bindParams($this->_bindParam); - } - $qp->start($this->_queryId); - - $retval = $this->_execute($params); - - $prof->queryEnd($this->_queryId); - - return $retval; - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - */ - public function fetchAll($style = null, $col = null) - { - $data = array(); - if ($style === Zend_Db::FETCH_COLUMN && $col === null) { - $col = 0; - } - if ($col === null) { - while ($row = $this->fetch($style)) { - $data[] = $row; - } - } else { - while (false !== ($val = $this->fetchColumn($col))) { - $data[] = $val; - } - } - return $data; - } - - /** - * Returns a single column from the next row of a result set. - * - * @param int $col OPTIONAL Position of the column to fetch. - * @return string One value from the next row of result set, or false. - */ - public function fetchColumn($col = 0) - { - $data = array(); - $col = (int) $col; - $row = $this->fetch(Zend_Db::FETCH_NUM); - if (!is_array($row)) { - return false; - } - return $row[$col]; - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class, or false. - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - $obj = new $class($config); - $row = $this->fetch(Zend_Db::FETCH_ASSOC); - if (!is_array($row)) { - return false; - } - foreach ($row as $key => $val) { - $obj->$key = $val; - } - return $obj; - } - - /** - * Retrieve a statement attribute. - * - * @param string $key Attribute name. - * @return mixed Attribute value. - */ - public function getAttribute($key) - { - if (array_key_exists($key, $this->_attribute)) { - return $this->_attribute[$key]; - } - } - - /** - * Set a statement attribute. - * - * @param string $key Attribute name. - * @param mixed $val Attribute value. - * @return bool - */ - public function setAttribute($key, $val) - { - $this->_attribute[$key] = $val; - } - - /** - * Set the default fetch mode for this statement. - * - * @param int $mode The fetch mode. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function setFetchMode($mode) - { - switch ($mode) { - case Zend_Db::FETCH_NUM: - case Zend_Db::FETCH_ASSOC: - case Zend_Db::FETCH_BOTH: - case Zend_Db::FETCH_OBJ: - $this->_fetchMode = $mode; - break; - case Zend_Db::FETCH_BOUND: - default: - $this->closeCursor(); - /** - * @see Zend_Db_Statement_Exception - */ - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception('invalid fetch mode'); - break; - } - } - - /** - * Helper function to map retrieved row - * to bound column variables - * - * @param array $row - * @return bool True - */ - public function _fetchBound($row) - { - foreach ($row as $key => $value) { - // bindColumn() takes 1-based integer positions - // but fetch() returns 0-based integer indexes - if (is_int($key)) { - $key++; - } - // set results only to variables that were bound previously - if (isset($this->_bindColumn[$key])) { - $this->_bindColumn[$key] = $value; - } - } - return true; - } - - /** - * Gets the Zend_Db_Adapter_Abstract for this - * particular Zend_Db_Statement object. - * - * @return Zend_Db_Adapter_Abstract - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Gets the resource or object setup by the - * _parse - * @return unknown_type - */ - public function getDriverStatement() - { - return $this->_stmt; - } -} diff --git a/lib/Zend/Db/Statement/Db2.php b/lib/Zend/Db/Statement/Db2.php deleted file mode 100644 index 327d37b2f7d..00000000000 --- a/lib/Zend/Db/Statement/Db2.php +++ /dev/null @@ -1,360 +0,0 @@ -_adapter->getConnection(); - - // db2_prepare on i5 emits errors, these need to be - // suppressed so that proper exceptions can be thrown - $this->_stmt = @db2_prepare($connection, $sql); - - if (!$this->_stmt) { - /** - * @see Zend_Db_Statement_Db2_Exception - */ - #require_once 'Zend/Db/Statement/Db2/Exception.php'; - throw new Zend_Db_Statement_Db2_Exception( - db2_stmt_errormsg(), - db2_stmt_error() - ); - } - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Db2_Exception - */ - public function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - if ($type === null) { - $type = DB2_PARAM_IN; - } - - if (isset($options['data-type'])) { - $datatype = $options['data-type']; - } else { - $datatype = DB2_CHAR; - } - - if (!db2_bind_param($this->_stmt, $parameter, "variable", $type, $datatype)) { - /** - * @see Zend_Db_Statement_Db2_Exception - */ - #require_once 'Zend/Db/Statement/Db2/Exception.php'; - throw new Zend_Db_Statement_Db2_Exception( - db2_stmt_errormsg(), - db2_stmt_error() - ); - } - - return true; - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - */ - public function closeCursor() - { - if (!$this->_stmt) { - return false; - } - db2_free_stmt($this->_stmt); - $this->_stmt = false; - return true; - } - - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - */ - public function columnCount() - { - if (!$this->_stmt) { - return false; - } - return db2_num_fields($this->_stmt); - } - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - */ - public function errorCode() - { - if (!$this->_stmt) { - return false; - } - - $error = db2_stmt_error(); - if ($error === '') { - return false; - } - - return $error; - } - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - */ - public function errorInfo() - { - $error = $this->errorCode(); - if ($error === false){ - return false; - } - - /* - * Return three-valued array like PDO. But DB2 does not distinguish - * between SQLCODE and native RDBMS error code, so repeat the SQLCODE. - */ - return array( - $error, - $error, - db2_stmt_errormsg() - ); - } - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Db2_Exception - */ - public function _execute(array $params = null) - { - if (!$this->_stmt) { - return false; - } - - $retval = true; - if ($params !== null) { - $retval = @db2_execute($this->_stmt, $params); - } else { - $retval = @db2_execute($this->_stmt); - } - - if ($retval === false) { - /** - * @see Zend_Db_Statement_Db2_Exception - */ - #require_once 'Zend/Db/Statement/Db2/Exception.php'; - throw new Zend_Db_Statement_Db2_Exception( - db2_stmt_errormsg(), - db2_stmt_error()); - } - - $this->_keys = array(); - if ($field_num = $this->columnCount()) { - for ($i = 0; $i < $field_num; $i++) { - $name = db2_field_name($this->_stmt, $i); - $this->_keys[] = $name; - } - } - - $this->_values = array(); - if ($this->_keys) { - $this->_values = array_fill(0, count($this->_keys), null); - } - - return $retval; - } - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Db2_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if (!$this->_stmt) { - return false; - } - - if ($style === null) { - $style = $this->_fetchMode; - } - - switch ($style) { - case Zend_Db::FETCH_NUM : - $row = db2_fetch_array($this->_stmt); - break; - case Zend_Db::FETCH_ASSOC : - $row = db2_fetch_assoc($this->_stmt); - break; - case Zend_Db::FETCH_BOTH : - $row = db2_fetch_both($this->_stmt); - break; - case Zend_Db::FETCH_OBJ : - $row = db2_fetch_object($this->_stmt); - break; - case Zend_Db::FETCH_BOUND: - $row = db2_fetch_both($this->_stmt); - if ($row !== false) { - return $this->_fetchBound($row); - } - break; - default: - /** - * @see Zend_Db_Statement_Db2_Exception - */ - #require_once 'Zend/Db/Statement/Db2/Exception.php'; - throw new Zend_Db_Statement_Db2_Exception("Invalid fetch mode '$style' specified"); - break; - } - - return $row; - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class. - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - $obj = $this->fetch(Zend_Db::FETCH_OBJ); - return $obj; - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Db2_Exception - */ - public function nextRowset() - { - /** - * @see Zend_Db_Statement_Db2_Exception - */ - #require_once 'Zend/Db/Statement/Db2/Exception.php'; - throw new Zend_Db_Statement_Db2_Exception(__FUNCTION__ . '() is not implemented'); - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - */ - public function rowCount() - { - if (!$this->_stmt) { - return false; - } - - $num = @db2_num_rows($this->_stmt); - - if ($num === false) { - return 0; - } - - return $num; - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - * - * Behaves like parent, but if limit() - * is used, the final result removes the extra column - * 'zend_db_rownum' - */ - public function fetchAll($style = null, $col = null) - { - $data = parent::fetchAll($style, $col); - $results = array(); - $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM'); - - foreach ($data as $row) { - if (is_array($row) && array_key_exists($remove, $row)) { - unset($row[$remove]); - } - $results[] = $row; - } - return $results; - } -} diff --git a/lib/Zend/Db/Statement/Db2/Exception.php b/lib/Zend/Db/Statement/Db2/Exception.php deleted file mode 100644 index 6f3b4509c76..00000000000 --- a/lib/Zend/Db/Statement/Db2/Exception.php +++ /dev/null @@ -1,58 +0,0 @@ -message = $msg; - $this->code = $state; - } - -} - diff --git a/lib/Zend/Db/Statement/Exception.php b/lib/Zend/Db/Statement/Exception.php deleted file mode 100644 index 08e5f149a1e..00000000000 --- a/lib/Zend/Db/Statement/Exception.php +++ /dev/null @@ -1,56 +0,0 @@ -getPrevious() !== null); - } - - /** - * @return Exception|null - */ - public function getChainedException() - { - return $this->getPrevious(); - } -} diff --git a/lib/Zend/Db/Statement/Interface.php b/lib/Zend/Db/Statement/Interface.php deleted file mode 100644 index 7154d9141f5..00000000000 --- a/lib/Zend/Db/Statement/Interface.php +++ /dev/null @@ -1,203 +0,0 @@ -_adapter->getConnection(); - - $this->_stmt = $mysqli->prepare($sql); - - if ($this->_stmt === false || $mysqli->errno) { - /** - * @see Zend_Db_Statement_Mysqli_Exception - */ - #require_once 'Zend/Db/Statement/Mysqli/Exception.php'; - throw new Zend_Db_Statement_Mysqli_Exception("Mysqli prepare error: " . $mysqli->error, $mysqli->errno); - } - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Mysqli_Exception - */ - protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - return true; - } - - /** - * Closes the cursor and the statement. - * - * @return bool - */ - public function close() - { - if ($this->_stmt) { - $r = $this->_stmt->close(); - $this->_stmt = null; - return $r; - } - return false; - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - */ - public function closeCursor() - { - if ($stmt = $this->_stmt) { - $mysqli = $this->_adapter->getConnection(); - while ($mysqli->more_results()) { - $mysqli->next_result(); - } - $this->_stmt->free_result(); - return $this->_stmt->reset(); - } - return false; - } - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - */ - public function columnCount() - { - if (isset($this->_meta) && $this->_meta) { - return $this->_meta->field_count; - } - return 0; - } - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - */ - public function errorCode() - { - if (!$this->_stmt) { - return false; - } - return substr($this->_stmt->sqlstate, 0, 5); - } - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - */ - public function errorInfo() - { - if (!$this->_stmt) { - return false; - } - return array( - substr($this->_stmt->sqlstate, 0, 5), - $this->_stmt->errno, - $this->_stmt->error, - ); - } - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Mysqli_Exception - */ - public function _execute(array $params = null) - { - if (!$this->_stmt) { - return false; - } - - // if no params were given as an argument to execute(), - // then default to the _bindParam array - if ($params === null) { - $params = $this->_bindParam; - } - // send $params as input parameters to the statement - if ($params) { - array_unshift($params, str_repeat('s', count($params))); - $stmtParams = array(); - foreach ($params as $k => &$value) { - $stmtParams[$k] = &$value; - } - call_user_func_array( - array($this->_stmt, 'bind_param'), - $stmtParams - ); - } - - // execute the statement - $retval = $this->_stmt->execute(); - if ($retval === false) { - /** - * @see Zend_Db_Statement_Mysqli_Exception - */ - #require_once 'Zend/Db/Statement/Mysqli/Exception.php'; - throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement execute error : " . $this->_stmt->error, $this->_stmt->errno); - } - - - // retain metadata - if ($this->_meta === null) { - $this->_meta = $this->_stmt->result_metadata(); - if ($this->_stmt->errno) { - /** - * @see Zend_Db_Statement_Mysqli_Exception - */ - #require_once 'Zend/Db/Statement/Mysqli/Exception.php'; - throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement metadata error: " . $this->_stmt->error, $this->_stmt->errno); - } - } - - // statements that have no result set do not return metadata - if ($this->_meta !== false) { - - // get the column names that will result - $this->_keys = array(); - foreach ($this->_meta->fetch_fields() as $col) { - $this->_keys[] = $this->_adapter->foldCase($col->name); - } - - // set up a binding space for result variables - $this->_values = array_fill(0, count($this->_keys), null); - - // set up references to the result binding space. - // just passing $this->_values in the call_user_func_array() - // below won't work, you need references. - $refs = array(); - foreach ($this->_values as $i => &$f) { - $refs[$i] = &$f; - } - - $this->_stmt->store_result(); - // bind to the result variables - call_user_func_array( - array($this->_stmt, 'bind_result'), - $this->_values - ); - } - return $retval; - } - - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Mysqli_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if (!$this->_stmt) { - return false; - } - // fetch the next result - $retval = $this->_stmt->fetch(); - switch ($retval) { - case null: // end of data - case false: // error occurred - $this->_stmt->reset(); - return false; - default: - // fallthrough - } - - // make sure we have a fetch mode - if ($style === null) { - $style = $this->_fetchMode; - } - - // dereference the result values, otherwise things like fetchAll() - // return the same values for every entry (because of the reference). - $values = array(); - foreach ($this->_values as $key => $val) { - $values[] = $val; - } - - $row = false; - switch ($style) { - case Zend_Db::FETCH_NUM: - $row = $values; - break; - case Zend_Db::FETCH_ASSOC: - $row = array_combine($this->_keys, $values); - break; - case Zend_Db::FETCH_BOTH: - $assoc = array_combine($this->_keys, $values); - $row = array_merge($values, $assoc); - break; - case Zend_Db::FETCH_OBJ: - $row = (object) array_combine($this->_keys, $values); - break; - case Zend_Db::FETCH_BOUND: - $assoc = array_combine($this->_keys, $values); - $row = array_merge($values, $assoc); - return $this->_fetchBound($row); - break; - default: - /** - * @see Zend_Db_Statement_Mysqli_Exception - */ - #require_once 'Zend/Db/Statement/Mysqli/Exception.php'; - throw new Zend_Db_Statement_Mysqli_Exception("Invalid fetch mode '$style' specified"); - break; - } - return $row; - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Mysqli_Exception - */ - public function nextRowset() - { - /** - * @see Zend_Db_Statement_Mysqli_Exception - */ - #require_once 'Zend/Db/Statement/Mysqli/Exception.php'; - throw new Zend_Db_Statement_Mysqli_Exception(__FUNCTION__.'() is not implemented'); - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - */ - public function rowCount() - { - if (!$this->_adapter) { - return false; - } - $mysqli = $this->_adapter->getConnection(); - return $mysqli->affected_rows; - } - -} diff --git a/lib/Zend/Db/Statement/Mysqli/Exception.php b/lib/Zend/Db/Statement/Mysqli/Exception.php deleted file mode 100644 index 9bcffbbe4f3..00000000000 --- a/lib/Zend/Db/Statement/Mysqli/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_lobAsString = (bool) $lob_as_string; - return $this; - } - - /** - * Return whether or not LOB are returned as string - * - * @return boolean - */ - public function getLobAsString() - { - return $this->_lobAsString; - } - - /** - * Prepares statement handle - * - * @param string $sql - * @return void - * @throws Zend_Db_Statement_Oracle_Exception - */ - protected function _prepare($sql) - { - $connection = $this->_adapter->getConnection(); - $this->_stmt = @oci_parse($connection, $sql); - if (!$this->_stmt) { - /** - * @see Zend_Db_Statement_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($connection)); - } - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - // default value - if ($type === NULL) { - $type = SQLT_CHR; - } - - // default value - if ($length === NULL) { - $length = -1; - } - - $retval = @oci_bind_by_name($this->_stmt, $parameter, $variable, $length, $type); - if ($retval === false) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt)); - } - - return true; - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - */ - public function closeCursor() - { - if (!$this->_stmt) { - return false; - } - - oci_free_statement($this->_stmt); - $this->_stmt = false; - return true; - } - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - */ - public function columnCount() - { - if (!$this->_stmt) { - return false; - } - - return oci_num_fields($this->_stmt); - } - - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - */ - public function errorCode() - { - if (!$this->_stmt) { - return false; - } - - $error = oci_error($this->_stmt); - - if (!$error) { - return false; - } - - return $error['code']; - } - - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - */ - public function errorInfo() - { - if (!$this->_stmt) { - return false; - } - - $error = oci_error($this->_stmt); - if (!$error) { - return false; - } - - if (isset($error['sqltext'])) { - return array( - $error['code'], - $error['message'], - $error['offset'], - $error['sqltext'], - ); - } else { - return array( - $error['code'], - $error['message'], - ); - } - } - - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function _execute(array $params = null) - { - $connection = $this->_adapter->getConnection(); - - if (!$this->_stmt) { - return false; - } - - if ($params !== null) { - if (!is_array($params)) { - $params = array($params); - } - $error = false; - foreach (array_keys($params) as $name) { - if (!$this->bindParam($name, $params[$name], null, -1)) { - $error = true; - break; - } - } - if ($error) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt)); - } - } - - $retval = @oci_execute($this->_stmt, $this->_adapter->_getExecuteMode()); - if ($retval === false) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt)); - } - - $this->_keys = Array(); - if ($field_num = oci_num_fields($this->_stmt)) { - for ($i = 1; $i <= $field_num; $i++) { - $name = oci_field_name($this->_stmt, $i); - $this->_keys[] = $name; - } - } - - $this->_values = Array(); - if ($this->_keys) { - $this->_values = array_fill(0, count($this->_keys), null); - } - - return $retval; - } - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if (!$this->_stmt) { - return false; - } - - if ($style === null) { - $style = $this->_fetchMode; - } - - $lob_as_string = $this->getLobAsString() ? OCI_RETURN_LOBS : 0; - - switch ($style) { - case Zend_Db::FETCH_NUM: - $row = oci_fetch_array($this->_stmt, OCI_NUM | OCI_RETURN_NULLS | $lob_as_string); - break; - case Zend_Db::FETCH_ASSOC: - $row = oci_fetch_array($this->_stmt, OCI_ASSOC | OCI_RETURN_NULLS | $lob_as_string); - break; - case Zend_Db::FETCH_BOTH: - $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string); - break; - case Zend_Db::FETCH_OBJ: - $row = oci_fetch_object($this->_stmt); - break; - case Zend_Db::FETCH_BOUND: - $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string); - if ($row !== false) { - return $this->_fetchBound($row); - } - break; - default: - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception( - array( - 'code' => 'HYC00', - 'message' => "Invalid fetch mode '$style' specified" - ) - ); - break; - } - - if (! $row && $error = oci_error($this->_stmt)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception($error); - } - - if (is_array($row) && array_key_exists('zend_db_rownum', $row)) { - unset($row['zend_db_rownum']); - } - - return $row; - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetchAll($style = null, $col = 0) - { - if (!$this->_stmt) { - return false; - } - - // make sure we have a fetch mode - if ($style === null) { - $style = $this->_fetchMode; - } - - $flags = OCI_FETCHSTATEMENT_BY_ROW; - - switch ($style) { - case Zend_Db::FETCH_BOTH: - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception( - array( - 'code' => 'HYC00', - 'message' => "OCI8 driver does not support fetchAll(FETCH_BOTH), use fetch() in a loop instead" - ) - ); - // notreached - $flags |= OCI_NUM; - $flags |= OCI_ASSOC; - break; - case Zend_Db::FETCH_NUM: - $flags |= OCI_NUM; - break; - case Zend_Db::FETCH_ASSOC: - $flags |= OCI_ASSOC; - break; - case Zend_Db::FETCH_OBJ: - break; - case Zend_Db::FETCH_COLUMN: - $flags = $flags &~ OCI_FETCHSTATEMENT_BY_ROW; - $flags |= OCI_FETCHSTATEMENT_BY_COLUMN; - $flags |= OCI_NUM; - break; - default: - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception( - array( - 'code' => 'HYC00', - 'message' => "Invalid fetch mode '$style' specified" - ) - ); - break; - } - - $result = Array(); - if ($flags != OCI_FETCHSTATEMENT_BY_ROW) { /* not Zend_Db::FETCH_OBJ */ - if (! ($rows = oci_fetch_all($this->_stmt, $result, 0, -1, $flags) )) { - if ($error = oci_error($this->_stmt)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception($error); - } - if (!$rows) { - return array(); - } - } - if ($style == Zend_Db::FETCH_COLUMN) { - $result = $result[$col]; - } - foreach ($result as &$row) { - if (is_array($row) && array_key_exists('zend_db_rownum', $row)) { - unset($row['zend_db_rownum']); - } - } - } else { - while (($row = oci_fetch_object($this->_stmt)) !== false) { - $result [] = $row; - } - if ($error = oci_error($this->_stmt)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception($error); - } - } - - return $result; - } - - - /** - * Returns a single column from the next row of a result set. - * - * @param int $col OPTIONAL Position of the column to fetch. - * @return string - * @throws Zend_Db_Statement_Exception - */ - public function fetchColumn($col = 0) - { - if (!$this->_stmt) { - return false; - } - - if (!oci_fetch($this->_stmt)) { - // if no error, there is simply no record - if (!$error = oci_error($this->_stmt)) { - return false; - } - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception($error); - } - - $data = oci_result($this->_stmt, $col+1); //1-based - if ($data === false) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt)); - } - - if ($this->getLobAsString()) { - // instanceof doesn't allow '-', we must use a temporary string - $type = 'OCI-Lob'; - if ($data instanceof $type) { - $data = $data->read($data->size()); - } - } - - return $data; - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class. - * @throws Zend_Db_Statement_Exception - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - if (!$this->_stmt) { - return false; - } - - $obj = oci_fetch_object($this->_stmt); - - if ($error = oci_error($this->_stmt)) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception($error); - } - - /* @todo XXX handle parameters */ - - return $obj; - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function nextRowset() - { - /** - * @see Zend_Db_Statement_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception( - array( - 'code' => 'HYC00', - 'message' => 'Optional feature not implemented' - ) - ); - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - * @throws Zend_Db_Statement_Exception - */ - public function rowCount() - { - if (!$this->_stmt) { - return false; - } - - $num_rows = oci_num_rows($this->_stmt); - - if ($num_rows === false) { - /** - * @see Zend_Db_Adapter_Oracle_Exception - */ - #require_once 'Zend/Db/Statement/Oracle/Exception.php'; - throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt)); - } - - return $num_rows; - } - -} diff --git a/lib/Zend/Db/Statement/Oracle/Exception.php b/lib/Zend/Db/Statement/Oracle/Exception.php deleted file mode 100644 index 0f8d9a22a2b..00000000000 --- a/lib/Zend/Db/Statement/Oracle/Exception.php +++ /dev/null @@ -1,59 +0,0 @@ -message = $error['code']." ".$error['message']; - } else { - $this->message = $error['code']." ".$error['message']." "; - $this->message .= substr($error['sqltext'], 0, $error['offset']); - $this->message .= "*"; - $this->message .= substr($error['sqltext'], $error['offset']); - } - $this->code = $error['code']; - } - if (!$this->code && $code) { - $this->code = $code; - } - } -} - diff --git a/lib/Zend/Db/Statement/Pdo.php b/lib/Zend/Db/Statement/Pdo.php deleted file mode 100644 index 00cf2108069..00000000000 --- a/lib/Zend/Db/Statement/Pdo.php +++ /dev/null @@ -1,440 +0,0 @@ -_stmt = $this->_adapter->getConnection()->prepare($sql); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Bind a column of the statement result set to a PHP variable. - * - * @param string $column Name the column in the result set, either by - * position or by name. - * @param mixed $param Reference to the PHP variable containing the value. - * @param mixed $type OPTIONAL - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function bindColumn($column, &$param, $type = null) - { - try { - if ($type === null) { - return $this->_stmt->bindColumn($column, $param); - } else { - return $this->_stmt->bindColumn($column, $param, $type); - } - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - try { - if ($type === null) { - if (is_bool($variable)) { - $type = PDO::PARAM_BOOL; - } elseif ($variable === null) { - $type = PDO::PARAM_NULL; - } elseif (is_integer($variable)) { - $type = PDO::PARAM_INT; - } else { - $type = PDO::PARAM_STR; - } - } - return $this->_stmt->bindParam($parameter, $variable, $type, $length, $options); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Binds a value to a parameter. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $value Scalar value to bind to the parameter. - * @param mixed $type OPTIONAL Datatype of the parameter. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function bindValue($parameter, $value, $type = null) - { - if (is_string($parameter) && $parameter[0] != ':') { - $parameter = ":$parameter"; - } - - $this->_bindParam[$parameter] = $value; - - try { - if ($type === null) { - return $this->_stmt->bindValue($parameter, $value); - } else { - return $this->_stmt->bindValue($parameter, $value, $type); - } - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function closeCursor() - { - try { - return $this->_stmt->closeCursor(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - * @throws Zend_Db_Statement_Exception - */ - public function columnCount() - { - try { - return $this->_stmt->columnCount(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - * @throws Zend_Db_Statement_Exception - */ - public function errorCode() - { - try { - return $this->_stmt->errorCode(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - * @throws Zend_Db_Statement_Exception - */ - public function errorInfo() - { - try { - return $this->_stmt->errorInfo(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function _execute(array $params = null) - { - try { - if ($params !== null) { - return $this->_stmt->execute($params); - } else { - return $this->_stmt->execute(); - } - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - $message = sprintf('%s, query was: %s', $e->getMessage(), $this->_stmt->queryString); - throw new Zend_Db_Statement_Exception($message, (int) $e->getCode(), $e); - } - } - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if ($style === null) { - $style = $this->_fetchMode; - } - try { - return $this->_stmt->fetch($style, $cursor, $offset); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Required by IteratorAggregate interface - * - * @return IteratorIterator - */ - public function getIterator() - { - return new IteratorIterator($this->_stmt); - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetchAll($style = null, $col = null) - { - if ($style === null) { - $style = $this->_fetchMode; - } - try { - if ($style == PDO::FETCH_COLUMN) { - if ($col === null) { - $col = 0; - } - return $this->_stmt->fetchAll($style, $col); - } else { - return $this->_stmt->fetchAll($style); - } - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Returns a single column from the next row of a result set. - * - * @param int $col OPTIONAL Position of the column to fetch. - * @return string - * @throws Zend_Db_Statement_Exception - */ - public function fetchColumn($col = 0) - { - try { - return $this->_stmt->fetchColumn($col); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class. - * @throws Zend_Db_Statement_Exception - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - try { - return $this->_stmt->fetchObject($class, $config); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Retrieve a statement attribute. - * - * @param integer $key Attribute name. - * @return mixed Attribute value. - * @throws Zend_Db_Statement_Exception - */ - public function getAttribute($key) - { - try { - return $this->_stmt->getAttribute($key); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Returns metadata for a column in a result set. - * - * @param int $column - * @return mixed - * @throws Zend_Db_Statement_Exception - */ - public function getColumnMeta($column) - { - try { - return $this->_stmt->getColumnMeta($column); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function nextRowset() - { - try { - return $this->_stmt->nextRowset(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - * @throws Zend_Db_Statement_Exception - */ - public function rowCount() - { - try { - return $this->_stmt->rowCount(); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Set a statement attribute. - * - * @param string $key Attribute name. - * @param mixed $val Attribute value. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function setAttribute($key, $val) - { - try { - return $this->_stmt->setAttribute($key, $val); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Set the default fetch mode for this statement. - * - * @param int $mode The fetch mode. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function setFetchMode($mode) - { - $this->_fetchMode = $mode; - try { - return $this->_stmt->setFetchMode($mode); - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - -} diff --git a/lib/Zend/Db/Statement/Pdo/Ibm.php b/lib/Zend/Db/Statement/Pdo/Ibm.php deleted file mode 100644 index 8f52769fc8f..00000000000 --- a/lib/Zend/Db/Statement/Pdo/Ibm.php +++ /dev/null @@ -1,94 +0,0 @@ -_adapter->foldCase('ZEND_DB_ROWNUM'); - - foreach ($data as $row) { - if (is_array($row) && array_key_exists($remove, $row)) { - unset($row[$remove]); - } - $results[] = $row; - } - return $results; - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - try { - if (($type === null) && ($length === null) && ($options === null)) { - return $this->_stmt->bindParam($parameter, $variable); - } else { - return $this->_stmt->bindParam($parameter, $variable, $type, $length, $options); - } - } catch (PDOException $e) { - #require_once 'Zend/Db/Statement/Exception.php'; - throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); - } - } - -} diff --git a/lib/Zend/Db/Statement/Pdo/Oci.php b/lib/Zend/Db/Statement/Pdo/Oci.php deleted file mode 100644 index ad8955e559e..00000000000 --- a/lib/Zend/Db/Statement/Pdo/Oci.php +++ /dev/null @@ -1,91 +0,0 @@ -_adapter->foldCase('zend_db_rownum'); - - foreach ($data as $row) { - if (is_array($row) && array_key_exists($remove, $row)) { - unset($row[$remove]); - } - $results[] = $row; - } - return $results; - } - - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - $row = parent::fetch($style, $cursor, $offset); - - $remove = $this->_adapter->foldCase('zend_db_rownum'); - if (is_array($row) && array_key_exists($remove, $row)) { - unset($row[$remove]); - } - - return $row; - } -} diff --git a/lib/Zend/Db/Statement/Sqlsrv.php b/lib/Zend/Db/Statement/Sqlsrv.php deleted file mode 100644 index c2464165d0a..00000000000 --- a/lib/Zend/Db/Statement/Sqlsrv.php +++ /dev/null @@ -1,440 +0,0 @@ -_adapter->getConnection(); - - $this->_stmt = sqlsrv_prepare($connection, $sql); - - if (!$this->_stmt) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors()); - } - - $this->_originalSQL = $sql; - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - //Sql server doesn't support bind by name - return true; - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - */ - public function closeCursor() - { - if (!$this->_stmt) { - return false; - } - - sqlsrv_free_stmt($this->_stmt); - $this->_stmt = false; - return true; - } - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - */ - public function columnCount() - { - if ($this->_stmt && $this->_executed) { - return sqlsrv_num_fields($this->_stmt); - } - - return 0; - } - - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - */ - public function errorCode() - { - if (!$this->_stmt) { - return false; - } - - $error = sqlsrv_errors(); - if (!$error) { - return false; - } - - return $error[0]['code']; - } - - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - */ - public function errorInfo() - { - if (!$this->_stmt) { - return false; - } - - $error = sqlsrv_errors(); - if (!$error) { - return false; - } - - return array( - $error[0]['code'], - $error[0]['message'], - ); - } - - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function _execute(array $params = null) - { - $connection = $this->_adapter->getConnection(); - if (!$this->_stmt) { - return false; - } - - if ($params !== null) { - if (!is_array($params)) { - $params = array($params); - } - $error = false; - - // make all params passed by reference - $params_ = array(); - $temp = array(); - $i = 1; - foreach ($params as $param) { - $temp[$i] = $param; - $params_[] = &$temp[$i]; - $i++; - } - $params = $params_; - } - - $this->_stmt = sqlsrv_query($connection, $this->_originalSQL, $params); - - if (!$this->_stmt) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors()); - } - - $this->_executed = true; - - return (!$this->_stmt); - } - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if (!$this->_stmt) { - return false; - } - - if (null === $style) { - $style = $this->_fetchMode; - } - - $values = sqlsrv_fetch_array($this->_stmt, SQLSRV_FETCH_ASSOC); - - if (!$values && (null !== $error = sqlsrv_errors())) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception($error); - } - - if (null === $values) { - return null; - } - - if (!$this->_keys) { - foreach ($values as $key => $value) { - $this->_keys[] = $this->_adapter->foldCase($key); - } - } - - $values = array_values($values); - - $row = false; - switch ($style) { - case Zend_Db::FETCH_NUM: - $row = $values; - break; - case Zend_Db::FETCH_ASSOC: - $row = array_combine($this->_keys, $values); - break; - case Zend_Db::FETCH_BOTH: - $assoc = array_combine($this->_keys, $values); - $row = array_merge($values, $assoc); - break; - case Zend_Db::FETCH_OBJ: - $row = (object) array_combine($this->_keys, $values); - break; - case Zend_Db::FETCH_BOUND: - $assoc = array_combine($this->_keys, $values); - $row = array_merge($values, $assoc); - $row = $this->_fetchBound($row); - break; - default: - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception("Invalid fetch mode '$style' specified"); - break; - } - - return $row; - } - - /** - * Returns a single column from the next row of a result set. - * - * @param int $col OPTIONAL Position of the column to fetch. - * @return string - * @throws Zend_Db_Statement_Exception - */ - public function fetchColumn($col = 0) - { - if (!$this->_stmt) { - return false; - } - - if (!sqlsrv_fetch($this->_stmt)) { - if (null !== $error = sqlsrv_errors()) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception($error); - } - - // If no error, there is simply no record - return false; - } - - $data = sqlsrv_get_field($this->_stmt, $col); //0-based - if ($data === false) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors()); - } - - return $data; - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class. - * @throws Zend_Db_Statement_Exception - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - if (!$this->_stmt) { - return false; - } - - $obj = sqlsrv_fetch_object($this->_stmt); - - if ($error = sqlsrv_errors()) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception($error); - } - - /* @todo XXX handle parameters */ - - if (null === $obj) { - return false; - } - - return $obj; - } - - /** - * Returns metadata for a column in a result set. - * - * @param int $column - * @return mixed - * @throws Zend_Db_Statement_Sqlsrv_Exception - */ - public function getColumnMeta($column) - { - $fields = sqlsrv_field_metadata($this->_stmt); - - if (!$fields) { - throw new Zend_Db_Statement_Sqlsrv_Exception('Column metadata can not be fetched'); - } - - if (!isset($fields[$column])) { - throw new Zend_Db_Statement_Sqlsrv_Exception('Column index does not exist in statement'); - } - - return $fields[$column]; - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function nextRowset() - { - if (sqlsrv_next_result($this->_stmt) === false) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors()); - } - - // reset column keys - $this->_keys = null; - - return true; - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - * @throws Zend_Db_Statement_Exception - */ - public function rowCount() - { - if (!$this->_stmt) { - return false; - } - - if (!$this->_executed) { - return 0; - } - - $num_rows = sqlsrv_rows_affected($this->_stmt); - - // Strict check is necessary; 0 is a valid return value - if ($num_rows === false) { - #require_once 'Zend/Db/Statement/Sqlsrv/Exception.php'; - throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors()); - } - - return $num_rows; - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - * - * Behaves like parent, but if limit() - * is used, the final result removes the extra column - * 'zend_db_rownum' - */ - public function fetchAll($style = null, $col = null) - { - $data = parent::fetchAll($style, $col); - $results = array(); - $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM'); - - foreach ($data as $row) { - if (is_array($row) && array_key_exists($remove, $row)) { - unset($row[$remove]); - } - $results[] = $row; - } - return $results; - } -} diff --git a/lib/Zend/Db/Statement/Sqlsrv/Exception.php b/lib/Zend/Db/Statement/Sqlsrv/Exception.php deleted file mode 100644 index 975e7a25e22..00000000000 --- a/lib/Zend/Db/Statement/Sqlsrv/Exception.php +++ /dev/null @@ -1,61 +0,0 @@ - $config); - } else { - // process this as table with or without a definition - if ($definition instanceof Zend_Db_Table_Definition - && $definition->hasTableConfig($config)) { - // this will have DEFINITION_CONFIG_NAME & DEFINITION - $config = $definition->getTableConfig($config); - } else { - $config = array(self::NAME => $config); - } - } - } - - parent::__construct($config); - } -} diff --git a/lib/Zend/Db/Table/Abstract.php b/lib/Zend/Db/Table/Abstract.php deleted file mode 100644 index 07349e24146..00000000000 --- a/lib/Zend/Db/Table/Abstract.php +++ /dev/null @@ -1,1624 +0,0 @@ - $config); - } - - if ($config) { - $this->setOptions($config); - } - - $this->_setup(); - $this->init(); - } - - /** - * setOptions() - * - * @param array $options - * @return Zend_Db_Table_Abstract - */ - public function setOptions(Array $options) - { - foreach ($options as $key => $value) { - switch ($key) { - case self::ADAPTER: - $this->_setAdapter($value); - break; - case self::DEFINITION: - $this->setDefinition($value); - break; - case self::DEFINITION_CONFIG_NAME: - $this->setDefinitionConfigName($value); - break; - case self::SCHEMA: - $this->_schema = (string) $value; - break; - case self::NAME: - $this->_name = (string) $value; - break; - case self::PRIMARY: - $this->_primary = (array) $value; - break; - case self::ROW_CLASS: - $this->setRowClass($value); - break; - case self::ROWSET_CLASS: - $this->setRowsetClass($value); - break; - case self::REFERENCE_MAP: - $this->setReferences($value); - break; - case self::DEPENDENT_TABLES: - $this->setDependentTables($value); - break; - case self::METADATA_CACHE: - $this->_setMetadataCache($value); - break; - case self::METADATA_CACHE_IN_CLASS: - $this->setMetadataCacheInClass($value); - break; - case self::SEQUENCE: - $this->_setSequence($value); - break; - default: - // ignore unrecognized configuration directive - break; - } - } - - return $this; - } - - /** - * setDefinition() - * - * @param Zend_Db_Table_Definition $definition - * @return Zend_Db_Table_Abstract - */ - public function setDefinition(Zend_Db_Table_Definition $definition) - { - $this->_definition = $definition; - return $this; - } - - /** - * getDefinition() - * - * @return Zend_Db_Table_Definition|null - */ - public function getDefinition() - { - return $this->_definition; - } - - /** - * setDefinitionConfigName() - * - * @param string $definition - * @return Zend_Db_Table_Abstract - */ - public function setDefinitionConfigName($definitionConfigName) - { - $this->_definitionConfigName = $definitionConfigName; - return $this; - } - - /** - * getDefinitionConfigName() - * - * @return string - */ - public function getDefinitionConfigName() - { - return $this->_definitionConfigName; - } - - /** - * @param string $classname - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - public function setRowClass($classname) - { - $this->_rowClass = (string) $classname; - - return $this; - } - - /** - * @return string - */ - public function getRowClass() - { - return $this->_rowClass; - } - - /** - * @param string $classname - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - public function setRowsetClass($classname) - { - $this->_rowsetClass = (string) $classname; - - return $this; - } - - /** - * @return string - */ - public function getRowsetClass() - { - return $this->_rowsetClass; - } - - /** - * Add a reference to the reference map - * - * @param string $ruleKey - * @param string|array $columns - * @param string $refTableClass - * @param string|array $refColumns - * @param string $onDelete - * @param string $onUpdate - * @return Zend_Db_Table_Abstract - */ - public function addReference($ruleKey, $columns, $refTableClass, $refColumns, - $onDelete = null, $onUpdate = null) - { - $reference = array(self::COLUMNS => (array) $columns, - self::REF_TABLE_CLASS => $refTableClass, - self::REF_COLUMNS => (array) $refColumns); - - if (!empty($onDelete)) { - $reference[self::ON_DELETE] = $onDelete; - } - - if (!empty($onUpdate)) { - $reference[self::ON_UPDATE] = $onUpdate; - } - - $this->_referenceMap[$ruleKey] = $reference; - - return $this; - } - - /** - * @param array $referenceMap - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - public function setReferences(array $referenceMap) - { - $this->_referenceMap = $referenceMap; - - return $this; - } - - /** - * @param string $tableClassname - * @param string $ruleKey OPTIONAL - * @return array - * @throws Zend_Db_Table_Exception - */ - public function getReference($tableClassname, $ruleKey = null) - { - $thisClass = get_class($this); - if ($thisClass === 'Zend_Db_Table') { - $thisClass = $this->_definitionConfigName; - } - $refMap = $this->_getReferenceMapNormalized(); - if ($ruleKey !== null) { - if (!isset($refMap[$ruleKey])) { - #require_once "Zend/Db/Table/Exception.php"; - throw new Zend_Db_Table_Exception("No reference rule \"$ruleKey\" from table $thisClass to table $tableClassname"); - } - if ($refMap[$ruleKey][self::REF_TABLE_CLASS] != $tableClassname) { - #require_once "Zend/Db/Table/Exception.php"; - throw new Zend_Db_Table_Exception("Reference rule \"$ruleKey\" does not reference table $tableClassname"); - } - return $refMap[$ruleKey]; - } - foreach ($refMap as $reference) { - if ($reference[self::REF_TABLE_CLASS] == $tableClassname) { - return $reference; - } - } - #require_once "Zend/Db/Table/Exception.php"; - throw new Zend_Db_Table_Exception("No reference from table $thisClass to table $tableClassname"); - } - - /** - * @param array $dependentTables - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - public function setDependentTables(array $dependentTables) - { - $this->_dependentTables = $dependentTables; - - return $this; - } - - /** - * @return array - */ - public function getDependentTables() - { - return $this->_dependentTables; - } - - /** - * set the defaultSource property - this tells the table class where to find default values - * - * @param string $defaultSource - * @return Zend_Db_Table_Abstract - */ - public function setDefaultSource($defaultSource = self::DEFAULT_NONE) - { - if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) { - $defaultSource = self::DEFAULT_NONE; - } - - $this->_defaultSource = $defaultSource; - return $this; - } - - /** - * returns the default source flag that determines where defaultSources come from - * - * @return unknown - */ - public function getDefaultSource() - { - return $this->_defaultSource; - } - - /** - * set the default values for the table class - * - * @param array $defaultValues - * @return Zend_Db_Table_Abstract - */ - public function setDefaultValues(Array $defaultValues) - { - foreach ($defaultValues as $defaultName => $defaultValue) { - if (array_key_exists($defaultName, $this->_metadata)) { - $this->_defaultValues[$defaultName] = $defaultValue; - } - } - return $this; - } - - public function getDefaultValues() - { - return $this->_defaultValues; - } - - - /** - * Sets the default Zend_Db_Adapter_Abstract for all Zend_Db_Table objects. - * - * @param mixed $db Either an Adapter object, or a string naming a Registry key - * @return void - */ - public static function setDefaultAdapter($db = null) - { - self::$_defaultDb = self::_setupAdapter($db); - } - - /** - * Gets the default Zend_Db_Adapter_Abstract for all Zend_Db_Table objects. - * - * @return Zend_Db_Adapter_Abstract or null - */ - public static function getDefaultAdapter() - { - return self::$_defaultDb; - } - - /** - * @param mixed $db Either an Adapter object, or a string naming a Registry key - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - protected function _setAdapter($db) - { - $this->_db = self::_setupAdapter($db); - return $this; - } - - /** - * Gets the Zend_Db_Adapter_Abstract for this particular Zend_Db_Table object. - * - * @return Zend_Db_Adapter_Abstract - */ - public function getAdapter() - { - return $this->_db; - } - - /** - * @param mixed $db Either an Adapter object, or a string naming a Registry key - * @return Zend_Db_Adapter_Abstract - * @throws Zend_Db_Table_Exception - */ - protected static function _setupAdapter($db) - { - if ($db === null) { - return null; - } - if (is_string($db)) { - #require_once 'Zend/Registry.php'; - $db = Zend_Registry::get($db); - } - if (!$db instanceof Zend_Db_Adapter_Abstract) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception('Argument must be of type Zend_Db_Adapter_Abstract, or a Registry key where a Zend_Db_Adapter_Abstract object is stored'); - } - return $db; - } - - /** - * Sets the default metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable(). - * - * If $defaultMetadataCache is null, then no metadata cache is used by default. - * - * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key - * @return void - */ - public static function setDefaultMetadataCache($metadataCache = null) - { - self::$_defaultMetadataCache = self::_setupMetadataCache($metadataCache); - } - - /** - * Gets the default metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable(). - * - * @return Zend_Cache_Core or null - */ - public static function getDefaultMetadataCache() - { - return self::$_defaultMetadataCache; - } - - /** - * Sets the metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable(). - * - * If $metadataCache is null, then no metadata cache is used. Since there is no opportunity to reload metadata - * after instantiation, this method need not be public, particularly because that it would have no effect - * results in unnecessary API complexity. To configure the metadata cache, use the metadataCache configuration - * option for the class constructor upon instantiation. - * - * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key - * @return Zend_Db_Table_Abstract Provides a fluent interface - */ - protected function _setMetadataCache($metadataCache) - { - $this->_metadataCache = self::_setupMetadataCache($metadataCache); - return $this; - } - - /** - * Gets the metadata cache for information returned by Zend_Db_Adapter_Abstract::describeTable(). - * - * @return Zend_Cache_Core or null - */ - public function getMetadataCache() - { - return $this->_metadataCache; - } - - /** - * Indicate whether metadata should be cached in the class for the duration - * of the instance - * - * @param bool $flag - * @return Zend_Db_Table_Abstract - */ - public function setMetadataCacheInClass($flag) - { - $this->_metadataCacheInClass = (bool) $flag; - return $this; - } - - /** - * Retrieve flag indicating if metadata should be cached for duration of - * instance - * - * @return bool - */ - public function metadataCacheInClass() - { - return $this->_metadataCacheInClass; - } - - /** - * @param mixed $metadataCache Either a Cache object, or a string naming a Registry key - * @return Zend_Cache_Core - * @throws Zend_Db_Table_Exception - */ - protected static function _setupMetadataCache($metadataCache) - { - if ($metadataCache === null) { - return null; - } - if (is_string($metadataCache)) { - #require_once 'Zend/Registry.php'; - $metadataCache = Zend_Registry::get($metadataCache); - } - if (!$metadataCache instanceof Zend_Cache_Core) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception('Argument must be of type Zend_Cache_Core, or a Registry key where a Zend_Cache_Core object is stored'); - } - return $metadataCache; - } - - /** - * Sets the sequence member, which defines the behavior for generating - * primary key values in new rows. - * - If this is a string, then the string names the sequence object. - * - If this is boolean true, then the key uses an auto-incrementing - * or identity mechanism. - * - If this is boolean false, then the key is user-defined. - * Use this for natural keys, for example. - * - * @param mixed $sequence - * @return Zend_Db_Table_Adapter_Abstract Provides a fluent interface - */ - protected function _setSequence($sequence) - { - $this->_sequence = $sequence; - - return $this; - } - - /** - * Turnkey for initialization of a table object. - * Calls other protected methods for individual tasks, to make it easier - * for a subclass to override part of the setup logic. - * - * @return void - */ - protected function _setup() - { - $this->_setupDatabaseAdapter(); - $this->_setupTableName(); - } - - /** - * Initialize database adapter. - * - * @return void - * @throws Zend_Db_Table_Exception - */ - protected function _setupDatabaseAdapter() - { - if (! $this->_db) { - $this->_db = self::getDefaultAdapter(); - if (!$this->_db instanceof Zend_Db_Adapter_Abstract) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception('No adapter found for ' . get_class($this)); - } - } - } - - /** - * Initialize table and schema names. - * - * If the table name is not set in the class definition, - * use the class name itself as the table name. - * - * A schema name provided with the table name (e.g., "schema.table") overrides - * any existing value for $this->_schema. - * - * @return void - */ - protected function _setupTableName() - { - if (! $this->_name) { - $this->_name = get_class($this); - } else if (strpos($this->_name, '.')) { - list($this->_schema, $this->_name) = explode('.', $this->_name); - } - } - - /** - * Initializes metadata. - * - * If metadata cannot be loaded from cache, adapter's describeTable() method is called to discover metadata - * information. Returns true if and only if the metadata are loaded from cache. - * - * @return boolean - * @throws Zend_Db_Table_Exception - */ - protected function _setupMetadata() - { - if ($this->metadataCacheInClass() && (count($this->_metadata) > 0)) { - return true; - } - - // Assume that metadata will be loaded from cache - $isMetadataFromCache = true; - - // If $this has no metadata cache but the class has a default metadata cache - if (null === $this->_metadataCache && null !== self::$_defaultMetadataCache) { - // Make $this use the default metadata cache of the class - $this->_setMetadataCache(self::$_defaultMetadataCache); - } - - // If $this has a metadata cache - if (null !== $this->_metadataCache) { - // Define the cache identifier where the metadata are saved - - //get db configuration - $dbConfig = $this->_db->getConfig(); - - $port = isset($dbConfig['options']['port']) - ? ':'.$dbConfig['options']['port'] - : (isset($dbConfig['port']) - ? ':'.$dbConfig['port'] - : null); - - $host = isset($dbConfig['options']['host']) - ? ':'.$dbConfig['options']['host'] - : (isset($dbConfig['host']) - ? ':'.$dbConfig['host'] - : null); - - // Define the cache identifier where the metadata are saved - $cacheId = md5( // port:host/dbname:schema.table (based on availabilty) - $port . $host . '/'. $dbConfig['dbname'] . ':' - . $this->_schema. '.' . $this->_name - ); - } - - // If $this has no metadata cache or metadata cache misses - if (null === $this->_metadataCache || !($metadata = $this->_metadataCache->load($cacheId))) { - // Metadata are not loaded from cache - $isMetadataFromCache = false; - // Fetch metadata from the adapter's describeTable() method - $metadata = $this->_db->describeTable($this->_name, $this->_schema); - // If $this has a metadata cache, then cache the metadata - if (null !== $this->_metadataCache && !$this->_metadataCache->save($metadata, $cacheId)) { - trigger_error('Failed saving metadata to metadataCache', E_USER_NOTICE); - } - } - - // Assign the metadata to $this - $this->_metadata = $metadata; - - // Return whether the metadata were loaded from cache - return $isMetadataFromCache; - } - - /** - * Retrieve table columns - * - * @return array - */ - protected function _getCols() - { - if (null === $this->_cols) { - $this->_setupMetadata(); - $this->_cols = array_keys($this->_metadata); - } - return $this->_cols; - } - - /** - * Initialize primary key from metadata. - * If $_primary is not defined, discover primary keys - * from the information returned by describeTable(). - * - * @return void - * @throws Zend_Db_Table_Exception - */ - protected function _setupPrimaryKey() - { - if (!$this->_primary) { - $this->_setupMetadata(); - $this->_primary = array(); - foreach ($this->_metadata as $col) { - if ($col['PRIMARY']) { - $this->_primary[ $col['PRIMARY_POSITION'] ] = $col['COLUMN_NAME']; - if ($col['IDENTITY']) { - $this->_identity = $col['PRIMARY_POSITION']; - } - } - } - // if no primary key was specified and none was found in the metadata - // then throw an exception. - if (empty($this->_primary)) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception("A table must have a primary key, but none was found for table '{$this->_name}'"); - } - } else if (!is_array($this->_primary)) { - $this->_primary = array(1 => $this->_primary); - } else if (isset($this->_primary[0])) { - array_unshift($this->_primary, null); - unset($this->_primary[0]); - } - - $cols = $this->_getCols(); - if (! array_intersect((array) $this->_primary, $cols) == (array) $this->_primary) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception("Primary key column(s) (" - . implode(',', (array) $this->_primary) - . ") are not columns in this table (" - . implode(',', $cols) - . ")"); - } - - $primary = (array) $this->_primary; - $pkIdentity = $primary[(int) $this->_identity]; - - /** - * Special case for PostgreSQL: a SERIAL key implicitly uses a sequence - * object whose name is "__seq". - */ - if ($this->_sequence === true && $this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql) { - $this->_sequence = $this->_db->quoteIdentifier("{$this->_name}_{$pkIdentity}_seq"); - if ($this->_schema) { - $this->_sequence = $this->_db->quoteIdentifier($this->_schema) . '.' . $this->_sequence; - } - } - } - - /** - * Returns a normalized version of the reference map - * - * @return array - */ - protected function _getReferenceMapNormalized() - { - $referenceMapNormalized = array(); - - foreach ($this->_referenceMap as $rule => $map) { - - $referenceMapNormalized[$rule] = array(); - - foreach ($map as $key => $value) { - switch ($key) { - - // normalize COLUMNS and REF_COLUMNS to arrays - case self::COLUMNS: - case self::REF_COLUMNS: - if (!is_array($value)) { - $referenceMapNormalized[$rule][$key] = array($value); - } else { - $referenceMapNormalized[$rule][$key] = $value; - } - break; - - // other values are copied as-is - default: - $referenceMapNormalized[$rule][$key] = $value; - break; - } - } - } - - return $referenceMapNormalized; - } - - /** - * Initialize object - * - * Called from {@link __construct()} as final step of object instantiation. - * - * @return void - */ - public function init() - { - } - - /** - * Returns table information. - * - * You can elect to return only a part of this information by supplying its key name, - * otherwise all information is returned as an array. - * - * @param string $key The specific info part to return OPTIONAL - * @return mixed - * @throws Zend_Db_Table_Exception - */ - public function info($key = null) - { - $this->_setupPrimaryKey(); - - $info = array( - self::SCHEMA => $this->_schema, - self::NAME => $this->_name, - self::COLS => $this->_getCols(), - self::PRIMARY => (array) $this->_primary, - self::METADATA => $this->_metadata, - self::ROW_CLASS => $this->getRowClass(), - self::ROWSET_CLASS => $this->getRowsetClass(), - self::REFERENCE_MAP => $this->_referenceMap, - self::DEPENDENT_TABLES => $this->_dependentTables, - self::SEQUENCE => $this->_sequence - ); - - if ($key === null) { - return $info; - } - - if (!array_key_exists($key, $info)) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception('There is no table information for the key "' . $key . '"'); - } - - return $info[$key]; - } - - /** - * Returns an instance of a Zend_Db_Table_Select object. - * - * @param bool $withFromPart Whether or not to include the from part of the select based on the table - * @return Zend_Db_Table_Select - */ - public function select($withFromPart = self::SELECT_WITHOUT_FROM_PART) - { - #require_once 'Zend/Db/Table/Select.php'; - $select = new Zend_Db_Table_Select($this); - if ($withFromPart == self::SELECT_WITH_FROM_PART) { - $select->from($this->info(self::NAME), Zend_Db_Table_Select::SQL_WILDCARD, $this->info(self::SCHEMA)); - } - return $select; - } - - /** - * Inserts a new row. - * - * @param array $data Column-value pairs. - * @return mixed The primary key of the row inserted. - */ - public function insert(array $data) - { - $this->_setupPrimaryKey(); - - /** - * Zend_Db_Table assumes that if you have a compound primary key - * and one of the columns in the key uses a sequence, - * it's the _first_ column in the compound key. - */ - $primary = (array) $this->_primary; - $pkIdentity = $primary[(int)$this->_identity]; - - - /** - * If the primary key can be generated automatically, and no value was - * specified in the user-supplied data, then omit it from the tuple. - * - * Note: this checks for sensible values in the supplied primary key - * position of the data. The following values are considered empty: - * null, false, true, '', array() - */ - if (array_key_exists($pkIdentity, $data)) { - if ($data[$pkIdentity] === null // null - || $data[$pkIdentity] === '' // empty string - || is_bool($data[$pkIdentity]) // boolean - || (is_array($data[$pkIdentity]) && empty($data[$pkIdentity]))) { // empty array - unset($data[$pkIdentity]); - } - } - - /** - * If this table uses a database sequence object and the data does not - * specify a value, then get the next ID from the sequence and add it - * to the row. We assume that only the first column in a compound - * primary key takes a value from a sequence. - */ - if (is_string($this->_sequence) && !isset($data[$pkIdentity])) { - $data[$pkIdentity] = $this->_db->nextSequenceId($this->_sequence); - } - - /** - * INSERT the new row. - */ - $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name; - $this->_db->insert($tableSpec, $data); - - /** - * Fetch the most recent ID generated by an auto-increment - * or IDENTITY column, unless the user has specified a value, - * overriding the auto-increment mechanism. - */ - if ($this->_sequence === true && !isset($data[$pkIdentity])) { - $data[$pkIdentity] = $this->_db->lastInsertId(); - } - - /** - * Return the primary key value if the PK is a single column, - * else return an associative array of the PK column/value pairs. - */ - $pkData = array_intersect_key($data, array_flip($primary)); - if (count($primary) == 1) { - reset($pkData); - return current($pkData); - } - - return $pkData; - } - - /** - * Check if the provided column is an identity of the table - * - * @param string $column - * @throws Zend_Db_Table_Exception - * @return boolean - */ - public function isIdentity($column) - { - $this->_setupPrimaryKey(); - - if (!isset($this->_metadata[$column])) { - /** - * @see Zend_Db_Table_Exception - */ - #require_once 'Zend/Db/Table/Exception.php'; - - throw new Zend_Db_Table_Exception('Column "' . $column . '" not found in table.'); - } - - return (bool) $this->_metadata[$column]['IDENTITY']; - } - - /** - * Updates existing rows. - * - * @param array $data Column-value pairs. - * @param array|string $where An SQL WHERE clause, or an array of SQL WHERE clauses. - * @return int The number of rows updated. - */ - public function update(array $data, $where) - { - $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name; - return $this->_db->update($tableSpec, $data, $where); - } - - /** - * Called by a row object for the parent table's class during save() method. - * - * @param string $parentTableClassname - * @param array $oldPrimaryKey - * @param array $newPrimaryKey - * @return int - */ - public function _cascadeUpdate($parentTableClassname, array $oldPrimaryKey, array $newPrimaryKey) - { - $this->_setupMetadata(); - $rowsAffected = 0; - foreach ($this->_getReferenceMapNormalized() as $map) { - if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_UPDATE])) { - switch ($map[self::ON_UPDATE]) { - case self::CASCADE: - $newRefs = array(); - $where = array(); - for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) { - $col = $this->_db->foldCase($map[self::COLUMNS][$i]); - $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]); - if (array_key_exists($refCol, $newPrimaryKey)) { - $newRefs[$col] = $newPrimaryKey[$refCol]; - } - $type = $this->_metadata[$col]['DATA_TYPE']; - $where[] = $this->_db->quoteInto( - $this->_db->quoteIdentifier($col, true) . ' = ?', - $oldPrimaryKey[$refCol], $type); - } - $rowsAffected += $this->update($newRefs, $where); - break; - default: - // no action - break; - } - } - } - return $rowsAffected; - } - - /** - * Deletes existing rows. - * - * @param array|string $where SQL WHERE clause(s). - * @return int The number of rows deleted. - */ - public function delete($where) - { - $depTables = $this->getDependentTables(); - if (!empty($depTables)) { - $resultSet = $this->fetchAll($where); - if (count($resultSet) > 0 ) { - foreach ($resultSet as $row) { - /** - * Execute cascading deletes against dependent tables - */ - foreach ($depTables as $tableClass) { - $t = self::getTableFromString($tableClass, $this); - $t->_cascadeDelete( - get_class($this), $row->getPrimaryKey() - ); - } - } - } - } - - $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name; - return $this->_db->delete($tableSpec, $where); - } - - /** - * Called by parent table's class during delete() method. - * - * @param string $parentTableClassname - * @param array $primaryKey - * @return int Number of affected rows - */ - public function _cascadeDelete($parentTableClassname, array $primaryKey) - { - // setup metadata - $this->_setupMetadata(); - - // get this class name - $thisClass = get_class($this); - if ($thisClass === 'Zend_Db_Table') { - $thisClass = $this->_definitionConfigName; - } - - $rowsAffected = 0; - - foreach ($this->_getReferenceMapNormalized() as $map) { - if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_DELETE])) { - - $where = array(); - - // CASCADE or CASCADE_RECURSE - if (in_array($map[self::ON_DELETE], array(self::CASCADE, self::CASCADE_RECURSE))) { - for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) { - $col = $this->_db->foldCase($map[self::COLUMNS][$i]); - $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]); - $type = $this->_metadata[$col]['DATA_TYPE']; - $where[] = $this->_db->quoteInto( - $this->_db->quoteIdentifier($col, true) . ' = ?', - $primaryKey[$refCol], $type); - } - } - - // CASCADE_RECURSE - if ($map[self::ON_DELETE] == self::CASCADE_RECURSE) { - - /** - * Execute cascading deletes against dependent tables - */ - $depTables = $this->getDependentTables(); - if (!empty($depTables)) { - foreach ($depTables as $tableClass) { - $t = self::getTableFromString($tableClass, $this); - foreach ($this->fetchAll($where) as $depRow) { - $rowsAffected += $t->_cascadeDelete($thisClass, $depRow->getPrimaryKey()); - } - } - } - } - - // CASCADE or CASCADE_RECURSE - if (in_array($map[self::ON_DELETE], array(self::CASCADE, self::CASCADE_RECURSE))) { - $rowsAffected += $this->delete($where); - } - - } - } - return $rowsAffected; - } - - /** - * Fetches rows by primary key. The argument specifies one or more primary - * key value(s). To find multiple rows by primary key, the argument must - * be an array. - * - * This method accepts a variable number of arguments. If the table has a - * multi-column primary key, the number of arguments must be the same as - * the number of columns in the primary key. To find multiple rows in a - * table with a multi-column primary key, each argument must be an array - * with the same number of elements. - * - * The find() method always returns a Rowset object, even if only one row - * was found. - * - * @param mixed $key The value(s) of the primary keys. - * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria. - * @throws Zend_Db_Table_Exception - */ - public function find() - { - $this->_setupPrimaryKey(); - $args = func_get_args(); - $keyNames = array_values((array) $this->_primary); - - if (count($args) < count($keyNames)) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception("Too few columns for the primary key"); - } - - if (count($args) > count($keyNames)) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception("Too many columns for the primary key"); - } - - $whereList = array(); - $numberTerms = 0; - foreach ($args as $keyPosition => $keyValues) { - $keyValuesCount = count($keyValues); - // Coerce the values to an array. - // Don't simply typecast to array, because the values - // might be Zend_Db_Expr objects. - if (!is_array($keyValues)) { - $keyValues = array($keyValues); - } - if ($numberTerms == 0) { - $numberTerms = $keyValuesCount; - } else if ($keyValuesCount != $numberTerms) { - #require_once 'Zend/Db/Table/Exception.php'; - throw new Zend_Db_Table_Exception("Missing value(s) for the primary key"); - } - $keyValues = array_values($keyValues); - for ($i = 0; $i < $keyValuesCount; ++$i) { - if (!isset($whereList[$i])) { - $whereList[$i] = array(); - } - $whereList[$i][$keyPosition] = $keyValues[$i]; - } - } - - $whereClause = null; - if (count($whereList)) { - $whereOrTerms = array(); - $tableName = $this->_db->quoteTableAs($this->_name, null, true); - foreach ($whereList as $keyValueSets) { - $whereAndTerms = array(); - foreach ($keyValueSets as $keyPosition => $keyValue) { - $type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE']; - $columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true); - $whereAndTerms[] = $this->_db->quoteInto( - $tableName . '.' . $columnName . ' = ?', - $keyValue, $type); - } - $whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')'; - } - $whereClause = '(' . implode(' OR ', $whereOrTerms) . ')'; - } - - // issue ZF-5775 (empty where clause should return empty rowset) - if ($whereClause == null) { - $rowsetClass = $this->getRowsetClass(); - if (!class_exists($rowsetClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rowsetClass); - } - return new $rowsetClass(array('table' => $this, 'rowClass' => $this->getRowClass(), 'stored' => true)); - } - - return $this->fetchAll($whereClause); - } - - /** - * Fetches all rows. - * - * Honors the Zend_Db_Adapter fetch mode. - * - * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object. - * @param string|array $order OPTIONAL An SQL ORDER clause. - * @param int $count OPTIONAL An SQL LIMIT count. - * @param int $offset OPTIONAL An SQL LIMIT offset. - * @return Zend_Db_Table_Rowset_Abstract The row results per the Zend_Db_Adapter fetch mode. - */ - public function fetchAll($where = null, $order = null, $count = null, $offset = null) - { - if (!($where instanceof Zend_Db_Table_Select)) { - $select = $this->select(); - - if ($where !== null) { - $this->_where($select, $where); - } - - if ($order !== null) { - $this->_order($select, $order); - } - - if ($count !== null || $offset !== null) { - $select->limit($count, $offset); - } - - } else { - $select = $where; - } - - $rows = $this->_fetch($select); - - $data = array( - 'table' => $this, - 'data' => $rows, - 'readOnly' => $select->isReadOnly(), - 'rowClass' => $this->getRowClass(), - 'stored' => true - ); - - $rowsetClass = $this->getRowsetClass(); - if (!class_exists($rowsetClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rowsetClass); - } - return new $rowsetClass($data); - } - - /** - * Fetches one row in an object of type Zend_Db_Table_Row_Abstract, - * or returns null if no row matches the specified criteria. - * - * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object. - * @param string|array $order OPTIONAL An SQL ORDER clause. - * @param int $offset OPTIONAL An SQL OFFSET value. - * @return Zend_Db_Table_Row_Abstract|null The row results per the - * Zend_Db_Adapter fetch mode, or null if no row found. - */ - public function fetchRow($where = null, $order = null, $offset = null) - { - if (!($where instanceof Zend_Db_Table_Select)) { - $select = $this->select(); - - if ($where !== null) { - $this->_where($select, $where); - } - - if ($order !== null) { - $this->_order($select, $order); - } - - $select->limit(1, ((is_numeric($offset)) ? (int) $offset : null)); - - } else { - $select = $where->limit(1, $where->getPart(Zend_Db_Select::LIMIT_OFFSET)); - } - - $rows = $this->_fetch($select); - - if (count($rows) == 0) { - return null; - } - - $data = array( - 'table' => $this, - 'data' => $rows[0], - 'readOnly' => $select->isReadOnly(), - 'stored' => true - ); - - $rowClass = $this->getRowClass(); - if (!class_exists($rowClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rowClass); - } - return new $rowClass($data); - } - - /** - * Fetches a new blank row (not from the database). - * - * @return Zend_Db_Table_Row_Abstract - * @deprecated since 0.9.3 - use createRow() instead. - */ - public function fetchNew() - { - return $this->createRow(); - } - - /** - * Fetches a new blank row (not from the database). - * - * @param array $data OPTIONAL data to populate in the new row. - * @param string $defaultSource OPTIONAL flag to force default values into new row - * @return Zend_Db_Table_Row_Abstract - */ - public function createRow(array $data = array(), $defaultSource = null) - { - $cols = $this->_getCols(); - $defaults = array_combine($cols, array_fill(0, count($cols), null)); - - // nothing provided at call-time, take the class value - if ($defaultSource == null) { - $defaultSource = $this->_defaultSource; - } - - if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) { - $defaultSource = self::DEFAULT_NONE; - } - - if ($defaultSource == self::DEFAULT_DB) { - foreach ($this->_metadata as $metadataName => $metadata) { - if (($metadata['DEFAULT'] != null) && - ($metadata['NULLABLE'] !== true || ($metadata['NULLABLE'] === true && isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === true)) && - (!(isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === false))) { - $defaults[$metadataName] = $metadata['DEFAULT']; - } - } - } elseif ($defaultSource == self::DEFAULT_CLASS && $this->_defaultValues) { - foreach ($this->_defaultValues as $defaultName => $defaultValue) { - if (array_key_exists($defaultName, $defaults)) { - $defaults[$defaultName] = $defaultValue; - } - } - } - - $config = array( - 'table' => $this, - 'data' => $defaults, - 'readOnly' => false, - 'stored' => false - ); - - $rowClass = $this->getRowClass(); - if (!class_exists($rowClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rowClass); - } - $row = new $rowClass($config); - $row->setFromArray($data); - return $row; - } - - /** - * Generate WHERE clause from user-supplied string or array - * - * @param string|array $where OPTIONAL An SQL WHERE clause. - * @return Zend_Db_Table_Select - */ - protected function _where(Zend_Db_Table_Select $select, $where) - { - $where = (array) $where; - - foreach ($where as $key => $val) { - // is $key an int? - if (is_int($key)) { - // $val is the full condition - $select->where($val); - } else { - // $key is the condition with placeholder, - // and $val is quoted into the condition - $select->where($key, $val); - } - } - - return $select; - } - - /** - * Generate ORDER clause from user-supplied string or array - * - * @param string|array $order OPTIONAL An SQL ORDER clause. - * @return Zend_Db_Table_Select - */ - protected function _order(Zend_Db_Table_Select $select, $order) - { - if (!is_array($order)) { - $order = array($order); - } - - foreach ($order as $val) { - $select->order($val); - } - - return $select; - } - - /** - * Support method for fetching rows. - * - * @param Zend_Db_Table_Select $select query options. - * @return array An array containing the row results in FETCH_ASSOC mode. - */ - protected function _fetch(Zend_Db_Table_Select $select) - { - $stmt = $this->_db->query($select); - $data = $stmt->fetchAll(Zend_Db::FETCH_ASSOC); - return $data; - } - - /** - * Get table gateway object from string - * - * @param string $tableName - * @param Zend_Db_Table_Abstract $referenceTable - * @throws Zend_Db_Table_Row_Exception - * @return Zend_Db_Table_Abstract - */ - public static function getTableFromString($tableName, Zend_Db_Table_Abstract $referenceTable = null) - { - if ($referenceTable instanceof Zend_Db_Table_Abstract) { - $tableDefinition = $referenceTable->getDefinition(); - - if ($tableDefinition !== null && $tableDefinition->hasTableConfig($tableName)) { - return new Zend_Db_Table($tableName, $tableDefinition); - } - } - - // assume the tableName is the class name - if (!class_exists($tableName)) { - try { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($tableName); - } catch (Zend_Exception $e) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e); - } - } - - $options = array(); - - if ($referenceTable instanceof Zend_Db_Table_Abstract) { - $options['db'] = $referenceTable->getAdapter(); - } - - if (isset($tableDefinition) && $tableDefinition !== null) { - $options[Zend_Db_Table_Abstract::DEFINITION] = $tableDefinition; - } - - return new $tableName($options); - } - -} diff --git a/lib/Zend/Db/Table/Definition.php b/lib/Zend/Db/Table/Definition.php deleted file mode 100644 index 76265ae20aa..00000000000 --- a/lib/Zend/Db/Table/Definition.php +++ /dev/null @@ -1,131 +0,0 @@ -setConfig($options); - } elseif (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * setConfig() - * - * @param Zend_Config $config - * @return Zend_Db_Table_Definition - */ - public function setConfig(Zend_Config $config) - { - $this->setOptions($config->toArray()); - return $this; - } - - /** - * setOptions() - * - * @param array $options - * @return Zend_Db_Table_Definition - */ - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $this->setTableConfig($optionName, $optionValue); - } - return $this; - } - - /** - * @param string $tableName - * @param array $tableConfig - * @return Zend_Db_Table_Definition - */ - public function setTableConfig($tableName, array $tableConfig) - { - // @todo logic here - $tableConfig[Zend_Db_Table::DEFINITION_CONFIG_NAME] = $tableName; - $tableConfig[Zend_Db_Table::DEFINITION] = $this; - - if (!isset($tableConfig[Zend_Db_Table::NAME])) { - $tableConfig[Zend_Db_Table::NAME] = $tableName; - } - - $this->_tableConfigs[$tableName] = $tableConfig; - return $this; - } - - /** - * getTableConfig() - * - * @param string $tableName - * @return array - */ - public function getTableConfig($tableName) - { - return $this->_tableConfigs[$tableName]; - } - - /** - * removeTableConfig() - * - * @param string $tableName - */ - public function removeTableConfig($tableName) - { - unset($this->_tableConfigs[$tableName]); - } - - /** - * hasTableConfig() - * - * @param string $tableName - * @return bool - */ - public function hasTableConfig($tableName) - { - return (isset($this->_tableConfigs[$tableName])); - } - -} diff --git a/lib/Zend/Db/Table/Exception.php b/lib/Zend/Db/Table/Exception.php deleted file mode 100644 index 226e7c91df5..00000000000 --- a/lib/Zend/Db/Table/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ - value). - * The keys must match the physical names of columns in the - * table for which this row is defined. - * - * @var array - */ - protected $_data = array(); - - /** - * This is set to a copy of $_data when the data is fetched from - * a database, specified as a new tuple in the constructor, or - * when dirty data is posted to the database with save(). - * - * @var array - */ - protected $_cleanData = array(); - - /** - * Tracks columns where data has been updated. Allows more specific insert and - * update operations. - * - * @var array - */ - protected $_modifiedFields = array(); - - /** - * Zend_Db_Table_Abstract parent class or instance. - * - * @var Zend_Db_Table_Abstract - */ - protected $_table = null; - - /** - * Connected is true if we have a reference to a live - * Zend_Db_Table_Abstract object. - * This is false after the Rowset has been deserialized. - * - * @var boolean - */ - protected $_connected = true; - - /** - * A row is marked read only if it contains columns that are not physically represented within - * the database schema (e.g. evaluated columns/Zend_Db_Expr columns). This can also be passed - * as a run-time config options as a means of protecting row data. - * - * @var boolean - */ - protected $_readOnly = false; - - /** - * Name of the class of the Zend_Db_Table_Abstract object. - * - * @var string - */ - protected $_tableClass = null; - - /** - * Primary row key(s). - * - * @var array - */ - protected $_primary; - - /** - * Constructor. - * - * Supported params for $config are:- - * - table = class name or object of type Zend_Db_Table_Abstract - * - data = values of columns in this row. - * - * @param array $config OPTIONAL Array of user-specified config options. - * @return void - * @throws Zend_Db_Table_Row_Exception - */ - public function __construct(array $config = array()) - { - if (isset($config['table']) && $config['table'] instanceof Zend_Db_Table_Abstract) { - $this->_table = $config['table']; - $this->_tableClass = get_class($this->_table); - } elseif ($this->_tableClass !== null) { - $this->_table = $this->_getTableFromString($this->_tableClass); - } - - if (isset($config['data'])) { - if (!is_array($config['data'])) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('Data must be an array'); - } - $this->_data = $config['data']; - } - if (isset($config['stored']) && $config['stored'] === true) { - $this->_cleanData = $this->_data; - } - - if (isset($config['readOnly']) && $config['readOnly'] === true) { - $this->setReadOnly(true); - } - - // Retrieve primary keys from table schema - if (($table = $this->_getTable())) { - $info = $table->info(); - $this->_primary = (array) $info['primary']; - } - - $this->init(); - } - - /** - * Transform a column name from the user-specified form - * to the physical form used in the database. - * You can override this method in a custom Row class - * to implement column name mappings, for example inflection. - * - * @param string $columnName Column name given. - * @return string The column name after transformation applied (none by default). - * @throws Zend_Db_Table_Row_Exception if the $columnName is not a string. - */ - protected function _transformColumn($columnName) - { - if (!is_string($columnName)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('Specified column is not a string'); - } - // Perform no transformation by default - return $columnName; - } - - /** - * Retrieve row field value - * - * @param string $columnName The user-specified column name. - * @return string The corresponding column value. - * @throws Zend_Db_Table_Row_Exception if the $columnName is not a column in the row. - */ - public function __get($columnName) - { - $columnName = $this->_transformColumn($columnName); - if (!array_key_exists($columnName, $this->_data)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row"); - } - return $this->_data[$columnName]; - } - - /** - * Set row field value - * - * @param string $columnName The column key. - * @param mixed $value The value for the property. - * @return void - * @throws Zend_Db_Table_Row_Exception - */ - public function __set($columnName, $value) - { - $columnName = $this->_transformColumn($columnName); - if (!array_key_exists($columnName, $this->_data)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row"); - } - $this->_data[$columnName] = $value; - $this->_modifiedFields[$columnName] = true; - } - - /** - * Unset row field value - * - * @param string $columnName The column key. - * @return Zend_Db_Table_Row_Abstract - * @throws Zend_Db_Table_Row_Exception - */ - public function __unset($columnName) - { - $columnName = $this->_transformColumn($columnName); - if (!array_key_exists($columnName, $this->_data)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row"); - } - if ($this->isConnected() && in_array($columnName, $this->_table->info('primary'))) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is a primary key and should not be unset"); - } - unset($this->_data[$columnName]); - return $this; - } - - /** - * Test existence of row field - * - * @param string $columnName The column key. - * @return boolean - */ - public function __isset($columnName) - { - $columnName = $this->_transformColumn($columnName); - return array_key_exists($columnName, $this->_data); - } - - /** - * Store table, primary key and data in serialized object - * - * @return array - */ - public function __sleep() - { - return array('_tableClass', '_primary', '_data', '_cleanData', '_readOnly' ,'_modifiedFields'); - } - - /** - * Setup to do on wakeup. - * A de-serialized Row should not be assumed to have access to a live - * database connection, so set _connected = false. - * - * @return void - */ - public function __wakeup() - { - $this->_connected = false; - } - - /** - * Proxy to __isset - * Required by the ArrayAccess implementation - * - * @param string $offset - * @return boolean - */ - public function offsetExists($offset) - { - return $this->__isset($offset); - } - - /** - * Proxy to __get - * Required by the ArrayAccess implementation - * - * @param string $offset - * @return string - */ - public function offsetGet($offset) - { - return $this->__get($offset); - } - - /** - * Proxy to __set - * Required by the ArrayAccess implementation - * - * @param string $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) - { - $this->__set($offset, $value); - } - - /** - * Proxy to __unset - * Required by the ArrayAccess implementation - * - * @param string $offset - */ - public function offsetUnset($offset) - { - return $this->__unset($offset); - } - - /** - * Initialize object - * - * Called from {@link __construct()} as final step of object instantiation. - * - * @return void - */ - public function init() - { - } - - /** - * Returns the table object, or null if this is disconnected row - * - * @return Zend_Db_Table_Abstract|null - */ - public function getTable() - { - return $this->_table; - } - - /** - * Set the table object, to re-establish a live connection - * to the database for a Row that has been de-serialized. - * - * @param Zend_Db_Table_Abstract $table - * @return boolean - * @throws Zend_Db_Table_Row_Exception - */ - public function setTable(Zend_Db_Table_Abstract $table = null) - { - if ($table == null) { - $this->_table = null; - $this->_connected = false; - return false; - } - - $tableClass = get_class($table); - if (! $table instanceof $this->_tableClass) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this->_tableClass"); - } - - $this->_table = $table; - $this->_tableClass = $tableClass; - - $info = $this->_table->info(); - - if ($info['cols'] != array_keys($this->_data)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row'); - } - - if (! array_intersect((array) $this->_primary, $info['primary']) == (array) $this->_primary) { - - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row"); - } - - $this->_connected = true; - return true; - } - - /** - * Query the class name of the Table object for which this - * Row was created. - * - * @return string - */ - public function getTableClass() - { - return $this->_tableClass; - } - - /** - * Test the connected status of the row. - * - * @return boolean - */ - public function isConnected() - { - return $this->_connected; - } - - /** - * Test the read-only status of the row. - * - * @return boolean - */ - public function isReadOnly() - { - return $this->_readOnly; - } - - /** - * Set the read-only status of the row. - * - * @param boolean $flag - * @return boolean - */ - public function setReadOnly($flag) - { - $this->_readOnly = (bool) $flag; - } - - /** - * Returns an instance of the parent table's Zend_Db_Table_Select object. - * - * @return Zend_Db_Table_Select - */ - public function select() - { - return $this->getTable()->select(); - } - - /** - * Saves the properties to the database. - * - * This performs an intelligent insert/update, and reloads the - * properties with fresh data from the table on success. - * - * @return mixed The primary key value(s), as an associative array if the - * key is compound, or a scalar if the key is single-column. - */ - public function save() - { - /** - * If the _cleanData array is empty, - * this is an INSERT of a new row. - * Otherwise it is an UPDATE. - */ - if (empty($this->_cleanData)) { - return $this->_doInsert(); - } else { - return $this->_doUpdate(); - } - } - - /** - * @return mixed The primary key value(s), as an associative array if the - * key is compound, or a scalar if the key is single-column. - */ - protected function _doInsert() - { - /** - * A read-only row cannot be saved. - */ - if ($this->_readOnly === true) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('This row has been marked read-only'); - } - - /** - * Run pre-INSERT logic - */ - $this->_insert(); - - /** - * Execute the INSERT (this may throw an exception) - */ - $data = array_intersect_key($this->_data, $this->_modifiedFields); - $primaryKey = $this->_getTable()->insert($data); - - /** - * Normalize the result to an array indexed by primary key column(s). - * The table insert() method may return a scalar. - */ - if (is_array($primaryKey)) { - $newPrimaryKey = $primaryKey; - } else { - //ZF-6167 Use tempPrimaryKey temporary to avoid that zend encoding fails. - $tempPrimaryKey = (array) $this->_primary; - $newPrimaryKey = array(current($tempPrimaryKey) => $primaryKey); - } - - /** - * Save the new primary key value in _data. The primary key may have - * been generated by a sequence or auto-increment mechanism, and this - * merge should be done before the _postInsert() method is run, so the - * new values are available for logging, etc. - */ - $this->_data = array_merge($this->_data, $newPrimaryKey); - - /** - * Run post-INSERT logic - */ - $this->_postInsert(); - - /** - * Update the _cleanData to reflect that the data has been inserted. - */ - $this->_refresh(); - - return $primaryKey; - } - - /** - * @return mixed The primary key value(s), as an associative array if the - * key is compound, or a scalar if the key is single-column. - */ - protected function _doUpdate() - { - /** - * A read-only row cannot be saved. - */ - if ($this->_readOnly === true) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('This row has been marked read-only'); - } - - /** - * Get expressions for a WHERE clause - * based on the primary key value(s). - */ - $where = $this->_getWhereQuery(false); - - /** - * Run pre-UPDATE logic - */ - $this->_update(); - - /** - * Compare the data to the modified fields array to discover - * which columns have been changed. - */ - $diffData = array_intersect_key($this->_data, $this->_modifiedFields); - - /** - * Were any of the changed columns part of the primary key? - */ - $pkDiffData = array_intersect_key($diffData, array_flip((array)$this->_primary)); - - /** - * Execute cascading updates against dependent tables. - * Do this only if primary key value(s) were changed. - */ - if (count($pkDiffData) > 0) { - $depTables = $this->_getTable()->getDependentTables(); - if (!empty($depTables)) { - $pkNew = $this->_getPrimaryKey(true); - $pkOld = $this->_getPrimaryKey(false); - foreach ($depTables as $tableClass) { - $t = $this->_getTableFromString($tableClass); - $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew); - } - } - } - - /** - * Execute the UPDATE (this may throw an exception) - * Do this only if data values were changed. - * Use the $diffData variable, so the UPDATE statement - * includes SET terms only for data values that changed. - */ - if (count($diffData) > 0) { - $this->_getTable()->update($diffData, $where); - } - - /** - * Run post-UPDATE logic. Do this before the _refresh() - * so the _postUpdate() function can tell the difference - * between changed data and clean (pre-changed) data. - */ - $this->_postUpdate(); - - /** - * Refresh the data just in case triggers in the RDBMS changed - * any columns. Also this resets the _cleanData. - */ - $this->_refresh(); - - /** - * Return the primary key value(s) as an array - * if the key is compound or a scalar if the key - * is a scalar. - */ - $primaryKey = $this->_getPrimaryKey(true); - if (count($primaryKey) == 1) { - return current($primaryKey); - } - - return $primaryKey; - } - - /** - * Deletes existing rows. - * - * @return int The number of rows deleted. - */ - public function delete() - { - /** - * A read-only row cannot be deleted. - */ - if ($this->_readOnly === true) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('This row has been marked read-only'); - } - - $where = $this->_getWhereQuery(); - - /** - * Execute pre-DELETE logic - */ - $this->_delete(); - - /** - * Execute cascading deletes against dependent tables - */ - $depTables = $this->_getTable()->getDependentTables(); - if (!empty($depTables)) { - $pk = $this->_getPrimaryKey(); - foreach ($depTables as $tableClass) { - $t = $this->_getTableFromString($tableClass); - $t->_cascadeDelete($this->getTableClass(), $pk); - } - } - - /** - * Execute the DELETE (this may throw an exception) - */ - $result = $this->_getTable()->delete($where); - - /** - * Execute post-DELETE logic - */ - $this->_postDelete(); - - /** - * Reset all fields to null to indicate that the row is not there - */ - $this->_data = array_combine( - array_keys($this->_data), - array_fill(0, count($this->_data), null) - ); - - return $result; - } - - public function getIterator() - { - return new ArrayIterator((array) $this->_data); - } - - /** - * Returns the column/value data as an array. - * - * @return array - */ - public function toArray() - { - return (array)$this->_data; - } - - /** - * Sets all data in the row from an array. - * - * @param array $data - * @return Zend_Db_Table_Row_Abstract Provides a fluent interface - */ - public function setFromArray(array $data) - { - $data = array_intersect_key($data, $this->_data); - - foreach ($data as $columnName => $value) { - $this->__set($columnName, $value); - } - - return $this; - } - - /** - * Refreshes properties from the database. - * - * @return void - */ - public function refresh() - { - return $this->_refresh(); - } - - /** - * Retrieves an instance of the parent table. - * - * @return Zend_Db_Table_Abstract - */ - protected function _getTable() - { - if (!$this->_connected) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('Cannot save a Row unless it is connected'); - } - return $this->_table; - } - - /** - * Retrieves an associative array of primary keys. - * - * @param bool $useDirty - * @return array - */ - protected function _getPrimaryKey($useDirty = true) - { - if (!is_array($this->_primary)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("The primary key must be set as an array"); - } - - $primary = array_flip($this->_primary); - if ($useDirty) { - $array = array_intersect_key($this->_data, $primary); - } else { - $array = array_intersect_key($this->_cleanData, $primary); - } - if (count($primary) != count($array)) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("The specified Table '$this->_tableClass' does not have the same primary key as the Row"); - } - return $array; - } - - /** - * Retrieves an associative array of primary keys. - * - * @param bool $useDirty - * @return array - */ - public function getPrimaryKey($useDirty = true) - { - return $this->_getPrimaryKey($useDirty); - } - - /** - * Constructs where statement for retrieving row(s). - * - * @param bool $useDirty - * @return array - */ - protected function _getWhereQuery($useDirty = true) - { - $where = array(); - $db = $this->_getTable()->getAdapter(); - $primaryKey = $this->_getPrimaryKey($useDirty); - $info = $this->_getTable()->info(); - $metadata = $info[Zend_Db_Table_Abstract::METADATA]; - - // retrieve recently updated row using primary keys - $where = array(); - foreach ($primaryKey as $column => $value) { - $tableName = $db->quoteIdentifier($info[Zend_Db_Table_Abstract::NAME], true); - $type = $metadata[$column]['DATA_TYPE']; - $columnName = $db->quoteIdentifier($column, true); - $where[] = $db->quoteInto("{$tableName}.{$columnName} = ?", $value, $type); - } - return $where; - } - - /** - * Refreshes properties from the database. - * - * @return void - */ - protected function _refresh() - { - $where = $this->_getWhereQuery(); - $row = $this->_getTable()->fetchRow($where); - - if (null === $row) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception('Cannot refresh row as parent is missing'); - } - - $this->_data = $row->toArray(); - $this->_cleanData = $this->_data; - $this->_modifiedFields = array(); - } - - /** - * Allows pre-insert logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _insert() - { - } - - /** - * Allows post-insert logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _postInsert() - { - } - - /** - * Allows pre-update logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _update() - { - } - - /** - * Allows post-update logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _postUpdate() - { - } - - /** - * Allows pre-delete logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _delete() - { - } - - /** - * Allows post-delete logic to be applied to row. - * Subclasses may override this method. - * - * @return void - */ - protected function _postDelete() - { - } - - /** - * Prepares a table reference for lookup. - * - * Ensures all reference keys are set and properly formatted. - * - * @param Zend_Db_Table_Abstract $dependentTable - * @param Zend_Db_Table_Abstract $parentTable - * @param string $ruleKey - * @return array - */ - protected function _prepareReference(Zend_Db_Table_Abstract $dependentTable, Zend_Db_Table_Abstract $parentTable, $ruleKey) - { - $parentTableName = (get_class($parentTable) === 'Zend_Db_Table') ? $parentTable->getDefinitionConfigName() : get_class($parentTable); - $map = $dependentTable->getReference($parentTableName, $ruleKey); - - if (!isset($map[Zend_Db_Table_Abstract::REF_COLUMNS])) { - $parentInfo = $parentTable->info(); - $map[Zend_Db_Table_Abstract::REF_COLUMNS] = array_values((array) $parentInfo['primary']); - } - - $map[Zend_Db_Table_Abstract::COLUMNS] = (array) $map[Zend_Db_Table_Abstract::COLUMNS]; - $map[Zend_Db_Table_Abstract::REF_COLUMNS] = (array) $map[Zend_Db_Table_Abstract::REF_COLUMNS]; - - return $map; - } - - /** - * Query a dependent table to retrieve rows matching the current row. - * - * @param string|Zend_Db_Table_Abstract $dependentTable - * @param string OPTIONAL $ruleKey - * @param Zend_Db_Table_Select OPTIONAL $select - * @return Zend_Db_Table_Rowset_Abstract Query result from $dependentTable - * @throws Zend_Db_Table_Row_Exception If $dependentTable is not a table or is not loadable. - */ - public function findDependentRowset($dependentTable, $ruleKey = null, Zend_Db_Table_Select $select = null) - { - $db = $this->_getTable()->getAdapter(); - - if (is_string($dependentTable)) { - $dependentTable = $this->_getTableFromString($dependentTable); - } - - if (!$dependentTable instanceof Zend_Db_Table_Abstract) { - $type = gettype($dependentTable); - if ($type == 'object') { - $type = get_class($dependentTable); - } - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Dependent table must be a Zend_Db_Table_Abstract, but it is $type"); - } - - // even if we are interacting between a table defined in a class and a - // table via extension, ensure to persist the definition - if (($tableDefinition = $this->_table->getDefinition()) !== null - && ($dependentTable->getDefinition() == null)) { - $dependentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition)); - } - - if ($select === null) { - $select = $dependentTable->select(); - } else { - $select->setTable($dependentTable); - } - - $map = $this->_prepareReference($dependentTable, $this->_getTable(), $ruleKey); - - for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) { - $parentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]); - $value = $this->_data[$parentColumnName]; - // Use adapter from dependent table to ensure correct query construction - $dependentDb = $dependentTable->getAdapter(); - $dependentColumnName = $dependentDb->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]); - $dependentColumn = $dependentDb->quoteIdentifier($dependentColumnName, true); - $dependentInfo = $dependentTable->info(); - $type = $dependentInfo[Zend_Db_Table_Abstract::METADATA][$dependentColumnName]['DATA_TYPE']; - $select->where("$dependentColumn = ?", $value, $type); - } - - return $dependentTable->fetchAll($select); - } - - /** - * Query a parent table to retrieve the single row matching the current row. - * - * @param string|Zend_Db_Table_Abstract $parentTable - * @param string OPTIONAL $ruleKey - * @param Zend_Db_Table_Select OPTIONAL $select - * @return Zend_Db_Table_Row_Abstract Query result from $parentTable - * @throws Zend_Db_Table_Row_Exception If $parentTable is not a table or is not loadable. - */ - public function findParentRow($parentTable, $ruleKey = null, Zend_Db_Table_Select $select = null) - { - $db = $this->_getTable()->getAdapter(); - - if (is_string($parentTable)) { - $parentTable = $this->_getTableFromString($parentTable); - } - - if (!$parentTable instanceof Zend_Db_Table_Abstract) { - $type = gettype($parentTable); - if ($type == 'object') { - $type = get_class($parentTable); - } - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Parent table must be a Zend_Db_Table_Abstract, but it is $type"); - } - - // even if we are interacting between a table defined in a class and a - // table via extension, ensure to persist the definition - if (($tableDefinition = $this->_table->getDefinition()) !== null - && ($parentTable->getDefinition() == null)) { - $parentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition)); - } - - if ($select === null) { - $select = $parentTable->select(); - } else { - $select->setTable($parentTable); - } - - $map = $this->_prepareReference($this->_getTable(), $parentTable, $ruleKey); - - // iterate the map, creating the proper wheres - for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) { - $dependentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]); - $value = $this->_data[$dependentColumnName]; - // Use adapter from parent table to ensure correct query construction - $parentDb = $parentTable->getAdapter(); - $parentColumnName = $parentDb->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]); - $parentColumn = $parentDb->quoteIdentifier($parentColumnName, true); - $parentInfo = $parentTable->info(); - - // determine where part - $type = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['DATA_TYPE']; - $nullable = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['NULLABLE']; - if ($value === null && $nullable == true) { - $select->where("$parentColumn IS NULL"); - } elseif ($value === null && $nullable == false) { - return null; - } else { - $select->where("$parentColumn = ?", $value, $type); - } - - } - - return $parentTable->fetchRow($select); - } - - /** - * @param string|Zend_Db_Table_Abstract $matchTable - * @param string|Zend_Db_Table_Abstract $intersectionTable - * @param string OPTIONAL $callerRefRule - * @param string OPTIONAL $matchRefRule - * @param Zend_Db_Table_Select OPTIONAL $select - * @return Zend_Db_Table_Rowset_Abstract Query result from $matchTable - * @throws Zend_Db_Table_Row_Exception If $matchTable or $intersectionTable is not a table class or is not loadable. - */ - public function findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule = null, - $matchRefRule = null, Zend_Db_Table_Select $select = null) - { - $db = $this->_getTable()->getAdapter(); - - if (is_string($intersectionTable)) { - $intersectionTable = $this->_getTableFromString($intersectionTable); - } - - if (!$intersectionTable instanceof Zend_Db_Table_Abstract) { - $type = gettype($intersectionTable); - if ($type == 'object') { - $type = get_class($intersectionTable); - } - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Intersection table must be a Zend_Db_Table_Abstract, but it is $type"); - } - - // even if we are interacting between a table defined in a class and a - // table via extension, ensure to persist the definition - if (($tableDefinition = $this->_table->getDefinition()) !== null - && ($intersectionTable->getDefinition() == null)) { - $intersectionTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition)); - } - - if (is_string($matchTable)) { - $matchTable = $this->_getTableFromString($matchTable); - } - - if (! $matchTable instanceof Zend_Db_Table_Abstract) { - $type = gettype($matchTable); - if ($type == 'object') { - $type = get_class($matchTable); - } - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Match table must be a Zend_Db_Table_Abstract, but it is $type"); - } - - // even if we are interacting between a table defined in a class and a - // table via extension, ensure to persist the definition - if (($tableDefinition = $this->_table->getDefinition()) !== null - && ($matchTable->getDefinition() == null)) { - $matchTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition)); - } - - if ($select === null) { - $select = $matchTable->select(); - } else { - $select->setTable($matchTable); - } - - // Use adapter from intersection table to ensure correct query construction - $interInfo = $intersectionTable->info(); - $interDb = $intersectionTable->getAdapter(); - $interName = $interInfo['name']; - $interSchema = isset($interInfo['schema']) ? $interInfo['schema'] : null; - $matchInfo = $matchTable->info(); - $matchName = $matchInfo['name']; - $matchSchema = isset($matchInfo['schema']) ? $matchInfo['schema'] : null; - - $matchMap = $this->_prepareReference($intersectionTable, $matchTable, $matchRefRule); - - for ($i = 0; $i < count($matchMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) { - $interCol = $interDb->quoteIdentifier('i' . '.' . $matchMap[Zend_Db_Table_Abstract::COLUMNS][$i], true); - $matchCol = $interDb->quoteIdentifier('m' . '.' . $matchMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i], true); - $joinCond[] = "$interCol = $matchCol"; - } - $joinCond = implode(' AND ', $joinCond); - - $select->from(array('i' => $interName), array(), $interSchema) - ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema) - ->setIntegrityCheck(false); - - $callerMap = $this->_prepareReference($intersectionTable, $this->_getTable(), $callerRefRule); - - for ($i = 0; $i < count($callerMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) { - $callerColumnName = $db->foldCase($callerMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i]); - $value = $this->_data[$callerColumnName]; - $interColumnName = $interDb->foldCase($callerMap[Zend_Db_Table_Abstract::COLUMNS][$i]); - $interCol = $interDb->quoteIdentifier("i.$interColumnName", true); - $interInfo = $intersectionTable->info(); - $type = $interInfo[Zend_Db_Table_Abstract::METADATA][$interColumnName]['DATA_TYPE']; - $select->where($interDb->quoteInto("$interCol = ?", $value, $type)); - } - - $stmt = $select->query(); - - $config = array( - 'table' => $matchTable, - 'data' => $stmt->fetchAll(Zend_Db::FETCH_ASSOC), - 'rowClass' => $matchTable->getRowClass(), - 'readOnly' => false, - 'stored' => true - ); - - $rowsetClass = $matchTable->getRowsetClass(); - if (!class_exists($rowsetClass)) { - try { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($rowsetClass); - } catch (Zend_Exception $e) { - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e); - } - } - $rowset = new $rowsetClass($config); - return $rowset; - } - - /** - * Turn magic function calls into non-magic function calls - * to the above methods. - * - * @param string $method - * @param array $args OPTIONAL Zend_Db_Table_Select query modifier - * @return Zend_Db_Table_Row_Abstract|Zend_Db_Table_Rowset_Abstract - * @throws Zend_Db_Table_Row_Exception If an invalid method is called. - */ - public function __call($method, array $args) - { - $matches = array(); - - if (count($args) && $args[0] instanceof Zend_Db_Table_Select) { - $select = $args[0]; - } else { - $select = null; - } - - /** - * Recognize methods for Has-Many cases: - * findParent() - * findParentBy() - * Use the non-greedy pattern repeat modifier e.g. \w+? - */ - if (preg_match('/^findParent(\w+?)(?:By(\w+))?$/', $method, $matches)) { - $class = $matches[1]; - $ruleKey1 = isset($matches[2]) ? $matches[2] : null; - return $this->findParentRow($class, $ruleKey1, $select); - } - - /** - * Recognize methods for Many-to-Many cases: - * findVia() - * findViaBy() - * findViaByAnd() - * Use the non-greedy pattern repeat modifier e.g. \w+? - */ - if (preg_match('/^find(\w+?)Via(\w+?)(?:By(\w+?)(?:And(\w+))?)?$/', $method, $matches)) { - $class = $matches[1]; - $viaClass = $matches[2]; - $ruleKey1 = isset($matches[3]) ? $matches[3] : null; - $ruleKey2 = isset($matches[4]) ? $matches[4] : null; - return $this->findManyToManyRowset($class, $viaClass, $ruleKey1, $ruleKey2, $select); - } - - /** - * Recognize methods for Belongs-To cases: - * find() - * findBy() - * Use the non-greedy pattern repeat modifier e.g. \w+? - */ - if (preg_match('/^find(\w+?)(?:By(\w+))?$/', $method, $matches)) { - $class = $matches[1]; - $ruleKey1 = isset($matches[2]) ? $matches[2] : null; - return $this->findDependentRowset($class, $ruleKey1, $select); - } - - #require_once 'Zend/Db/Table/Row/Exception.php'; - throw new Zend_Db_Table_Row_Exception("Unrecognized method '$method()'"); - } - - - /** - * _getTableFromString - * - * @param string $tableName - * @return Zend_Db_Table_Abstract - */ - protected function _getTableFromString($tableName) - { - return Zend_Db_Table_Abstract::getTableFromString($tableName, $this->_table); - } - -} diff --git a/lib/Zend/Db/Table/Row/Exception.php b/lib/Zend/Db/Table/Row/Exception.php deleted file mode 100644 index 1be69c39825..00000000000 --- a/lib/Zend/Db/Table/Row/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_table = $config['table']; - $this->_tableClass = get_class($this->_table); - } - if (isset($config['rowClass'])) { - $this->_rowClass = $config['rowClass']; - } - if (!class_exists($this->_rowClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($this->_rowClass); - } - if (isset($config['data'])) { - $this->_data = $config['data']; - } - if (isset($config['readOnly'])) { - $this->_readOnly = $config['readOnly']; - } - if (isset($config['stored'])) { - $this->_stored = $config['stored']; - } - - // set the count of rows - $this->_count = count($this->_data); - - $this->init(); - } - - /** - * Store data, class names, and state in serialized object - * - * @return array - */ - public function __sleep() - { - return array('_data', '_tableClass', '_rowClass', '_pointer', '_count', '_rows', '_stored', - '_readOnly'); - } - - /** - * Setup to do on wakeup. - * A de-serialized Rowset should not be assumed to have access to a live - * database connection, so set _connected = false. - * - * @return void - */ - public function __wakeup() - { - $this->_connected = false; - } - - /** - * Initialize object - * - * Called from {@link __construct()} as final step of object instantiation. - * - * @return void - */ - public function init() - { - } - - /** - * Return the connected state of the rowset. - * - * @return boolean - */ - public function isConnected() - { - return $this->_connected; - } - - /** - * Returns the table object, or null if this is disconnected rowset - * - * @return Zend_Db_Table_Abstract - */ - public function getTable() - { - return $this->_table; - } - - /** - * Set the table object, to re-establish a live connection - * to the database for a Rowset that has been de-serialized. - * - * @param Zend_Db_Table_Abstract $table - * @return boolean - * @throws Zend_Db_Table_Row_Exception - */ - public function setTable(Zend_Db_Table_Abstract $table) - { - $this->_table = $table; - $this->_connected = false; - // @todo This works only if we have iterated through - // the result set once to instantiate the rows. - foreach ($this as $row) { - $connected = $row->setTable($table); - if ($connected == true) { - $this->_connected = true; - } - } - $this->rewind(); - return $this->_connected; - } - - /** - * Query the class name of the Table object for which this - * Rowset was created. - * - * @return string - */ - public function getTableClass() - { - return $this->_tableClass; - } - - /** - * Rewind the Iterator to the first element. - * Similar to the reset() function for arrays in PHP. - * Required by interface Iterator. - * - * @return Zend_Db_Table_Rowset_Abstract Fluent interface. - */ - public function rewind() - { - $this->_pointer = 0; - return $this; - } - - /** - * Return the current element. - * Similar to the current() function for arrays in PHP - * Required by interface Iterator. - * - * @return Zend_Db_Table_Row_Abstract current element from the collection - */ - public function current() - { - if ($this->valid() === false) { - return null; - } - - // return the row object - return $this->_loadAndReturnRow($this->_pointer); - } - - /** - * Return the identifying key of the current element. - * Similar to the key() function for arrays in PHP. - * Required by interface Iterator. - * - * @return int - */ - public function key() - { - return $this->_pointer; - } - - /** - * Move forward to next element. - * Similar to the next() function for arrays in PHP. - * Required by interface Iterator. - * - * @return void - */ - public function next() - { - ++$this->_pointer; - } - - /** - * Check if there is a current element after calls to rewind() or next(). - * Used to check if we've iterated to the end of the collection. - * Required by interface Iterator. - * - * @return bool False if there's nothing more to iterate over - */ - public function valid() - { - return $this->_pointer >= 0 && $this->_pointer < $this->_count; - } - - /** - * Returns the number of elements in the collection. - * - * Implements Countable::count() - * - * @return int - */ - public function count() - { - return $this->_count; - } - - /** - * Take the Iterator to position $position - * Required by interface SeekableIterator. - * - * @param int $position the position to seek to - * @return Zend_Db_Table_Rowset_Abstract - * @throws Zend_Db_Table_Rowset_Exception - */ - public function seek($position) - { - $position = (int) $position; - if ($position < 0 || $position >= $this->_count) { - #require_once 'Zend/Db/Table/Rowset/Exception.php'; - throw new Zend_Db_Table_Rowset_Exception("Illegal index $position"); - } - $this->_pointer = $position; - return $this; - } - - /** - * Check if an offset exists - * Required by the ArrayAccess implementation - * - * @param string $offset - * @return boolean - */ - public function offsetExists($offset) - { - return isset($this->_data[(int) $offset]); - } - - /** - * Get the row for the given offset - * Required by the ArrayAccess implementation - * - * @param string $offset - * @return Zend_Db_Table_Row_Abstract - */ - public function offsetGet($offset) - { - $offset = (int) $offset; - if ($offset < 0 || $offset >= $this->_count) { - #require_once 'Zend/Db/Table/Rowset/Exception.php'; - throw new Zend_Db_Table_Rowset_Exception("Illegal index $offset"); - } - $this->_pointer = $offset; - - return $this->current(); - } - - /** - * Does nothing - * Required by the ArrayAccess implementation - * - * @param string $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) - { - } - - /** - * Does nothing - * Required by the ArrayAccess implementation - * - * @param string $offset - */ - public function offsetUnset($offset) - { - } - - /** - * Returns a Zend_Db_Table_Row from a known position into the Iterator - * - * @param int $position the position of the row expected - * @param bool $seek wether or not seek the iterator to that position after - * @return Zend_Db_Table_Row - * @throws Zend_Db_Table_Rowset_Exception - */ - public function getRow($position, $seek = false) - { - try { - $row = $this->_loadAndReturnRow($position); - } catch (Zend_Db_Table_Rowset_Exception $e) { - #require_once 'Zend/Db/Table/Rowset/Exception.php'; - throw new Zend_Db_Table_Rowset_Exception('No row could be found at position ' . (int) $position, 0, $e); - } - - if ($seek == true) { - $this->seek($position); - } - - return $row; - } - - /** - * Returns all data as an array. - * - * Updates the $_data property with current row object values. - * - * @return array - */ - public function toArray() - { - // @todo This works only if we have iterated through - // the result set once to instantiate the rows. - foreach ($this->_rows as $i => $row) { - $this->_data[$i] = $row->toArray(); - } - return $this->_data; - } - - protected function _loadAndReturnRow($position) - { - if (!isset($this->_data[$position])) { - #require_once 'Zend/Db/Table/Rowset/Exception.php'; - throw new Zend_Db_Table_Rowset_Exception("Data for provided position does not exist"); - } - - // do we already have a row object for this position? - if (empty($this->_rows[$position])) { - $this->_rows[$position] = new $this->_rowClass( - array( - 'table' => $this->_table, - 'data' => $this->_data[$position], - 'stored' => $this->_stored, - 'readOnly' => $this->_readOnly - ) - ); - - if ( $this->_table instanceof Zend_Db_Table_Abstract ) { - $info = $this->_table->info(); - - if ( $this->_rows[$position] instanceof Zend_Db_Table_Row_Abstract ) { - if ($info['cols'] == array_keys($this->_data[$position])) { - $this->_rows[$position]->setTable($this->getTable()); - } - } - } else { - $this->_rows[$position]->setTable(null); - } - } - - // return the row object - return $this->_rows[$position]; - } - -} diff --git a/lib/Zend/Db/Table/Rowset/Exception.php b/lib/Zend/Db/Table/Rowset/Exception.php deleted file mode 100644 index 89d5c456283..00000000000 --- a/lib/Zend/Db/Table/Rowset/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -getAdapter()); - - $this->setTable($table); - } - - /** - * Return the table that created this select object - * - * @return Zend_Db_Table_Abstract - */ - public function getTable() - { - return $this->_table; - } - - /** - * Sets the primary table name and retrieves the table schema. - * - * @param Zend_Db_Table_Abstract $adapter - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function setTable(Zend_Db_Table_Abstract $table) - { - $this->_adapter = $table->getAdapter(); - $this->_info = $table->info(); - $this->_table = $table; - - return $this; - } - - /** - * Sets the integrity check flag. - * - * Setting this flag to false skips the checks for table joins, allowing - * 'hybrid' table rows to be created. - * - * @param Zend_Db_Table_Abstract $adapter - * @return Zend_Db_Select This Zend_Db_Select object. - */ - public function setIntegrityCheck($flag = true) - { - $this->_integrityCheck = $flag; - return $this; - } - - /** - * Tests query to determine if expressions or aliases columns exist. - * - * @return boolean - */ - public function isReadOnly() - { - $readOnly = false; - $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS); - $cols = $this->_info[Zend_Db_Table_Abstract::COLS]; - - if (!count($fields)) { - return $readOnly; - } - - foreach ($fields as $columnEntry) { - $column = $columnEntry[1]; - $alias = $columnEntry[2]; - - if ($alias !== null) { - $column = $alias; - } - - switch (true) { - case ($column == self::SQL_WILDCARD): - break; - - case ($column instanceof Zend_Db_Expr): - case (!in_array($column, $cols)): - $readOnly = true; - break 2; - } - } - - return $readOnly; - } - - /** - * Adds a FROM table and optional columns to the query. - * - * The table name can be expressed - * - * @param array|string|Zend_Db_Expr|Zend_Db_Table_Abstract $name The table name or an - associative array relating - table name to correlation - name. - * @param array|string|Zend_Db_Expr $cols The columns to select from this table. - * @param string $schema The schema name to specify, if any. - * @return Zend_Db_Table_Select This Zend_Db_Table_Select object. - */ - public function from($name, $cols = self::SQL_WILDCARD, $schema = null) - { - if ($name instanceof Zend_Db_Table_Abstract) { - $info = $name->info(); - $name = $info[Zend_Db_Table_Abstract::NAME]; - if (isset($info[Zend_Db_Table_Abstract::SCHEMA])) { - $schema = $info[Zend_Db_Table_Abstract::SCHEMA]; - } - } - - return $this->joinInner($name, null, $cols, $schema); - } - - /** - * Performs a validation on the select query before passing back to the parent class. - * Ensures that only columns from the primary Zend_Db_Table are returned in the result. - * - * @return string|null This object as a SELECT string (or null if a string cannot be produced) - */ - public function assemble() - { - $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS); - $primary = $this->_info[Zend_Db_Table_Abstract::NAME]; - $schema = $this->_info[Zend_Db_Table_Abstract::SCHEMA]; - - - if (count($this->_parts[self::UNION]) == 0) { - - // If no fields are specified we assume all fields from primary table - if (!count($fields)) { - $this->from($primary, self::SQL_WILDCARD, $schema); - $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS); - } - - $from = $this->getPart(Zend_Db_Table_Select::FROM); - - if ($this->_integrityCheck !== false) { - foreach ($fields as $columnEntry) { - list($table, $column) = $columnEntry; - - // Check each column to ensure it only references the primary table - if ($column) { - if (!isset($from[$table]) || $from[$table]['tableName'] != $primary) { - #require_once 'Zend/Db/Table/Select/Exception.php'; - throw new Zend_Db_Table_Select_Exception('Select query cannot join with another table'); - } - } - } - } - } - - return parent::assemble(); - } -} diff --git a/lib/Zend/Db/Table/Select/Exception.php b/lib/Zend/Db/Table/Select/Exception.php deleted file mode 100644 index 677741e31cb..00000000000 --- a/lib/Zend/Db/Table/Select/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ - tags, cleans up newlines and indents, and runs - * htmlentities() before output. - * - * @param mixed $var The variable to dump. - * @param string $label OPTIONAL Label to prepend to output. - * @param bool $echo OPTIONAL Echo output if true. - * @return string - */ - public static function dump($var, $label=null, $echo=true) - { - // format the label - $label = ($label===null) ? '' : rtrim($label) . ' '; - - // var_dump the variable into a buffer and keep the output - ob_start(); - var_dump($var); - $output = ob_get_clean(); - - // neaten the newlines and indents - $output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output); - if (self::getSapi() == 'cli') { - $output = PHP_EOL . $label - . PHP_EOL . $output - . PHP_EOL; - } else { - if(!extension_loaded('xdebug')) { - $flags = ENT_QUOTES; - // PHP 5.4.0+ - if (defined('ENT_SUBSTITUTE')) { - $flags = ENT_QUOTES | ENT_SUBSTITUTE; - } - $output = htmlspecialchars($output, $flags); - } - - $output = '
'
-                    . $label
-                    . $output
-                    . '
'; - } - - if ($echo) { - echo($output); - } - return $output; - } - -} diff --git a/lib/Zend/Dojo.php b/lib/Zend/Dojo.php deleted file mode 100644 index 6035a65f33b..00000000000 --- a/lib/Zend/Dojo.php +++ /dev/null @@ -1,87 +0,0 @@ -addPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addPrefixPath('Zend_Dojo_Form_Element', 'Zend/Dojo/Form/Element', 'element') - ->addElementPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addDisplayGroupPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator') - ->setDefaultDisplayGroupClass('Zend_Dojo_Form_DisplayGroup'); - - foreach ($form->getSubForms() as $subForm) { - self::enableForm($subForm); - } - - if (null !== ($view = $form->getView())) { - self::enableView($view); - } - } - - /** - * Dojo-enable a view instance - * - * @param Zend_View_Interface $view - * @return void - */ - public static function enableView(Zend_View_Interface $view) - { - if (false === $view->getPluginLoader('helper')->getPaths('Zend_Dojo_View_Helper')) { - $view->addHelperPath('Zend/Dojo/View/Helper', 'Zend_Dojo_View_Helper'); - } - } -} - diff --git a/lib/Zend/Dojo/BuildLayer.php b/lib/Zend/Dojo/BuildLayer.php deleted file mode 100644 index 8d3d08f7373..00000000000 --- a/lib/Zend/Dojo/BuildLayer.php +++ /dev/null @@ -1,536 +0,0 @@ - 'release', - 'optimize' => 'shrinksafe', - 'layerOptimize' => 'shrinksafe', - 'copyTests' => false, - 'loader' => 'default', - 'cssOptimize' => 'comments', - ); - - /** - * Associative array of module/path pairs for the build profile - * @var array - */ - protected $_profilePrefixes = array(); - - /** - * Zend_View reference - * @var Zend_View_Interface - */ - protected $_view; - - /** - * Constructor - * - * @param array|Zend_Config $options - * @return void - * @throws Zend_Dojo_Exception for invalid option argument - */ - public function __construct($options = null) - { - if (null !== $options) { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (!is_array($options)) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Invalid options provided to constructor'); - } - $this->setOptions($options); - } - } - - /** - * Set options - * - * Proxies to any setter that matches an option key. - * - * @param array $options - * @return Zend_Dojo_BuildLayer - */ - public function setOptions(array $options) - { - $methods = get_class_methods($this); - foreach ($options as $key => $value) { - $method = 'set' . ucfirst($key); - if (in_array($method, $methods)) { - $this->$method($value); - } - } - return $this; - } - - /** - * Set View object - * - * @param Zend_View_Interface $view - * @return Zend_Dojo_BuildLayer - */ - public function setView(Zend_View_Interface $view) - { - $this->_view = $view; - return $this; - } - - /** - * Retrieve view object - * - * @return Zend_View_Interface|null - */ - public function getView() - { - return $this->_view; - } - - /** - * Set dojo() view helper instance - * - * @param Zend_Dojo_View_Helper_Dojo_Container $helper - * @return Zend_Dojo_BuildLayer - */ - public function setDojoHelper(Zend_Dojo_View_Helper_Dojo_Container $helper) - { - $this->_dojo = $helper; - return $this; - } - - /** - * Retrieve dojo() view helper instance - * - * Will retrieve it from the view object if not registered. - * - * @return Zend_Dojo_View_Helper_Dojo_Container - * @throws Zend_Dojo_Exception if not registered and no view object found - */ - public function getDojoHelper() - { - if (null === $this->_dojo) { - if (null === ($view = $this->getView())) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('View object not registered; cannot retrieve dojo helper'); - } - $helper = $view->getHelper('dojo'); - $this->setDojoHelper($view->dojo()); - } - return $this->_dojo; - } - - /** - * Set custom layer name; e.g. "custom.main" - * - * @param string $name - * @return Zend_Dojo_BuildLayer - */ - public function setLayerName($name) - { - if (!preg_match('/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/i', $name)) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Invalid layer name provided; must be of form[a-z][a-z0-9_](\.[a-z][a-z0-9_])+'); - } - $this->_layerName = $name; - return $this; - } - - /** - * Retrieve custom layer name - * - * @return string|null - */ - public function getLayerName() - { - return $this->_layerName; - } - - /** - * Set the path to the custom layer script - * - * Should be a path relative to dojo.js - * - * @param string $path - * @return Zend_Dojo_BuildLayer - */ - public function setLayerScriptPath($path) - { - $this->_layerScriptPath = (string) $path; - return $this; - } - - /** - * Get custom layer script path - * - * @return string|null - */ - public function getLayerScriptPath() - { - return $this->_layerScriptPath; - } - - /** - * Set flag indicating whether or not to consume JS aggregated in dojo() - * view helper - * - * @param bool $flag - * @return Zend_Dojo_BuildLayer - */ - public function setConsumeJavascript($flag) - { - $this->_consumeJavascript = (bool) $flag; - return $this; - } - - /** - * Get flag indicating whether or not to consume JS aggregated in dojo() - * view helper - * - * @return bool - */ - public function consumeJavascript() - { - return $this->_consumeJavascript; - } - - /** - * Set flag indicating whether or not to consume dojo.addOnLoad events - * aggregated in dojo() view helper - * - * @param bool $flag - * @return Zend_Dojo_BuildLayer - */ - public function setConsumeOnLoad($flag) - { - $this->_consumeOnLoad = (bool) $flag; - return $this; - } - - /** - * Get flag indicating whether or not to consume dojo.addOnLoad events aggregated in dojo() view helper - * - * @return bool - */ - public function consumeOnLoad() - { - return $this->_consumeOnLoad; - } - - /** - * Set many build profile options at once - * - * @param array $options - * @return Zend_Dojo_BuildLayer - */ - public function setProfileOptions(array $options) - { - $this->_profileOptions += $options; - return $this; - } - - /** - * Add many build profile options at once - * - * @param array $options - * @return Zend_Dojo_BuildLayer - */ - public function addProfileOptions(array $options) - { - $this->_profileOptions = $this->_profileOptions + $options; - return $this; - } - - /** - * Add a single build profile option - * - * @param string $key - * @param value $value - * @return Zend_Dojo_BuildLayer - */ - public function addProfileOption($key, $value) - { - $this->_profileOptions[(string) $key] = $value; - return $this; - } - - /** - * Is a given build profile option set? - * - * @param string $key - * @return bool - */ - public function hasProfileOption($key) - { - return array_key_exists((string) $key, $this->_profileOptions); - } - - /** - * Retrieve a single build profile option - * - * Returns null if profile option does not exist. - * - * @param string $key - * @return mixed - */ - public function getProfileOption($key) - { - if ($this->hasProfileOption($key)) { - return $this->_profileOptions[(string) $key]; - } - return null; - } - - /** - * Get all build profile options - * - * @return array - */ - public function getProfileOptions() - { - return $this->_profileOptions; - } - - /** - * Remove a build profile option - * - * @param string $name - * @return Zend_Dojo_BuildLayer - */ - public function removeProfileOption($name) - { - if ($this->hasProfileOption($name)) { - unset($this->_profileOptions[(string) $name]); - } - return $this; - } - - /** - * Remove all build profile options - * - * @return Zend_Dojo_BuildLayer - */ - public function clearProfileOptions() - { - $this->_profileOptions = array(); - return $this; - } - - /** - * Add a build profile dependency prefix - * - * If just the prefix is passed, sets path to "../$prefix". - * - * @param string $prefix - * @param null|string $path - * @return Zend_Dojo_BuildLayer - */ - public function addProfilePrefix($prefix, $path = null) - { - if (null === $path) { - $path = '../' . $prefix; - } - $this->_profilePrefixes[$prefix] = array($prefix, $path); - return $this; - } - - /** - * Set multiple dependency prefixes for bulid profile - * - * @param array $prefixes - * @return Zend_Dojo_BuildLayer - */ - public function setProfilePrefixes(array $prefixes) - { - foreach ($prefixes as $prefix => $path) { - $this->addProfilePrefix($prefix, $path); - } - return $this; - } - - /** - * Get build profile dependency prefixes - * - * @return array - */ - public function getProfilePrefixes() - { - $layerName = $this->getLayerName(); - if (null !== $layerName) { - $prefix = $this->_getPrefix($layerName); - if (!array_key_exists($prefix, $this->_profilePrefixes)) { - $this->addProfilePrefix($prefix); - } - } - $view = $this->getView(); - if (!empty($view)) { - $helper = $this->getDojoHelper(); - if ($helper) { - $modules = $helper->getModules(); - foreach ($modules as $module) { - $prefix = $this->_getPrefix($module); - if (!array_key_exists($prefix, $this->_profilePrefixes)) { - $this->addProfilePrefix($prefix); - } - } - } - } - return $this->_profilePrefixes; - } - - /** - * Generate module layer script - * - * @return string - */ - public function generateLayerScript() - { - $helper = $this->getDojoHelper(); - $layerName = $this->getLayerName(); - $modulePaths = $helper->getModulePaths(); - $modules = $helper->getModules(); - $onLoadActions = $helper->getOnLoadActions(); - $javascript = $helper->getJavascript(); - - $content = 'dojo.provide("' . $layerName . '");' . "\n\n(function(){\n"; - - foreach ($modulePaths as $module => $path) { - $content .= sprintf("dojo.registerModulePath(\"%s\", \"%s\");\n", $module, $path); - } - foreach ($modules as $module) { - $content .= sprintf("dojo.require(\"%s\");\n", $module); - } - - if ($this->consumeOnLoad()) { - foreach ($helper->getOnLoadActions() as $callback) { - $content .= sprintf("dojo.addOnLoad(%s);\n", $callback); - } - } - if ($this->consumeJavascript()) { - $javascript = implode("\n", $helper->getJavascript()); - if (!empty($javascript)) { - $content .= "\n" . $javascript . "\n"; - } - } - - $content .= "})();"; - - return $content; - } - - /** - * Generate build profile - * - * @return string - */ - public function generateBuildProfile() - { - $profileOptions = $this->getProfileOptions(); - $layerName = $this->getLayerName(); - $layerScriptPath = $this->getLayerScriptPath(); - $profilePrefixes = $this->getProfilePrefixes(); - - if (!array_key_exists('releaseName', $profileOptions)) { - $profileOptions['releaseName'] = substr($layerName, 0, strpos($layerName, '.')); - } - - $profile = $profileOptions; - $profile['layers'] = array(array( - 'name' => $layerScriptPath, - 'layerDependencies' => array(), - 'dependencies' => array($layerName), - )); - $profile['prefixes'] = array_values($profilePrefixes); - - return 'dependencies = ' . $this->_filterJsonProfileToJavascript($profile) . ';'; - } - - /** - * Retrieve module prefix - * - * @param string $module - * @return void - */ - protected function _getPrefix($module) - { - $segments = explode('.', $module, 2); - return $segments[0]; - } - - /** - * Filter a JSON build profile to JavaScript - * - * @param string $profile - * @return string - */ - protected function _filterJsonProfileToJavascript($profile) - { - #require_once 'Zend/Json.php'; - $profile = Zend_Json::encode($profile); - $profile = trim($profile, '"'); - $profile = preg_replace('/' . preg_quote('\\') . '/', '', $profile); - return $profile; - } -} diff --git a/lib/Zend/Dojo/Data.php b/lib/Zend/Dojo/Data.php deleted file mode 100644 index d614d2e36a1..00000000000 --- a/lib/Zend/Dojo/Data.php +++ /dev/null @@ -1,563 +0,0 @@ -setIdentifier($identifier); - } - if (null !== $items) { - $this->setItems($items); - } - if (null !== $label) { - $this->setLabel($label); - } - } - - /** - * Set the items to collect - * - * @param array|Traversable $items - * @return Zend_Dojo_Data - */ - public function setItems($items) - { - $this->clearItems(); - return $this->addItems($items); - } - - /** - * Set an individual item, optionally by identifier (overwrites) - * - * @param array|object $item - * @param string|null $identifier - * @return Zend_Dojo_Data - */ - public function setItem($item, $id = null) - { - $item = $this->_normalizeItem($item, $id); - $this->_items[$item['id']] = $item['data']; - return $this; - } - - /** - * Add an individual item, optionally by identifier - * - * @param array|object $item - * @param string|null $id - * @return Zend_Dojo_Data - */ - public function addItem($item, $id = null) - { - $item = $this->_normalizeItem($item, $id); - - if ($this->hasItem($item['id'])) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Overwriting items using addItem() is not allowed'); - } - - $this->_items[$item['id']] = $item['data']; - - return $this; - } - - /** - * Add multiple items at once - * - * @param array|Traversable $items - * @return Zend_Dojo_Data - */ - public function addItems($items) - { - if (!is_array($items) && (!is_object($items) || !($items instanceof Traversable))) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Only arrays and Traversable objects may be added to ' . __CLASS__); - } - - foreach ($items as $item) { - $this->addItem($item); - } - - return $this; - } - - /** - * Get all items as an array - * - * Serializes items to arrays. - * - * @return array - */ - public function getItems() - { - return $this->_items; - } - - /** - * Does an item with the given identifier exist? - * - * @param string|int $id - * @return bool - */ - public function hasItem($id) - { - return array_key_exists($id, $this->_items); - } - - /** - * Retrieve an item by identifier - * - * Item retrieved will be flattened to an array. - * - * @param string $id - * @return array - */ - public function getItem($id) - { - if (!$this->hasItem($id)) { - return null; - } - - return $this->_items[$id]; - } - - /** - * Remove item by identifier - * - * @param string $id - * @return Zend_Dojo_Data - */ - public function removeItem($id) - { - if ($this->hasItem($id)) { - unset($this->_items[$id]); - } - - return $this; - } - - /** - * Remove all items at once - * - * @return Zend_Dojo_Data - */ - public function clearItems() - { - $this->_items = array(); - return $this; - } - - - /** - * Set identifier for item lookups - * - * @param string|int|null $identifier - * @return Zend_Dojo_Data - */ - public function setIdentifier($identifier) - { - if (null === $identifier) { - $this->_identifier = null; - } elseif (is_string($identifier)) { - $this->_identifier = $identifier; - } elseif (is_numeric($identifier)) { - $this->_identifier = (int) $identifier; - } else { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Invalid identifier; please use a string or integer'); - } - - return $this; - } - - /** - * Retrieve current item identifier - * - * @return string|int|null - */ - public function getIdentifier() - { - return $this->_identifier; - } - - - /** - * Set label to use for displaying item associations - * - * @param string|null $label - * @return Zend_Dojo_Data - */ - public function setLabel($label) - { - if (null === $label) { - $this->_label = null; - } else { - $this->_label = (string) $label; - } - return $this; - } - - /** - * Retrieve item association label - * - * @return string|null - */ - public function getLabel() - { - return $this->_label; - } - - /** - * Set metadata by key or en masse - * - * @param string|array $spec - * @param mixed $value - * @return Zend_Dojo_Data - */ - public function setMetadata($spec, $value = null) - { - if (is_string($spec) && (null !== $value)) { - $this->_metadata[$spec] = $value; - } elseif (is_array($spec)) { - foreach ($spec as $key => $value) { - $this->setMetadata($key, $value); - } - } - return $this; - } - - /** - * Get metadata item or all metadata - * - * @param null|string $key Metadata key when pulling single metadata item - * @return mixed - */ - public function getMetadata($key = null) - { - if (null === $key) { - return $this->_metadata; - } - - if (array_key_exists($key, $this->_metadata)) { - return $this->_metadata[$key]; - } - - return null; - } - - /** - * Clear individual or all metadata item(s) - * - * @param null|string $key - * @return Zend_Dojo_Data - */ - public function clearMetadata($key = null) - { - if (null === $key) { - $this->_metadata = array(); - } elseif (array_key_exists($key, $this->_metadata)) { - unset($this->_metadata[$key]); - } - return $this; - } - - /** - * Load object from array - * - * @param array $data - * @return Zend_Dojo_Data - */ - public function fromArray(array $data) - { - if (array_key_exists('identifier', $data)) { - $this->setIdentifier($data['identifier']); - } - if (array_key_exists('label', $data)) { - $this->setLabel($data['label']); - } - if (array_key_exists('items', $data) && is_array($data['items'])) { - $this->setItems($data['items']); - } else { - $this->clearItems(); - } - return $this; - } - - /** - * Load object from JSON - * - * @param string $json - * @return Zend_Dojo_Data - */ - public function fromJson($json) - { - if (!is_string($json)) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('fromJson() expects JSON input'); - } - #require_once 'Zend/Json.php'; - $data = Zend_Json::decode($json); - return $this->fromArray($data); - } - - /** - * Seralize entire data structure, including identifier and label, to array - * - * @return array - */ - public function toArray() - { - if (null === ($identifier = $this->getIdentifier())) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Serialization requires that an identifier be present in the object; first call setIdentifier()'); - } - - $array = array( - 'identifier' => $identifier, - 'items' => array_values($this->getItems()), - ); - - $metadata = $this->getMetadata(); - if (!empty($metadata)) { - foreach ($metadata as $key => $value) { - $array[$key] = $value; - } - } - - if (null !== ($label = $this->getLabel())) { - $array['label'] = $label; - } - - return $array; - } - - /** - * Serialize to JSON (dojo.data format) - * - * @return string - */ - public function toJson() - { - #require_once 'Zend/Json.php'; - return Zend_Json::encode($this->toArray()); - } - - /** - * Serialize to string (proxy to {@link toJson()}) - * - * @return string - */ - public function __toString() - { - return $this->toJson(); - } - - /** - * ArrayAccess: does offset exist? - * - * @param string|int $offset - * @return bool - */ - public function offsetExists($offset) - { - return (null !== $this->getItem($offset)); - } - - /** - * ArrayAccess: retrieve by offset - * - * @param string|int $offset - * @return array - */ - public function offsetGet($offset) - { - return $this->getItem($offset); - } - - /** - * ArrayAccess: set value by offset - * - * @param string $offset - * @param array|object|null $value - * @return void - */ - public function offsetSet($offset, $value) - { - $this->setItem($value, $offset); - } - - /** - * ArrayAccess: unset value by offset - * - * @param string $offset - * @return void - */ - public function offsetUnset($offset) - { - $this->removeItem($offset); - } - - /** - * Iterator: get current value - * - * @return array - */ - public function current() - { - return current($this->_items); - } - - /** - * Iterator: get current key - * - * @return string|int - */ - public function key() - { - return key($this->_items); - } - - /** - * Iterator: get next item - * - * @return void - */ - public function next() - { - return next($this->_items); - } - - /** - * Iterator: rewind to first value in collection - * - * @return void - */ - public function rewind() - { - return reset($this->_items); - } - - /** - * Iterator: is item valid? - * - * @return bool - */ - public function valid() - { - return (bool) $this->current(); - } - - /** - * Countable: how many items are present - * - * @return int - */ - public function count() - { - return count($this->_items); - } - - /** - * Normalize an item to attach to the collection - * - * @param array|object $item - * @param string|int|null $id - * @return array - */ - protected function _normalizeItem($item, $id) - { - if (null === ($identifier = $this->getIdentifier())) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('You must set an identifier prior to adding items'); - } - - if (!is_object($item) && !is_array($item)) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Only arrays and objects may be attached'); - } - - if (is_object($item)) { - if (method_exists($item, 'toArray')) { - $item = $item->toArray(); - } else { - $item = get_object_vars($item); - } - } - - if ((null === $id) && !array_key_exists($identifier, $item)) { - #require_once 'Zend/Dojo/Exception.php'; - throw new Zend_Dojo_Exception('Item must contain a column matching the currently set identifier'); - } elseif (null === $id) { - $id = $item[$identifier]; - } else { - $item[$identifier] = $id; - } - - return array( - 'id' => $id, - 'data' => $item, - ); - } -} diff --git a/lib/Zend/Dojo/Exception.php b/lib/Zend/Dojo/Exception.php deleted file mode 100644 index ffdf3771563..00000000000 --- a/lib/Zend/Dojo/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -addPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addPrefixPath('Zend_Dojo_Form_Element', 'Zend/Dojo/Form/Element', 'element') - ->addElementPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addDisplayGroupPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator') - ->setDefaultDisplayGroupClass('Zend_Dojo_Form_DisplayGroup'); - parent::__construct($options); - } - - /** - * Load the default decorators - * - * @return void - */ - public function loadDefaultDecorators() - { - if ($this->loadDefaultDecoratorsIsDisabled()) { - return; - } - - $decorators = $this->getDecorators(); - if (empty($decorators)) { - $this->addDecorator('FormElements') - ->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form_dojo')) - ->addDecorator('DijitForm'); - } - } - - /** - * Set the view object - * - * Ensures that the view object has the dojo view helper path set. - * - * @param Zend_View_Interface $view - * @return Zend_Dojo_Form_Element_Dijit - */ - public function setView(Zend_View_Interface $view = null) - { - if (null !== $view) { - if (false === $view->getPluginLoader('helper')->getPaths('Zend_Dojo_View_Helper')) { - $view->addHelperPath('Zend/Dojo/View/Helper', 'Zend_Dojo_View_Helper'); - } - } - return parent::setView($view); - } -} diff --git a/lib/Zend/Dojo/Form/Decorator/AccordionContainer.php b/lib/Zend/Dojo/Form/Decorator/AccordionContainer.php deleted file mode 100644 index d247841af27..00000000000 --- a/lib/Zend/Dojo/Form/Decorator/AccordionContainer.php +++ /dev/null @@ -1,43 +0,0 @@ -_helper) { - #require_once 'Zend/Form/Decorator/Exception.php'; - throw new Zend_Form_Decorator_Exception('No view helper specified fo DijitContainer decorator'); - } - return $this->_helper; - } - - /** - * Get element attributes - * - * @return array - */ - public function getAttribs() - { - if (null === $this->_attribs) { - $attribs = $this->getElement()->getAttribs(); - if (array_key_exists('dijitParams', $attribs)) { - unset($attribs['dijitParams']); - } - $this->_attribs = $attribs; - } - return $this->_attribs; - } - - /** - * Get dijit option parameters - * - * @return array - */ - public function getDijitParams() - { - if (null === $this->_dijitParams) { - $attribs = $this->getElement()->getAttribs(); - if (array_key_exists('dijitParams', $attribs)) { - $this->_dijitParams = $attribs['dijitParams']; - } else { - $this->_dijitParams = array(); - } - - $options = $this->getOptions(); - if (array_key_exists('dijitParams', $options)) { - $this->_dijitParams = array_merge($this->_dijitParams, $options['dijitParams']); - $this->removeOption('dijitParams'); - } - } - - // Ensure we have a title param - if (!array_key_exists('title', $this->_dijitParams)) { - $this->_dijitParams['title'] = $this->getTitle(); - } - - return $this->_dijitParams; - } - - /** - * Get title - * - * @return string - */ - public function getTitle() - { - if (null === $this->_title) { - $title = null; - if (null !== ($element = $this->getElement())) { - if (method_exists($element, 'getLegend')) { - $title = $element->getLegend(); - } - } - if (empty($title) && (null !== ($title = $this->getOption('legend')))) { - $this->removeOption('legend'); - } - if (empty($title) && (null !== ($title = $this->getOption('title')))) { - $this->removeOption('title'); - } - - if (!empty($title)) { - if (null !== ($translator = $element->getTranslator())) { - $title = $translator->translate($title); - } - $this->_title = $title; - } - } - - return (empty($this->_title) ? '' : $this->_title); - } - - /** - * Render a dijit layout container - * - * Replaces $content entirely from currently set element. - * - * @param string $content - * @return string - */ - public function render($content) - { - $element = $this->getElement(); - $view = $element->getView(); - if (null === $view) { - return $content; - } - - $dijitParams = $this->getDijitParams(); - $attribs = array_merge($this->getAttribs(), $this->getOptions()); - - if (array_key_exists('legend', $attribs)) { - if (!array_key_exists('title', $dijitParams) || empty($dijitParams['title'])) { - $dijitParams['title'] = $attribs['legend']; - } - unset($attribs['legend']); - } - - $helper = $this->getHelper(); - $id = $element->getId() . '-' . $helper; - - if ($view->dojo()->hasDijit($id)) { - trigger_error(sprintf('Duplicate dijit ID detected for id "%s; temporarily generating uniqid"', $id), E_USER_WARNING); - $base = $id; - do { - $id = $base . '-' . uniqid(); - } while ($view->dojo()->hasDijit($id)); - } - - return $view->$helper($id, $content, $dijitParams, $attribs); - } -} diff --git a/lib/Zend/Dojo/Form/Decorator/DijitElement.php b/lib/Zend/Dojo/Form/Decorator/DijitElement.php deleted file mode 100644 index a4c67b53f3e..00000000000 --- a/lib/Zend/Dojo/Form/Decorator/DijitElement.php +++ /dev/null @@ -1,193 +0,0 @@ -_attribs) { - $this->_attribs = parent::getElementAttribs(); - if (array_key_exists('dijitParams', $this->_attribs)) { - $this->setDijitParams($this->_attribs['dijitParams']); - unset($this->_attribs['dijitParams']); - } - } - - return $this->_attribs; - } - - /** - * Set a single dijit option parameter - * - * @param string $key - * @param mixed $value - * @return Zend_Dojo_Form_Decorator_DijitContainer - */ - public function setDijitParam($key, $value) - { - $this->_dijitParams[(string) $key] = $value; - return $this; - } - - /** - * Set dijit option parameters - * - * @param array $params - * @return Zend_Dojo_Form_Decorator_DijitContainer - */ - public function setDijitParams(array $params) - { - $this->_dijitParams = array_merge($this->_dijitParams, $params); - return $this; - } - - /** - * Retrieve a single dijit option parameter - * - * @param string $key - * @return mixed|null - */ - public function getDijitParam($key) - { - $this->getElementAttribs(); - $key = (string) $key; - if (array_key_exists($key, $this->_dijitParams)) { - return $this->_dijitParams[$key]; - } - - return null; - } - - /** - * Get dijit option parameters - * - * @return array - */ - public function getDijitParams() - { - $this->getElementAttribs(); - return $this->_dijitParams; - } - - /** - * Render an element using a view helper - * - * Determine view helper from 'helper' option, or, if none set, from - * the element type. Then call as - * helper($element->getName(), $element->getValue(), $element->getAttribs()) - * - * @param string $content - * @return string - * @throws Zend_Form_Decorator_Exception if element or view are not registered - */ - public function render($content) - { - $element = $this->getElement(); - $view = $element->getView(); - if (null === $view) { - #require_once 'Zend/Form/Decorator/Exception.php'; - throw new Zend_Form_Decorator_Exception('DijitElement decorator cannot render without a registered view object'); - } - - $options = null; - $helper = $this->getHelper(); - $separator = $this->getSeparator(); - $value = $this->getValue($element); - $attribs = $this->getElementAttribs(); - $name = $element->getFullyQualifiedName(); - - $dijitParams = $this->getDijitParams(); - $dijitParams['required'] = $element->isRequired(); - - $id = $element->getId(); - if ($view->dojo()->hasDijit($id)) { - trigger_error(sprintf('Duplicate dijit ID detected for id "%s; temporarily generating uniqid"', $id), E_USER_NOTICE); - $base = $id; - do { - $id = $base . '-' . uniqid(); - } while ($view->dojo()->hasDijit($id)); - } - $attribs['id'] = $id; - - if (array_key_exists('options', $attribs)) { - $options = $attribs['options']; - } - - $elementContent = $view->$helper($name, $value, $dijitParams, $attribs, $options); - switch ($this->getPlacement()) { - case self::APPEND: - return $content . $separator . $elementContent; - case self::PREPEND: - return $elementContent . $separator . $content; - default: - return $elementContent; - } - } -} diff --git a/lib/Zend/Dojo/Form/Decorator/DijitForm.php b/lib/Zend/Dojo/Form/Decorator/DijitForm.php deleted file mode 100644 index 19ecfdcce9c..00000000000 --- a/lib/Zend/Dojo/Form/Decorator/DijitForm.php +++ /dev/null @@ -1,66 +0,0 @@ -getElement(); - $view = $element->getView(); - if (null === $view) { - return $content; - } - - $dijitParams = $this->getDijitParams(); - $attribs = array_merge($this->getAttribs(), $this->getOptions()); - - // Enforce id attribute of form for dojo events - if (!isset($attribs['name']) || !$attribs['name']) { - $element->setName(get_class($element) . '_' . uniqid()); - } - - return $view->form($element->getName(), $attribs, $content); - } -} diff --git a/lib/Zend/Dojo/Form/Decorator/SplitContainer.php b/lib/Zend/Dojo/Form/Decorator/SplitContainer.php deleted file mode 100644 index 7d51ac81d59..00000000000 --- a/lib/Zend/Dojo/Form/Decorator/SplitContainer.php +++ /dev/null @@ -1,43 +0,0 @@ -addPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator'); - } - - /** - * Set the view object - * - * Ensures that the view object has the dojo view helper path set. - * - * @param Zend_View_Interface $view - * @return Zend_Dojo_Form_Element_Dijit - */ - public function setView(Zend_View_Interface $view = null) - { - if (null !== $view) { - if (false === $view->getPluginLoader('helper')->getPaths('Zend_Dojo_View_Helper')) { - $view->addHelperPath('Zend/Dojo/View/Helper', 'Zend_Dojo_View_Helper'); - } - } - return parent::setView($view); - } -} diff --git a/lib/Zend/Dojo/Form/Element/Button.php b/lib/Zend/Dojo/Form/Element/Button.php deleted file mode 100644 index c1864ebb6d4..00000000000 --- a/lib/Zend/Dojo/Form/Element/Button.php +++ /dev/null @@ -1,121 +0,0 @@ - $options); - } - - parent::__construct($spec, $options); - } - - /** - * Return label - * - * If no label is present, returns the currently set name. - * - * If a translator is present, returns the translated label. - * - * @return string - */ - public function getLabel() - { - $value = parent::getLabel(); - - if (null === $value) { - $value = $this->getName(); - } - - if (null !== ($translator = $this->getTranslator())) { - return $translator->translate($value); - } - - return $value; - } - - /** - * Has this submit button been selected? - * - * @return bool - */ - public function isChecked() - { - $value = $this->getValue(); - - if (empty($value)) { - return false; - } - if ($value != $this->getLabel()) { - return false; - } - - return true; - } - - /** - * Default decorators - * - * Uses only 'DijitElement' and 'DtDdWrapper' decorators by default. - * - * @return void - */ - public function loadDefaultDecorators() - { - if ($this->loadDefaultDecoratorsIsDisabled()) { - return; - } - - $decorators = $this->getDecorators(); - if (empty($decorators)) { - $this->addDecorator('DijitElement') - ->addDecorator('DtDdWrapper'); - } - } -} diff --git a/lib/Zend/Dojo/Form/Element/CheckBox.php b/lib/Zend/Dojo/Form/Element/CheckBox.php deleted file mode 100644 index 14278bab25a..00000000000 --- a/lib/Zend/Dojo/Form/Element/CheckBox.php +++ /dev/null @@ -1,206 +0,0 @@ - '1', - 'uncheckedValue' => '0', - ); - - /** - * Value when checked - * @var string - */ - protected $_checkedValue = '1'; - - /** - * Value when not checked - * @var string - */ - protected $_uncheckedValue = '0'; - - /** - * Current value - * @var string 0 or 1 - */ - protected $_value = '0'; - - /** - * Set options - * - * Intercept checked and unchecked values and set them early; test stored - * value against checked and unchecked values after configuration. - * - * @param array $options - * @return Zend_Form_Element_Checkbox - */ - public function setOptions(array $options) - { - if (array_key_exists('checkedValue', $options)) { - $this->setCheckedValue($options['checkedValue']); - unset($options['checkedValue']); - } - if (array_key_exists('uncheckedValue', $options)) { - $this->setUncheckedValue($options['uncheckedValue']); - unset($options['uncheckedValue']); - } - parent::setOptions($options); - - $curValue = $this->getValue(); - $test = array($this->getCheckedValue(), $this->getUncheckedValue()); - if (!in_array($curValue, $test)) { - $this->setValue($curValue); - } - - return $this; - } - - /** - * Set value - * - * If value matches checked value, sets to that value, and sets the checked - * flag to true. - * - * Any other value causes the unchecked value to be set as the current - * value, and the checked flag to be set as false. - * - * - * @param mixed $value - * @return Zend_Form_Element_Checkbox - */ - public function setValue($value) - { - if ($value == $this->getCheckedValue()) { - parent::setValue($value); - $this->checked = true; - } else { - parent::setValue($this->getUncheckedValue()); - $this->checked = false; - } - return $this; - } - - /** - * Set checked value - * - * @param string $value - * @return Zend_Form_Element_Checkbox - */ - public function setCheckedValue($value) - { - $this->_checkedValue = (string) $value; - $this->options['checkedValue'] = $value; - return $this; - } - - /** - * Get value when checked - * - * @return string - */ - public function getCheckedValue() - { - return $this->_checkedValue; - } - - /** - * Set unchecked value - * - * @param string $value - * @return Zend_Form_Element_Checkbox - */ - public function setUncheckedValue($value) - { - $this->_uncheckedValue = (string) $value; - $this->options['uncheckedValue'] = $value; - return $this; - } - - /** - * Get value when not checked - * - * @return string - */ - public function getUncheckedValue() - { - return $this->_uncheckedValue; - } - - /** - * Set checked flag - * - * @param bool $flag - * @return Zend_Form_Element_Checkbox - */ - public function setChecked($flag) - { - $this->checked = (bool) $flag; - if ($this->checked) { - $this->setValue($this->getCheckedValue()); - } else { - $this->setValue($this->getUncheckedValue()); - } - return $this; - } - - /** - * Get checked flag - * - * @return bool - */ - public function isChecked() - { - return $this->checked; - } -} - diff --git a/lib/Zend/Dojo/Form/Element/ComboBox.php b/lib/Zend/Dojo/Form/Element/ComboBox.php deleted file mode 100644 index 2e3bad4f8a1..00000000000 --- a/lib/Zend/Dojo/Form/Element/ComboBox.php +++ /dev/null @@ -1,186 +0,0 @@ -hasDijitParam('store')) { - $this->dijitParams['store'] = array(); - } - return $this->dijitParams['store']; - } - - /** - * Set datastore identifier - * - * @param string $identifier - * @return Zend_Dojo_Form_Element_ComboBox - */ - public function setStoreId($identifier) - { - $store = $this->getStoreInfo(); - $store['store'] = (string) $identifier; - $this->setDijitParam('store', $store); - return $this; - } - - /** - * Get datastore identifier - * - * @return string|null - */ - public function getStoreId() - { - $store = $this->getStoreInfo(); - if (array_key_exists('store', $store)) { - return $store['store']; - } - return null; - } - - /** - * Set datastore dijit type - * - * @param string $dojoType - * @return Zend_Dojo_Form_Element_ComboBox - */ - public function setStoreType($dojoType) - { - $store = $this->getStoreInfo(); - $store['type'] = (string) $dojoType; - $this->setDijitParam('store', $store); - return $this; - } - - /** - * Get datastore dijit type - * - * @return string|null - */ - public function getStoreType() - { - $store = $this->getStoreInfo(); - if (array_key_exists('type', $store)) { - return $store['type']; - } - return null; - } - - /** - * Set datastore parameters - * - * @param array $params - * @return Zend_Dojo_Form_Element_ComboBox - */ - public function setStoreParams(array $params) - { - $store = $this->getStoreInfo(); - $store['params'] = $params; - $this->setDijitParam('store', $store); - return $this; - } - - /** - * Get datastore params - * - * @return array - */ - public function getStoreParams() - { - $store = $this->getStoreInfo(); - if (array_key_exists('params', $store)) { - return $store['params']; - } - return array(); - } - - /** - * Set autocomplete flag - * - * @param bool $flag - * @return Zend_Dojo_Form_Element_ComboBox - */ - public function setAutocomplete($flag) - { - $this->setDijitParam('autocomplete', (bool) $flag); - return $this; - } - - /** - * Get autocomplete flag - * - * @return bool - */ - public function getAutocomplete() - { - if (!$this->hasDijitParam('autocomplete')) { - return false; - } - return $this->getDijitParam('autocomplete'); - } - - /** - * Is the value valid? - * - * @param string $value - * @param mixed $context - * @return bool - */ - public function isValid($value, $context = null) - { - $storeInfo = $this->getStoreInfo(); - if (!empty($storeInfo)) { - $this->setRegisterInArrayValidator(false); - } - return parent::isValid($value, $context); - } -} diff --git a/lib/Zend/Dojo/Form/Element/CurrencyTextBox.php b/lib/Zend/Dojo/Form/Element/CurrencyTextBox.php deleted file mode 100644 index 97e48b8cb6d..00000000000 --- a/lib/Zend/Dojo/Form/Element/CurrencyTextBox.php +++ /dev/null @@ -1,120 +0,0 @@ -setDijitParam('currency', (string) $currency); - return $this; - } - - /** - * Retrieve currency - * - * @return string|null - */ - public function getCurrency() - { - return $this->getDijitParam('currency'); - } - - /** - * Set currency symbol - * - * Casts to string, uppercases, and trims to three characters. - * - * @param string $symbol - * @return Zend_Dojo_Form_Element_CurrencyTextBox - */ - public function setSymbol($symbol) - { - $symbol = strtoupper((string) $symbol); - $length = strlen($symbol); - if (3 > $length) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception('Invalid symbol provided; please provide ISO 4217 alphabetic currency code'); - } - if (3 < $length) { - $symbol = substr($symbol, 0, 3); - } - - $this->setConstraint('symbol', $symbol); - return $this; - } - - /** - * Retrieve symbol - * - * @return string|null - */ - public function getSymbol() - { - return $this->getConstraint('symbol'); - } - - /** - * Set whether currency is fractional - * - * @param bool $flag - * @return Zend_Dojo_Form_Element_CurrencyTextBox - */ - public function setFractional($flag) - { - $this->setConstraint('fractional', (bool) $flag); - return $this; - } - - /** - * Get whether or not to present fractional values - * - * @return bool - */ - public function getFractional() - { - return ('true' == $this->getConstraint('fractional')); - } -} diff --git a/lib/Zend/Dojo/Form/Element/DateTextBox.php b/lib/Zend/Dojo/Form/Element/DateTextBox.php deleted file mode 100644 index 1e4f572fb07..00000000000 --- a/lib/Zend/Dojo/Form/Element/DateTextBox.php +++ /dev/null @@ -1,214 +0,0 @@ -setConstraint('am,pm', (bool) $flag); - return $this; - } - - /** - * Retrieve am,pm flag - * - * @return bool - */ - public function getAmPm() - { - if (!$this->hasConstraint('am,pm')) { - return false; - } - return ('true' ==$this->getConstraint('am,pm')); - } - - /** - * Set strict flag - * - * @param bool $strict - * @return Zend_Dojo_Form_Element_DateTextBox - */ - public function setStrict($flag) - { - $this->setConstraint('strict', (bool) $flag); - return $this; - } - - /** - * Retrieve strict flag - * - * @return bool - */ - public function getStrict() - { - if (!$this->hasConstraint('strict')) { - return false; - } - return ('true' == $this->getConstraint('strict')); - } - - /** - * Set locale - * - * @param string $locale - * @return Zend_Dojo_Form_Element_DateTextBox - */ - public function setLocale($locale) - { - $this->setConstraint('locale', (string) $locale); - return $this; - } - - /** - * Retrieve locale - * - * @return string|null - */ - public function getLocale() - { - return $this->getConstraint('locale'); - } - - /** - * Set date format pattern - * - * @param string $pattern - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setDatePattern($pattern) - { - $this->setConstraint('datePattern', (string) $pattern); - return $this; - } - - /** - * Retrieve date format pattern - * - * @return string|null - */ - public function getDatePattern() - { - return $this->getConstraint('datePattern'); - } - - /** - * Set numeric format formatLength - * - * @see $_allowedFormatTypes - * @param string $formatLength - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setFormatLength($formatLength) - { - $formatLength = strtolower($formatLength); - if (!in_array($formatLength, $this->_allowedFormatTypes)) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception(sprintf('Invalid formatLength "%s" specified', $formatLength)); - } - - $this->setConstraint('formatLength', $formatLength); - return $this; - } - - /** - * Retrieve formatLength - * - * @return string|null - */ - public function getFormatLength() - { - return $this->getConstraint('formatLength'); - } - - /** - * Set numeric format Selector - * - * @see $_allowedSelectorTypes - * @param string $selector - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setSelector($selector) - { - $selector = strtolower($selector); - if (!in_array($selector, $this->_allowedSelectorTypes)) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception(sprintf('Invalid Selector "%s" specified', $selector)); - } - - $this->setConstraint('selector', $selector); - return $this; - } - - /** - * Retrieve selector - * - * @return string|null - */ - public function getSelector() - { - return $this->getConstraint('selector'); - } -} diff --git a/lib/Zend/Dojo/Form/Element/Dijit.php b/lib/Zend/Dojo/Form/Element/Dijit.php deleted file mode 100644 index 55be94429b9..00000000000 --- a/lib/Zend/Dojo/Form/Element/Dijit.php +++ /dev/null @@ -1,189 +0,0 @@ -addPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator'); - parent::__construct($spec, $options); - } - - /** - * Set a dijit parameter - * - * @param string $key - * @param mixed $value - * @return Zend_Dojo_Form_Element_Dijit - */ - public function setDijitParam($key, $value) - { - $key = (string) $key; - $this->dijitParams[$key] = $value; - return $this; - } - - /** - * Set multiple dijit params at once - * - * @param array $params - * @return Zend_Dojo_Form_Element_Dijit - */ - public function setDijitParams(array $params) - { - $this->dijitParams = array_merge($this->dijitParams, $params); - return $this; - } - - /** - * Does the given dijit parameter exist? - * - * @param string $key - * @return bool - */ - public function hasDijitParam($key) - { - return array_key_exists($key, $this->dijitParams); - } - - /** - * Get a single dijit parameter - * - * @param string $key - * @return mixed - */ - public function getDijitParam($key) - { - $key = (string) $key; - if ($this->hasDijitParam($key)) { - return $this->dijitParams[$key]; - } - return null; - } - - /** - * Retrieve all dijit parameters - * - * @return array - */ - public function getDijitParams() - { - return $this->dijitParams; - } - - /** - * Remove a single dijit parameter - * - * @param string $key - * @return Zend_Dojo_Form_Element_Dijit - */ - public function removeDijitParam($key) - { - $key = (string) $key; - if (array_key_exists($key, $this->dijitParams)) { - unset($this->dijitParams[$key]); - } - return $this; - } - - /** - * Clear all dijit parameters - * - * @return Zend_Dojo_Form_Element_Dijit - */ - public function clearDijitParams() - { - $this->dijitParams = array(); - return $this; - } - - /** - * Load default decorators - * - * @return void - */ - public function loadDefaultDecorators() - { - if ($this->loadDefaultDecoratorsIsDisabled()) { - return; - } - - $decorators = $this->getDecorators(); - if (empty($decorators)) { - $this->addDecorator('DijitElement') - ->addDecorator('Errors') - ->addDecorator('Description', array('tag' => 'p', 'class' => 'description')) - ->addDecorator('HtmlTag', array('tag' => 'dd')) - ->addDecorator('Label', array('tag' => 'dt')); - } - } - - /** - * Set the view object - * - * Ensures that the view object has the dojo view helper path set. - * - * @param Zend_View_Interface $view - * @return Zend_Dojo_Form_Element_Dijit - */ - public function setView(Zend_View_Interface $view = null) - { - if (null !== $view) { - if (false === $view->getPluginLoader('helper')->getPaths('Zend_Dojo_View_Helper')) { - $view->addHelperPath('Zend/Dojo/View/Helper', 'Zend_Dojo_View_Helper'); - } - } - return parent::setView($view); - } -} diff --git a/lib/Zend/Dojo/Form/Element/DijitMulti.php b/lib/Zend/Dojo/Form/Element/DijitMulti.php deleted file mode 100644 index fb93d81436a..00000000000 --- a/lib/Zend/Dojo/Form/Element/DijitMulti.php +++ /dev/null @@ -1,303 +0,0 @@ -'. - * @var string - */ - protected $_separator = '
'; - - /** - * Which values are translated already? - * @var array - */ - protected $_translated = array(); - - /** - * Retrieve separator - * - * @return mixed - */ - public function getSeparator() - { - return $this->_separator; - } - - /** - * Set separator - * - * @param mixed $separator - * @return self - */ - public function setSeparator($separator) - { - $this->_separator = $separator; - return $this; - } - - /** - * Retrieve options array - * - * @return array - */ - protected function _getMultiOptions() - { - if (null === $this->options || !is_array($this->options)) { - $this->options = array(); - } - - return $this->options; - } - - /** - * Add an option - * - * @param string $option - * @param string $value - * @return Zend_Form_Element_Multi - */ - public function addMultiOption($option, $value = '') - { - $option = (string) $option; - $this->_getMultiOptions(); - if (!$this->_translateOption($option, $value)) { - $this->options[$option] = $value; - } - - return $this; - } - - /** - * Add many options at once - * - * @param array $options - * @return Zend_Form_Element_Multi - */ - public function addMultiOptions(array $options) - { - foreach ($options as $option => $value) { - if (is_array($value) - && array_key_exists('key', $value) - && array_key_exists('value', $value) - ) { - $this->addMultiOption($value['key'], $value['value']); - } else { - $this->addMultiOption($option, $value); - } - } - return $this; - } - - /** - * Set all options at once (overwrites) - * - * @param array $options - * @return Zend_Form_Element_Multi - */ - public function setMultiOptions(array $options) - { - $this->clearMultiOptions(); - return $this->addMultiOptions($options); - } - - /** - * Retrieve single multi option - * - * @param string $option - * @return mixed - */ - public function getMultiOption($option) - { - $option = (string) $option; - $this->_getMultiOptions(); - if (isset($this->options[$option])) { - $this->_translateOption($option, $this->options[$option]); - return $this->options[$option]; - } - - return null; - } - - /** - * Retrieve options - * - * @return array - */ - public function getMultiOptions() - { - $this->_getMultiOptions(); - foreach ($this->options as $option => $value) { - $this->_translateOption($option, $value); - } - return $this->options; - } - - /** - * Remove a single multi option - * - * @param string $option - * @return bool - */ - public function removeMultiOption($option) - { - $option = (string) $option; - $this->_getMultiOptions(); - if (isset($this->options[$option])) { - unset($this->options[$option]); - if (isset($this->_translated[$option])) { - unset($this->_translated[$option]); - } - return true; - } - - return false; - } - - /** - * Clear all options - * - * @return Zend_Form_Element_Multi - */ - public function clearMultiOptions() - { - $this->options = array(); - $this->_translated = array(); - return $this; - } - - /** - * Set flag indicating whether or not to auto-register inArray validator - * - * @param bool $flag - * @return Zend_Form_Element_Multi - */ - public function setRegisterInArrayValidator($flag) - { - $this->_registerInArrayValidator = (bool) $flag; - return $this; - } - - /** - * Get status of auto-register inArray validator flag - * - * @return bool - */ - public function registerInArrayValidator() - { - return $this->_registerInArrayValidator; - } - - /** - * Is the value provided valid? - * - * Autoregisters InArray validator if necessary. - * - * @param string $value - * @param mixed $context - * @return bool - */ - public function isValid($value, $context = null) - { - if ($this->registerInArrayValidator()) { - if (!$this->getValidator('InArray')) { - $options = $this->getMultiOptions(); - $this->addValidator( - 'InArray', - true, - array(array_keys($options)) - ); - } - } - return parent::isValid($value, $context); - } - - /** - * Translate an option - * - * @param string $option - * @param string $value - * @return bool - */ - protected function _translateOption($option, $value) - { - if (!isset($this->_translated[$option])) { - $this->options[$option] = $this->_translateValue($value); - if ($this->options[$option] === $value) { - return false; - } - $this->_translated[$option] = true; - return true; - } - - return false; - } - - /** - * Translate a value - * - * @param array|string $value - * @return array|string - */ - protected function _translateValue($value) - { - if (is_array($value)) { - foreach ($value as $key => $val) { - $value[$key] = $this->_translateValue($val); - } - return $value; - } else { - if (null !== ($translator = $this->getTranslator())) { - return $translator->translate($value); - } - - return $value; - } - } -} diff --git a/lib/Zend/Dojo/Form/Element/Editor.php b/lib/Zend/Dojo/Form/Element/Editor.php deleted file mode 100644 index b49834924a4..00000000000 --- a/lib/Zend/Dojo/Form/Element/Editor.php +++ /dev/null @@ -1,697 +0,0 @@ -getCaptureEvents(); - if (in_array($event, $captureEvents)) { - return $this; - } - - $captureEvents[] = (string) $event; - $this->setDijitParam('captureEvents', $captureEvents); - return $this; - } - - /** - * Add multiple capture events - * - * @param array $events - * @return Zend_Dojo_Form_Element_Editor - */ - public function addCaptureEvents(array $events) - { - foreach ($events as $event) { - $this->addCaptureEvent($event); - } - return $this; - } - - /** - * Overwrite many capture events at once - * - * @param array $events - * @return Zend_Dojo_Form_Element_Editor - */ - public function setCaptureEvents(array $events) - { - $this->clearCaptureEvents(); - $this->addCaptureEvents($events); - return $this; - } - - /** - * Get all capture events - * - * @return array - */ - public function getCaptureEvents() - { - if (!$this->hasDijitParam('captureEvents')) { - return array(); - } - return $this->getDijitParam('captureEvents'); - } - - /** - * Is a given capture event registered? - * - * @param string $event - * @return bool - */ - public function hasCaptureEvent($event) - { - $captureEvents = $this->getCaptureEvents(); - return in_array((string) $event, $captureEvents); - } - - /** - * Remove a given capture event - * - * @param string $event - * @return Zend_Dojo_Form_Element_Editor - */ - public function removeCaptureEvent($event) - { - $event = (string) $event; - $captureEvents = $this->getCaptureEvents(); - if (false === ($index = array_search($event, $captureEvents))) { - return $this; - } - unset($captureEvents[$index]); - $this->setDijitParam('captureEvents', $captureEvents); - return $this; - } - - /** - * Clear all capture events - * - * @return Zend_Dojo_Form_Element_Editor - */ - public function clearCaptureEvents() - { - return $this->removeDijitParam('captureEvents'); - } - - /** - * Add a single event to the dijit - * - * @param string $event - * @return Zend_Dojo_Form_Element_Editor - */ - public function addEvent($event) - { - $event = (string) $event; - $events = $this->getEvents(); - if (in_array($event, $events)) { - return $this; - } - - $events[] = (string) $event; - $this->setDijitParam('events', $events); - return $this; - } - - /** - * Add multiple events - * - * @param array $events - * @return Zend_Dojo_Form_Element_Editor - */ - public function addEvents(array $events) - { - foreach ($events as $event) { - $this->addEvent($event); - } - return $this; - } - - /** - * Overwrite many events at once - * - * @param array $events - * @return Zend_Dojo_Form_Element_Editor - */ - public function setEvents(array $events) - { - $this->clearEvents(); - $this->addEvents($events); - return $this; - } - - /** - * Get all events - * - * @return array - */ - public function getEvents() - { - if (!$this->hasDijitParam('events')) { - return array(); - } - return $this->getDijitParam('events'); - } - - /** - * Is a given event registered? - * - * @param string $event - * @return bool - */ - public function hasEvent($event) - { - $events = $this->getEvents(); - return in_array((string) $event, $events); - } - - /** - * Remove a given event - * - * @param string $event - * @return Zend_Dojo_Form_Element_Editor - */ - public function removeEvent($event) - { - $events = $this->getEvents(); - if (false === ($index = array_search($event, $events))) { - return $this; - } - unset($events[$index]); - $this->setDijitParam('events', $events); - return $this; - } - - /** - * Clear all events - * - * @return Zend_Dojo_Form_Element_Editor - */ - public function clearEvents() - { - return $this->removeDijitParam('events'); - } - - /** - * Add a single editor plugin - * - * @param string $plugin - * @return Zend_Dojo_Form_Element_Editor - */ - public function addPlugin($plugin) - { - $plugin = (string) $plugin; - $plugins = $this->getPlugins(); - if (in_array($plugin, $plugins) && $plugin !== '|') { - return $this; - } - - $plugins[] = (string) $plugin; - $this->setDijitParam('plugins', $plugins); - return $this; - } - - /** - * Add multiple plugins - * - * @param array $plugins - * @return Zend_Dojo_Form_Element_Editor - */ - public function addPlugins(array $plugins) - { - foreach ($plugins as $plugin) { - $this->addPlugin($plugin); - } - return $this; - } - - /** - * Overwrite many plugins at once - * - * @param array $plugins - * @return Zend_Dojo_Form_Element_Editor - */ - public function setPlugins(array $plugins) - { - $this->clearPlugins(); - $this->addPlugins($plugins); - return $this; - } - - /** - * Get all plugins - * - * @return array - */ - public function getPlugins() - { - if (!$this->hasDijitParam('plugins')) { - return array(); - } - return $this->getDijitParam('plugins'); - } - - /** - * Is a given plugin registered? - * - * @param string $plugin - * @return bool - */ - public function hasPlugin($plugin) - { - $plugins = $this->getPlugins(); - return in_array((string) $plugin, $plugins); - } - - /** - * Remove a given plugin - * - * @param string $plugin - * @return Zend_Dojo_Form_Element_Editor - */ - public function removePlugin($plugin) - { - $plugins = $this->getPlugins(); - if (false === ($index = array_search($plugin, $plugins))) { - return $this; - } - unset($plugins[$index]); - $this->setDijitParam('plugins', $plugins); - return $this; - } - - /** - * Clear all plugins - * - * @return Zend_Dojo_Form_Element_Editor - */ - public function clearPlugins() - { - return $this->removeDijitParam('plugins'); - } - - /** - * Set edit action interval - * - * @param int $interval - * @return Zend_Dojo_Form_Element_Editor - */ - public function setEditActionInterval($interval) - { - return $this->setDijitParam('editActionInterval', (int) $interval); - } - - /** - * Get edit action interval; defaults to 3 - * - * @return int - */ - public function getEditActionInterval() - { - if (!$this->hasDijitParam('editActionInterval')) { - $this->setEditActionInterval(3); - } - return $this->getDijitParam('editActionInterval'); - } - - /** - * Set focus on load flag - * - * @param bool $flag - * @return Zend_Dojo_Form_Element_Editor - */ - public function setFocusOnLoad($flag) - { - return $this->setDijitParam('focusOnLoad', (bool) $flag); - } - - /** - * Retrieve focus on load flag - * - * @return bool - */ - public function getFocusOnLoad() - { - if (!$this->hasDijitParam('focusOnLoad')) { - return false; - } - return $this->getDijitParam('focusOnLoad'); - } - - /** - * Set editor height - * - * @param string|int $height - * @return Zend_Dojo_Form_Element_Editor - */ - public function setHeight($height) - { - if (!preg_match('/^\d+(em|px|%)?$/i', $height)) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception('Invalid height provided; must be integer or CSS measurement'); - } - if (!preg_match('/(em|px|%)$/', $height)) { - $height .= 'px'; - } - return $this->setDijitParam('height', $height); - } - - /** - * Retrieve height - * - * @return string - */ - public function getHeight() - { - if (!$this->hasDijitParam('height')) { - return '300px'; - } - return $this->getDijitParam('height'); - } - - /** - * Set whether or not to inherit parent's width - * - * @param bool $flag - * @return Zend_Dojo_Form_Element_Editor - */ - public function setInheritWidth($flag) - { - return $this->setDijitParam('inheritWidth', (bool) $flag); - } - - /** - * Whether or not to inherit the parent's width - * - * @return bool - */ - public function getInheritWidth() - { - if (!$this->hasDijitParam('inheritWidth')) { - return false; - } - return $this->getDijitParam('inheritWidth'); - } - - /** - * Set minimum height of editor - * - * @param string|int $minHeight - * @return Zend_Dojo_Form_Element_Editor - */ - public function setMinHeight($minHeight) - { - if (!preg_match('/^\d+(em|px|%)?$/i', $minHeight)) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception('Invalid minHeight provided; must be integer or CSS measurement'); - } - if (!preg_match('/(em|px|%)$/', $minHeight)) { - $minHeight .= 'em'; - } - return $this->setDijitParam('minHeight', $minHeight); - } - - /** - * Get minimum height of editor - * - * @return string - */ - public function getMinHeight() - { - if (!$this->hasDijitParam('minHeight')) { - return '1em'; - } - return $this->getDijitParam('minHeight'); - } - - /** - * Add a custom stylesheet - * - * @param string $styleSheet - * @return Zend_Dojo_Form_Element_Editor - */ - public function addStyleSheet($styleSheet) - { - $stylesheets = $this->getStyleSheets(); - if (strstr($stylesheets, ';')) { - $stylesheets = explode(';', $stylesheets); - } elseif (!empty($stylesheets)) { - $stylesheets = (array) $stylesheets; - } else { - $stylesheets = array(); - } - if (!in_array($styleSheet, $stylesheets)) { - $stylesheets[] = (string) $styleSheet; - } - return $this->setDijitParam('styleSheets', implode(';', $stylesheets)); - } - - /** - * Add multiple custom stylesheets - * - * @param array $styleSheets - * @return Zend_Dojo_Form_Element_Editor - */ - public function addStyleSheets(array $styleSheets) - { - foreach ($styleSheets as $styleSheet) { - $this->addStyleSheet($styleSheet); - } - return $this; - } - - /** - * Overwrite all stylesheets - * - * @param array $styleSheets - * @return Zend_Dojo_Form_Element_Editor - */ - public function setStyleSheets(array $styleSheets) - { - $this->clearStyleSheets(); - return $this->addStyleSheets($styleSheets); - } - - /** - * Get all stylesheets - * - * @return string - */ - public function getStyleSheets() - { - if (!$this->hasDijitParam('styleSheets')) { - return ''; - } - return $this->getDijitParam('styleSheets'); - } - - /** - * Is a given stylesheet registered? - * - * @param string $styleSheet - * @return bool - */ - public function hasStyleSheet($styleSheet) - { - $styleSheets = $this->getStyleSheets(); - $styleSheets = explode(';', $styleSheets); - return in_array($styleSheet, $styleSheets); - } - - /** - * Remove a single stylesheet - * - * @param string $styleSheet - * @return Zend_Dojo_Form_Element_Editor - */ - public function removeStyleSheet($styleSheet) - { - $styleSheets = $this->getStyleSheets(); - $styleSheets = explode(';', $styleSheets); - if (false !== ($index = array_search($styleSheet, $styleSheets))) { - unset($styleSheets[$index]); - $this->setDijitParam('styleSheets', implode(';', $styleSheets)); - } - return $this; - } - - /** - * Clear all stylesheets - * - * @return Zend_Dojo_Form_Element_Editor - */ - public function clearStyleSheets() - { - if ($this->hasDijitParam('styleSheets')) { - $this->removeDijitParam('styleSheets'); - } - return $this; - } - - /** - * Set update interval - * - * @param int $interval - * @return Zend_Dojo_Form_Element_Editor - */ - public function setUpdateInterval($interval) - { - return $this->setDijitParam('updateInterval', (int) $interval); - } - - /** - * Get update interval - * - * @return int - */ - public function getUpdateInterval() - { - if (!$this->hasDijitParam('updateInterval')) { - return 200; - } - return $this->getDijitParam('updateInterval'); - } - - /** - * Add a single editor extra plugin. - * - * @param string $plugin - * @return Zend_Dojo_Form_Element_Editor - */ - public function addExtraPlugin($plugin) - { - $plugin = (string) $plugin; - $extraPlugins = $this->getExtraPlugins(); - if (in_array($plugin, $extraPlugins)) { - return $this; - } - - $extraPlugins[] = (string) $plugin; - $this->setDijitParam('extraPlugins', $extraPlugins); - return $this; - } - - /** - * Add multiple extra plugins. - * - * @param array $extraPlugins - * @return Zend_Dojo_Form_Element_Editor - */ - public function addExtraPlugins(array $plugins) - { - foreach ($plugins as $plugin) { - $this->addExtraPlugin($plugin); - } - return $this; - } - - /** - * Overwrite many extra plugins at once. - * - * @param array $plugins - * @return Zend_Dojo_Form_Element_Editor - */ - public function setExtraPlugins(array $plugins) - { - $this->clearExtraPlugins(); - $this->addExtraPlugins($plugins); - return $this; - } - - /** - * Get all extra plugins. - * - * @return array - */ - public function getExtraPlugins() - { - if (!$this->hasDijitParam('extraPlugins')) { - return array(); - } - return $this->getDijitParam('extraPlugins'); - } - - /** - * Is a given extra plugin registered? - * - * @param string $plugin - * @return bool - */ - public function hasExtraPlugin($plugin) - { - $extraPlugins = $this->getExtraPlugins(); - return in_array((string) $plugin, $extraPlugins); - } - - /** - * Remove a given extra plugin. - * - * @param string $plugin - * @return Zend_Dojo_Form_Element_Editor - */ - public function removeExtraPlugin($plugin) - { - $extraPlugins = $this->getExtraPlugins(); - if (false === ($index = array_search($plugin, $extraPlugins))) { - return $this; - } - unset($extraPlugins[$index]); - $this->setDijitParam('extraPlugins', $extraPlugins); - return $this; - } - - /** - * Clear all extra plugins. - * - * @return Zend_Dojo_Form_Element_Editor - */ - public function clearExtraPlugins() - { - return $this->removeDijitParam('extraPlugins'); - } -} diff --git a/lib/Zend/Dojo/Form/Element/FilteringSelect.php b/lib/Zend/Dojo/Form/Element/FilteringSelect.php deleted file mode 100644 index c882fd5c0d9..00000000000 --- a/lib/Zend/Dojo/Form/Element/FilteringSelect.php +++ /dev/null @@ -1,48 +0,0 @@ -hasDijitParam('topDecoration')) { - return $this->getDijitParam('topDecoration'); - } - return array(); - } - - /** - * Set dijit to use with top decoration - * - * @param mixed $dijit - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setTopDecorationDijit($dijit) - { - $decoration = $this->getTopDecoration(); - $decoration['dijit'] = (string) $dijit; - $this->setDijitParam('topDecoration', $decoration); - return $this; - } - - /** - * Set container to use with top decoration - * - * @param mixed $container - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setTopDecorationContainer($container) - { - $decoration = $this->getTopDecoration(); - $decoration['container'] = (string) $container; - $this->setDijitParam('topDecoration', $decoration); - return $this; - } - - /** - * Set labels to use with top decoration - * - * @param array $labels - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setTopDecorationLabels(array $labels) - { - $decoration = $this->getTopDecoration(); - $decoration['labels'] = array_values($labels); - $this->setDijitParam('topDecoration', $decoration); - return $this; - } - - /** - * Set params to use with top decoration - * - * @param array $params - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setTopDecorationParams(array $params) - { - $decoration = $this->getTopDecoration(); - $decoration['params'] = $params; - $this->setDijitParam('topDecoration', $decoration); - return $this; - } - - /** - * Set attribs to use with top decoration - * - * @param array $attribs - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setTopDecorationAttribs(array $attribs) - { - $decoration = $this->getTopDecoration(); - $decoration['attribs'] = $attribs; - $this->setDijitParam('topDecoration', $decoration); - return $this; - } - - /** - * Get bottom decoration data - * - * @return array - */ - public function getBottomDecoration() - { - if ($this->hasDijitParam('bottomDecoration')) { - return $this->getDijitParam('bottomDecoration'); - } - return array(); - } - - /** - * Set dijit to use with bottom decoration - * - * @param mixed $dijit - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setBottomDecorationDijit($dijit) - { - $decoration = $this->getBottomDecoration(); - $decoration['dijit'] = (string) $dijit; - $this->setDijitParam('bottomDecoration', $decoration); - return $this; - } - - /** - * Set container to use with bottom decoration - * - * @param mixed $container - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setBottomDecorationContainer($container) - { - $decoration = $this->getBottomDecoration(); - $decoration['container'] = (string) $container; - $this->setDijitParam('bottomDecoration', $decoration); - return $this; - } - - /** - * Set labels to use with bottom decoration - * - * @param array $labels - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setBottomDecorationLabels(array $labels) - { - $decoration = $this->getBottomDecoration(); - $decoration['labels'] = array_values($labels); - $this->setDijitParam('bottomDecoration', $decoration); - return $this; - } - - /** - * Set params to use with bottom decoration - * - * @param array $params - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setBottomDecorationParams(array $params) - { - $decoration = $this->getBottomDecoration(); - $decoration['params'] = $params; - $this->setDijitParam('bottomDecoration', $decoration); - return $this; - } - - /** - * Set attribs to use with bottom decoration - * - * @param array $attribs - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setBottomDecorationAttribs(array $attribs) - { - $decoration = $this->getBottomDecoration(); - $decoration['attribs'] = $attribs; - $this->setDijitParam('bottomDecoration', $decoration); - return $this; - } -} diff --git a/lib/Zend/Dojo/Form/Element/NumberSpinner.php b/lib/Zend/Dojo/Form/Element/NumberSpinner.php deleted file mode 100644 index 443352dcf1e..00000000000 --- a/lib/Zend/Dojo/Form/Element/NumberSpinner.php +++ /dev/null @@ -1,245 +0,0 @@ -setDijitParam('defaultTimeout', (int) $timeout); - return $this; - } - - /** - * Retrieve defaultTimeout - * - * @return int|null - */ - public function getDefaultTimeout() - { - return $this->getDijitParam('defaultTimeout'); - } - - /** - * Set timeoutChangeRate - * - * @param int $rate - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setTimeoutChangeRate($rate) - { - $this->setDijitParam('timeoutChangeRate', (int) $rate); - return $this; - } - - /** - * Retrieve timeoutChangeRate - * - * @return int|null - */ - public function getTimeoutChangeRate() - { - return $this->getDijitParam('timeoutChangeRate'); - } - - /** - * Set largeDelta - * - * @param int $delta - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setLargeDelta($delta) - { - $this->setDijitParam('largeDelta', (float) $delta); - return $this; - } - - /** - * Retrieve largeDelta - * - * @return int|null - */ - public function getLargeDelta() - { - return $this->getDijitParam('largeDelta'); - } - - /** - * Set smallDelta - * - * @param int $delta - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setSmallDelta($delta) - { - $this->setDijitParam('smallDelta', (float) $delta); - return $this; - } - - /** - * Retrieve smallDelta - * - * @return int|null - */ - public function getSmallDelta() - { - return $this->getDijitParam('smallDelta'); - } - - /** - * Set intermediateChanges flag - * - * @param bool $flag - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setIntermediateChanges($flag) - { - $this->setDijitParam('intermediateChanges', (bool) $flag); - return $this; - } - - /** - * Retrieve intermediateChanges flag - * - * @return bool - */ - public function getIntermediateChanges() - { - if (!$this->hasDijitParam('intermediateChanges')) { - return false; - } - return $this->getDijitParam('intermediateChanges'); - } - - /** - * Set rangeMessage - * - * @param string $message - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setRangeMessage($message) - { - $this->setDijitParam('rangeMessage', (string) $message); - return $this; - } - - /** - * Retrieve rangeMessage - * - * @return string|null - */ - public function getRangeMessage() - { - return $this->getDijitParam('rangeMessage'); - } - - /** - * Set minimum value - * - * @param int $value - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setMin($value) - { - $constraints = array(); - if ($this->hasDijitParam('constraints')) { - $constraints = $this->getDijitParam('constraints'); - } - $constraints['min'] = (float) $value; - $this->setDijitParam('constraints', $constraints); - return $this; - } - - /** - * Get minimum value - * - * @return null|int - */ - public function getMin() - { - if (!$this->hasDijitParam('constraints')) { - return null; - } - $constraints = $this->getDijitParam('constraints'); - if (!array_key_exists('min', $constraints)) { - return null; - } - return $constraints['min']; - } - - /** - * Set maximum value - * - * @param int $value - * @return Zend_Dojo_Form_Element_NumberSpinner - */ - public function setMax($value) - { - $constraints = array(); - if ($this->hasDijitParam('constraints')) { - $constraints = $this->getDijitParam('constraints'); - } - $constraints['max'] = (float) $value; - $this->setDijitParam('constraints', $constraints); - return $this; - } - - /** - * Get maximum value - * - * @return null|int - */ - public function getMax() - { - if (!$this->hasDijitParam('constraints')) { - return null; - } - $constraints = $this->getDijitParam('constraints'); - if (!array_key_exists('max', $constraints)) { - return null; - } - return $constraints['max']; - } -} diff --git a/lib/Zend/Dojo/Form/Element/NumberTextBox.php b/lib/Zend/Dojo/Form/Element/NumberTextBox.php deleted file mode 100644 index c2e09e1457a..00000000000 --- a/lib/Zend/Dojo/Form/Element/NumberTextBox.php +++ /dev/null @@ -1,173 +0,0 @@ -setConstraint('locale', (string) $locale); - return $this; - } - - /** - * Retrieve locale - * - * @return string|null - */ - public function getLocale() - { - return $this->getConstraint('locale'); - } - - /** - * Set numeric format pattern - * - * @param string $pattern - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setPattern($pattern) - { - $this->setConstraint('pattern', (string) $pattern); - return $this; - } - - /** - * Retrieve numeric format pattern - * - * @return string|null - */ - public function getPattern() - { - return $this->getConstraint('pattern'); - } - - /** - * Set numeric format type - * - * @see $_allowedTypes - * @param string $type - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setType($type) - { - $type = strtolower($type); - if (!in_array($type, $this->_allowedTypes)) { - #require_once 'Zend/Form/Element/Exception.php'; - throw new Zend_Form_Element_Exception(sprintf('Invalid numeric type "%s" specified', $type)); - } - - $this->setConstraint('type', $type); - return $this; - } - - /** - * Retrieve type - * - * @return string|null - */ - public function getType() - { - return $this->getConstraint('type'); - } - - /** - * Set decimal places - * - * @param int $places - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setPlaces($places) - { - $this->setConstraint('places', (int) $places); - return $this; - } - - /** - * Retrieve decimal places - * - * @return int|null - */ - public function getPlaces() - { - return $this->getConstraint('places'); - } - - /** - * Set strict flag - * - * @param bool $strict - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setStrict($flag) - { - $this->setConstraint('strict', (bool) $flag); - return $this; - } - - /** - * Retrieve strict flag - * - * @return bool - */ - public function getStrict() - { - if (!$this->hasConstraint('strict')) { - return false; - } - return ('true' == $this->getConstraint('strict')); - } -} diff --git a/lib/Zend/Dojo/Form/Element/PasswordTextBox.php b/lib/Zend/Dojo/Form/Element/PasswordTextBox.php deleted file mode 100644 index fa43e45b118..00000000000 --- a/lib/Zend/Dojo/Form/Element/PasswordTextBox.php +++ /dev/null @@ -1,42 +0,0 @@ -setDijitParam('clickSelect', (bool) $flag); - return $this; - } - - /** - * Retrieve clickSelect flag - * - * @return bool - */ - public function getClickSelect() - { - if (!$this->hasDijitParam('clickSelect')) { - return false; - } - return $this->getDijitParam('clickSelect'); - } - - /** - * Set intermediateChanges flag - * - * @param bool $intermediateChanges - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setIntermediateChanges($flag) - { - $this->setDijitParam('intermediateChanges', (bool) $flag); - return $this; - } - - /** - * Retrieve intermediateChanges flag - * - * @return bool - */ - public function getIntermediateChanges() - { - if (!$this->hasDijitParam('intermediateChanges')) { - return false; - } - return $this->getDijitParam('intermediateChanges'); - } - - /** - * Set showButtons flag - * - * @param bool $showButtons - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setShowButtons($flag) - { - $this->setDijitParam('showButtons', (bool) $flag); - return $this; - } - - /** - * Retrieve showButtons flag - * - * @return bool - */ - public function getShowButtons() - { - if (!$this->hasDijitParam('showButtons')) { - return false; - } - return $this->getDijitParam('showButtons'); - } - - /** - * Set discreteValues - * - * @param int $value - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setDiscreteValues($value) - { - $this->setDijitParam('discreteValues', (int) $value); - return $this; - } - - /** - * Retrieve discreteValues - * - * @return int|null - */ - public function getDiscreteValues() - { - return $this->getDijitParam('discreteValues'); - } - - /** - * Set maximum - * - * @param int $value - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setMaximum($value) - { - $this->setDijitParam('maximum', (int) $value); - return $this; - } - - /** - * Retrieve maximum - * - * @return int|null - */ - public function getMaximum() - { - return $this->getDijitParam('maximum'); - } - - /** - * Set minimum - * - * @param int $value - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setMinimum($value) - { - $this->setDijitParam('minimum', (int) $value); - return $this; - } - - /** - * Retrieve minimum - * - * @return int|null - */ - public function getMinimum() - { - return $this->getDijitParam('minimum'); - } - - /** - * Set pageIncrement - * - * @param int $value - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setPageIncrement($value) - { - $this->setDijitParam('pageIncrement', (int) $value); - return $this; - } - - /** - * Retrieve pageIncrement - * - * @return int|null - */ - public function getPageIncrement() - { - return $this->getDijitParam('pageIncrement'); - } -} diff --git a/lib/Zend/Dojo/Form/Element/SubmitButton.php b/lib/Zend/Dojo/Form/Element/SubmitButton.php deleted file mode 100644 index 76c526b63b9..00000000000 --- a/lib/Zend/Dojo/Form/Element/SubmitButton.php +++ /dev/null @@ -1,42 +0,0 @@ -setDijitParam('lowercase', (bool) $flag); - return $this; - } - - /** - * Retrieve lowercase flag - * - * @return bool - */ - public function getLowercase() - { - if (!$this->hasDijitParam('lowercase')) { - return false; - } - return $this->getDijitParam('lowercase'); - } - - /** - * Set propercase flag - * - * @param bool $propercase - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setPropercase($flag) - { - $this->setDijitParam('propercase', (bool) $flag); - return $this; - } - - /** - * Retrieve propercase flag - * - * @return bool - */ - public function getPropercase() - { - if (!$this->hasDijitParam('propercase')) { - return false; - } - return $this->getDijitParam('propercase'); - } - - /** - * Set uppercase flag - * - * @param bool $uppercase - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setUppercase($flag) - { - $this->setDijitParam('uppercase', (bool) $flag); - return $this; - } - - /** - * Retrieve uppercase flag - * - * @return bool - */ - public function getUppercase() - { - if (!$this->hasDijitParam('uppercase')) { - return false; - } - return $this->getDijitParam('uppercase'); - } - - /** - * Set trim flag - * - * @param bool $trim - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setTrim($flag) - { - $this->setDijitParam('trim', (bool) $flag); - return $this; - } - - /** - * Retrieve trim flag - * - * @return bool - */ - public function getTrim() - { - if (!$this->hasDijitParam('trim')) { - return false; - } - return $this->getDijitParam('trim'); - } - - /** - * Set maxLength - * - * @param int $length - * @return Zend_Dojo_Form_Element_TextBox - */ - public function setMaxLength($length) - { - $this->setDijitParam('maxLength', (int) $length); - return $this; - } - - /** - * Retrieve maxLength - * - * @return int|null - */ - public function getMaxLength() - { - return $this->getDijitParam('maxLength'); - } -} diff --git a/lib/Zend/Dojo/Form/Element/Textarea.php b/lib/Zend/Dojo/Form/Element/Textarea.php deleted file mode 100644 index 676777fba78..00000000000 --- a/lib/Zend/Dojo/Form/Element/Textarea.php +++ /dev/null @@ -1,42 +0,0 @@ -setConstraint('timePattern', (string) $pattern); - return $this; - } - - /** - * Retrieve time format pattern - * - * @return string|null - */ - public function getTimePattern() - { - return $this->getConstraint('timePattern'); - } - - /** - * Set clickableIncrement - * - * @param string $format - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setClickableIncrement($format) - { - $format = (string) $format; - $this->_validateIso8601($format); - $this->setConstraint('clickableIncrement', $format); - return $this; - } - - /** - * Retrieve clickableIncrement - * - * @return string|null - */ - public function getClickableIncrement() - { - return $this->getConstraint('clickableIncrement'); - } - - /** - * Set visibleIncrement - * - * @param string $format - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setVisibleIncrement($format) - { - $format = (string) $format; - $this->_validateIso8601($format); - $this->setConstraint('visibleIncrement', $format); - return $this; - } - - /** - * Retrieve visibleIncrement - * - * @return string|null - */ - public function getVisibleIncrement() - { - return $this->getConstraint('visibleIncrement'); - } - - /** - * Set visibleRange - * - * @param string $format - * @return Zend_Dojo_Form_Element_NumberTextBox - */ - public function setVisibleRange($format) - { - $format = (string) $format; - $this->_validateIso8601($format); - $this->setConstraint('visibleRange', $format); - return $this; - } - - /** - * Retrieve visibleRange - * - * @return string|null - */ - public function getVisibleRange() - { - return $this->getConstraint('visibleRange'); - } -} diff --git a/lib/Zend/Dojo/Form/Element/ValidationTextBox.php b/lib/Zend/Dojo/Form/Element/ValidationTextBox.php deleted file mode 100644 index 64b19094622..00000000000 --- a/lib/Zend/Dojo/Form/Element/ValidationTextBox.php +++ /dev/null @@ -1,220 +0,0 @@ -setDijitParam('invalidMessage', (string) $message); - return $this; - } - - /** - * Retrieve invalidMessage - * - * @return string|null - */ - public function getInvalidMessage() - { - return $this->getDijitParam('invalidMessage'); - } - - /** - * Set promptMessage - * - * @param string $message - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function setPromptMessage($message) - { - $this->setDijitParam('promptMessage', (string) $message); - return $this; - } - - /** - * Retrieve promptMessage - * - * @return string|null - */ - public function getPromptMessage() - { - return $this->getDijitParam('promptMessage'); - } - - /** - * Set regExp - * - * @param string $regexp - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function setRegExp($regexp) - { - $this->setDijitParam('regExp', (string) $regexp); - return $this; - } - - /** - * Retrieve regExp - * - * @return string|null - */ - public function getRegExp() - { - return $this->getDijitParam('regExp'); - } - - /** - * Set an individual constraint - * - * @param string $key - * @param mixed $value - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function setConstraint($key, $value) - { - $constraints = $this->getConstraints(); - $constraints[(string) $key] = $value; - $this->setConstraints($constraints); - return $this; - } - - /** - * Set validation constraints - * - * Refer to Dojo dijit.form.ValidationTextBox documentation for valid - * structure. - * - * @param array $constraints - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function setConstraints(array $constraints) - { - $tmp = $this->getConstraints(); - $constraints = array_merge($tmp, $constraints); - array_walk_recursive($constraints, array($this, '_castBoolToString')); - $this->setDijitParam('constraints', $constraints); - return $this; - } - - /** - * Is the given constraint set? - * - * @param string $key - * @return bool - */ - public function hasConstraint($key) - { - $constraints = $this->getConstraints(); - return array_key_exists((string)$key, $constraints); - } - - /** - * Get an individual constraint - * - * @param string $key - * @return mixed - */ - public function getConstraint($key) - { - $key = (string) $key; - if (!$this->hasConstraint($key)) { - return null; - } - return $this->dijitParams['constraints'][$key]; - } - - /** - * Get constraints - * - * @return array - */ - public function getConstraints() - { - if ($this->hasDijitParam('constraints')) { - return $this->getDijitParam('constraints'); - } - return array(); - } - - /** - * Remove a single constraint - * - * @param string $key - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function removeConstraint($key) - { - $key = (string) $key; - if ($this->hasConstraint($key)) { - unset($this->dijitParams['constraints'][$key]); - } - return $this; - } - - /** - * Clear all constraints - * - * @return Zend_Dojo_Form_Element_ValidationTextBox - */ - public function clearConstraints() - { - return $this->removeDijitParam('constraints'); - } - - /** - * Cast a boolean value to a string - * - * @param mixed $item - * @param string $key - * @return void - */ - protected function _castBoolToString(&$item, $key) - { - if (is_bool($item)) { - $item = ($item) ? 'true' : 'false'; - } - } -} diff --git a/lib/Zend/Dojo/Form/Element/VerticalSlider.php b/lib/Zend/Dojo/Form/Element/VerticalSlider.php deleted file mode 100644 index d6e29c9acf6..00000000000 --- a/lib/Zend/Dojo/Form/Element/VerticalSlider.php +++ /dev/null @@ -1,208 +0,0 @@ -hasDijitParam('leftDecoration')) { - return $this->getDijitParam('leftDecoration'); - } - return array(); - } - - /** - * Set dijit to use with left decoration - * - * @param mixed $dijit - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setLeftDecorationDijit($dijit) - { - $decoration = $this->getLeftDecoration(); - $decoration['dijit'] = (string) $dijit; - $this->setDijitParam('leftDecoration', $decoration); - return $this; - } - - /** - * Set container to use with left decoration - * - * @param mixed $container - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setLeftDecorationContainer($container) - { - $decoration = $this->getLeftDecoration(); - $decoration['container'] = (string) $container; - $this->setDijitParam('leftDecoration', $decoration); - return $this; - } - - /** - * Set labels to use with left decoration - * - * @param array $labels - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setLeftDecorationLabels(array $labels) - { - $decoration = $this->getLeftDecoration(); - $decoration['labels'] = array_values($labels); - $this->setDijitParam('leftDecoration', $decoration); - return $this; - } - - /** - * Set params to use with left decoration - * - * @param array $params - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setLeftDecorationParams(array $params) - { - $decoration = $this->getLeftDecoration(); - $decoration['params'] = $params; - $this->setDijitParam('leftDecoration', $decoration); - return $this; - } - - /** - * Set attribs to use with left decoration - * - * @param array $attribs - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setLeftDecorationAttribs(array $attribs) - { - $decoration = $this->getLeftDecoration(); - $decoration['attribs'] = $attribs; - $this->setDijitParam('leftDecoration', $decoration); - return $this; - } - - /** - * Get right decoration data - * - * @return array - */ - public function getRightDecoration() - { - if ($this->hasDijitParam('rightDecoration')) { - return $this->getDijitParam('rightDecoration'); - } - return array(); - } - - /** - * Set dijit to use with right decoration - * - * @param mixed $dijit - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setRightDecorationDijit($dijit) - { - $decoration = $this->getRightDecoration(); - $decoration['dijit'] = (string) $dijit; - $this->setDijitParam('rightDecoration', $decoration); - return $this; - } - - /** - * Set container to use with right decoration - * - * @param mixed $container - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setRightDecorationContainer($container) - { - $decoration = $this->getRightDecoration(); - $decoration['container'] = (string) $container; - $this->setDijitParam('rightDecoration', $decoration); - return $this; - } - - /** - * Set labels to use with right decoration - * - * @param array $labels - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setRightDecorationLabels(array $labels) - { - $decoration = $this->getRightDecoration(); - $decoration['labels'] = array_values($labels); - $this->setDijitParam('rightDecoration', $decoration); - return $this; - } - - /** - * Set params to use with right decoration - * - * @param array $params - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setRightDecorationParams(array $params) - { - $decoration = $this->getRightDecoration(); - $decoration['params'] = $params; - $this->setDijitParam('rightDecoration', $decoration); - return $this; - } - - /** - * Set attribs to use with right decoration - * - * @param array $attribs - * @return Zend_Dojo_Form_Element_HorizontalSlider - */ - public function setRightDecorationAttribs(array $attribs) - { - $decoration = $this->getRightDecoration(); - $decoration['attribs'] = $attribs; - $this->setDijitParam('rightDecoration', $decoration); - return $this; - } -} diff --git a/lib/Zend/Dojo/Form/SubForm.php b/lib/Zend/Dojo/Form/SubForm.php deleted file mode 100644 index cde6197f144..00000000000 --- a/lib/Zend/Dojo/Form/SubForm.php +++ /dev/null @@ -1,94 +0,0 @@ -addPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addPrefixPath('Zend_Dojo_Form_Element', 'Zend/Dojo/Form/Element', 'element') - ->addElementPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator', 'decorator') - ->addDisplayGroupPrefixPath('Zend_Dojo_Form_Decorator', 'Zend/Dojo/Form/Decorator') - ->setDefaultDisplayGroupClass('Zend_Dojo_Form_DisplayGroup'); - parent::__construct($options); - } - - /** - * Load the default decorators - * - * @return void - */ - public function loadDefaultDecorators() - { - if ($this->loadDefaultDecoratorsIsDisabled()) { - return; - } - - $decorators = $this->getDecorators(); - if (empty($decorators)) { - $this->addDecorator('FormElements') - ->addDecorator('HtmlTag', array('tag' => 'dl')) - ->addDecorator('ContentPane'); - } - } - - /** - * Get view - * - * @return Zend_View_Interface - */ - public function getView() - { - $view = parent::getView(); - if (!$this->_dojoViewPathRegistered) { - if (false === $view->getPluginLoader('helper')->getPaths('Zend_Dojo_View_Helper')) { - $view->addHelperPath('Zend/Dojo/View/Helper', 'Zend_Dojo_View_Helper'); - } - $this->_dojoViewPathRegistered = true; - } - return $view; - } -} diff --git a/lib/Zend/Dojo/View/Exception.php b/lib/Zend/Dojo/View/Exception.php deleted file mode 100644 index 83860a3384b..00000000000 --- a/lib/Zend/Dojo/View/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_createLayoutContainer($id, $content, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/AccordionPane.php b/lib/Zend/Dojo/View/Helper/AccordionPane.php deleted file mode 100644 index 215339af542..00000000000 --- a/lib/Zend/Dojo/View/Helper/AccordionPane.php +++ /dev/null @@ -1,66 +0,0 @@ -_createLayoutContainer($id, $content, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/BorderContainer.php b/lib/Zend/Dojo/View/Helper/BorderContainer.php deleted file mode 100644 index ab99939d391..00000000000 --- a/lib/Zend/Dojo/View/Helper/BorderContainer.php +++ /dev/null @@ -1,79 +0,0 @@ -_styleIsRegistered) { - $this->view->headStyle()->appendStyle('html, body { height: 100%; width: 100%; margin: 0; padding: 0; }'); - $this->_styleIsRegistered = true; - } - - // and now we create it: - return $this->_createLayoutContainer($id, $content, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/Button.php b/lib/Zend/Dojo/View/Helper/Button.php deleted file mode 100644 index 656c765a423..00000000000 --- a/lib/Zend/Dojo/View/Helper/Button.php +++ /dev/null @@ -1,68 +0,0 @@ -_prepareDijit($attribs, $params, 'element'); - - return $this->view->formButton($id, $value, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/CheckBox.php b/lib/Zend/Dojo/View/Helper/CheckBox.php deleted file mode 100644 index 4144179e714..00000000000 --- a/lib/Zend/Dojo/View/Helper/CheckBox.php +++ /dev/null @@ -1,100 +0,0 @@ -_prepareDijit($attribs, $params, 'element'); - - // strip options so they don't show up in markup - if (array_key_exists('options', $attribs)) { - unset($attribs['options']); - } - - // and now we create it: - $html = ''; - if (!strstr($id, '[]')) { - // hidden element for unchecked value - $html .= $this->_renderHiddenElement($id, $checkboxInfo['uncheckedValue']); - } - - // and final element - $html .= $this->_createFormElement($id, $checkboxInfo['checkedValue'], $params, $attribs); - - return $html; - } -} diff --git a/lib/Zend/Dojo/View/Helper/ComboBox.php b/lib/Zend/Dojo/View/Helper/ComboBox.php deleted file mode 100644 index cb20ef888d2..00000000000 --- a/lib/Zend/Dojo/View/Helper/ComboBox.php +++ /dev/null @@ -1,155 +0,0 @@ -_renderStore($params['store'], $id))) { - $params['store'] = $params['store']['store']; - if (is_string($store)) { - $html .= $store; - } - $html .= $this->_createFormElement($id, $value, $params, $attribs); - return $html; - } - unset($params['store']); - } elseif (array_key_exists('store', $params)) { - if (array_key_exists('storeType', $params)) { - $storeParams = array( - 'store' => $params['store'], - 'type' => $params['storeType'], - ); - unset($params['storeType']); - if (array_key_exists('storeParams', $params)) { - $storeParams['params'] = $params['storeParams']; - unset($params['storeParams']); - } - if (false !== ($store = $this->_renderStore($storeParams, $id))) { - if (is_string($store)) { - $html .= $store; - } - } - } - $html .= $this->_createFormElement($id, $value, $params, $attribs); - return $html; - } - - // required for correct type casting in declerative mode - if (isset($params['autocomplete'])) { - $params['autocomplete'] = ($params['autocomplete']) ? 'true' : 'false'; - } - // do as normal select - $attribs = $this->_prepareDijit($attribs, $params, 'element'); - return $this->view->formSelect($id, $value, $attribs, $options); - } - - /** - * Render data store element - * - * Renders to dojo view helper - * - * @param array $params - * @return string|false - */ - protected function _renderStore(array $params, $id) - { - if (!array_key_exists('store', $params) || !array_key_exists('type', $params)) { - return false; - } - - $this->dojo->requireModule($params['type']); - - $extraParams = array(); - $storeParams = array( - 'dojoType' => $params['type'], - 'jsId' => $params['store'], - ); - - if (array_key_exists('params', $params)) { - $storeParams = array_merge($storeParams, $params['params']); - $extraParams = $params['params']; - } - - if ($this->_useProgrammatic()) { - if (!$this->_useProgrammaticNoScript()) { - #require_once 'Zend/Json.php'; - $this->dojo->addJavascript('var ' . $storeParams['jsId'] . ";\n"); - $js = $storeParams['jsId'] . ' = ' - . 'new ' . $storeParams['dojoType'] . '(' - . Zend_Json::encode($extraParams) - . ");\n"; - $js = "function() {\n$js\n}"; - $this->dojo->_addZendLoad($js); - } - return true; - } - - return '_htmlAttribs($storeParams) . '>'; - } -} diff --git a/lib/Zend/Dojo/View/Helper/ContentPane.php b/lib/Zend/Dojo/View/Helper/ContentPane.php deleted file mode 100644 index dd28b19a1b9..00000000000 --- a/lib/Zend/Dojo/View/Helper/ContentPane.php +++ /dev/null @@ -1,66 +0,0 @@ -_createLayoutContainer($id, $content, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/CurrencyTextBox.php b/lib/Zend/Dojo/View/Helper/CurrencyTextBox.php deleted file mode 100644 index faaeaeb1e59..00000000000 --- a/lib/Zend/Dojo/View/Helper/CurrencyTextBox.php +++ /dev/null @@ -1,68 +0,0 @@ -_createFormElement($id, $value, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/CustomDijit.php b/lib/Zend/Dojo/View/Helper/CustomDijit.php deleted file mode 100644 index 07c36858714..00000000000 --- a/lib/Zend/Dojo/View/Helper/CustomDijit.php +++ /dev/null @@ -1,112 +0,0 @@ -_defaultDojoType) - ) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('No dojoType specified; cannot create dijit'); - } elseif (array_key_exists('dojoType', $params)) { - $this->_dijit = $params['dojoType']; - $this->_module = $params['dojoType']; - unset($params['dojoType']); - } else { - $this->_dijit = $this->_defaultDojoType; - $this->_module = $this->_defaultDojoType; - } - - if (array_key_exists('rootNode', $params)) { - $this->setRootNode($params['rootNode']); - unset($params['rootNode']); - } - - return $this->_createLayoutContainer($id, $value, $params, $attribs); - } - - /** - * Begin capturing content. - * - * Requires that either the {@link $_defaultDojotype} property is set, or - * that you pass a value to the "dojoType" key of the $params argument. - * - * @param string $id - * @param array $params - * @param array $attribs - * @return void - */ - public function captureStart($id, array $params = array(), array $attribs = array()) - { - if (!array_key_exists('dojoType', $params) - && (null === $this->_defaultDojoType) - ) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('No dojoType specified; cannot create dijit'); - } elseif (array_key_exists('dojoType', $params)) { - $this->_dijit = $params['dojoType']; - $this->_module = $params['dojoType']; - unset($params['dojoType']); - } else { - $this->_dijit = $this->_defaultDojoType; - $this->_module = $this->_defaultDojoType; - } - - return parent::captureStart($id, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/DateTextBox.php b/lib/Zend/Dojo/View/Helper/DateTextBox.php deleted file mode 100644 index f7dd8e7c83f..00000000000 --- a/lib/Zend/Dojo/View/Helper/DateTextBox.php +++ /dev/null @@ -1,68 +0,0 @@ -_createFormElement($id, $value, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/Dijit.php b/lib/Zend/Dojo/View/Helper/Dijit.php deleted file mode 100644 index b46751a43d1..00000000000 --- a/lib/Zend/Dojo/View/Helper/Dijit.php +++ /dev/null @@ -1,344 +0,0 @@ -dojo = $this->view->dojo(); - $this->dojo->enable(); - return $this; - } - - - /** - * Get root node type - * - * @return string - */ - public function getRootNode() - { - return $this->_rootNode; - } - - /** - * Set root node type - * - * @param string $value - * @return Zend_Dojo_View_Helper_Dijit - */ - public function setRootNode($value) - { - $this->_rootNode = $value; - return $this; - } - - /** - * Whether or not to use declarative dijit creation - * - * @return bool - */ - protected function _useDeclarative() - { - return Zend_Dojo_View_Helper_Dojo::useDeclarative(); - } - - /** - * Whether or not to use programmatic dijit creation - * - * @return bool - */ - protected function _useProgrammatic() - { - return Zend_Dojo_View_Helper_Dojo::useProgrammatic(); - } - - /** - * Whether or not to use programmatic dijit creation w/o script creation - * - * @return bool - */ - protected function _useProgrammaticNoScript() - { - return Zend_Dojo_View_Helper_Dojo::useProgrammaticNoScript(); - } - - /** - * Create a layout container - * - * @param int $id - * @param string $content - * @param array $params - * @param array $attribs - * @param string|null $dijit - * @return string - */ - protected function _createLayoutContainer($id, $content, array $params, array $attribs, $dijit = null) - { - $attribs['id'] = $id; - $attribs = $this->_prepareDijit($attribs, $params, 'layout', $dijit); - - $nodeType = $this->getRootNode(); - $html = '<' . $nodeType . $this->_htmlAttribs($attribs) . '>' - . $content - . "\n"; - - return $html; - } - - /** - * Create HTML representation of a dijit form element - * - * @param string $id - * @param string $value - * @param array $params - * @param array $attribs - * @param string|null $dijit - * @return string - */ - public function _createFormElement($id, $value, array $params, array $attribs, $dijit = null) - { - if (!array_key_exists('id', $attribs)) { - $attribs['id'] = $id; - } - $attribs['name'] = $id; - $attribs['value'] = (string) $value; - $attribs['type'] = $this->_elementType; - - $attribs = $this->_prepareDijit($attribs, $params, 'element', $dijit); - - $html = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - return $html; - } - - /** - * Merge attributes and parameters - * - * Also sets up requires - * - * @param array $attribs - * @param array $params - * @param string $type - * @param string $dijit Dijit type to use (otherwise, pull from $_dijit) - * @return array - */ - protected function _prepareDijit(array $attribs, array $params, $type, $dijit = null) - { - $this->dojo->requireModule($this->_module); - - switch ($type) { - case 'layout': - $stripParams = array('id'); - break; - case 'element': - $stripParams = array('id', 'name', 'value', 'type'); - foreach (array('checked', 'disabled', 'readonly') as $attrib) { - if (array_key_exists($attrib, $attribs)) { - if ($attribs[$attrib]) { - $attribs[$attrib] = $attrib; - } else { - unset($attribs[$attrib]); - } - } - } - break; - case 'textarea': - $stripParams = array('id', 'name', 'type', 'degrade'); - break; - default: - } - - foreach ($stripParams as $param) { - if (array_key_exists($param, $params)) { - unset($params[$param]); - } - } - - // Normalize constraints, if present - foreach ($this->_jsonParams as $param) { - if (array_key_exists($param, $params)) { - #require_once 'Zend/Json.php'; - - if (is_array($params[$param])) { - $values = array(); - foreach ($params[$param] as $key => $value) { - if (!is_scalar($value)) { - continue; - } - $values[$key] = $value; - } - } elseif (is_string($params[$param])) { - $values = (array) $params[$param]; - } else { - $values = array(); - } - $values = Zend_Json::encode($values); - if ($this->_useDeclarative()) { - $values = str_replace('"', "'", $values); - } - $params[$param] = $values; - } - } - - $dijit = (null === $dijit) ? $this->_dijit : $dijit; - if ($this->_useDeclarative()) { - $attribs = array_merge($attribs, $params); - if (isset($attribs['required'])) { - $attribs['required'] = ($attribs['required']) ? 'true' : 'false'; - } - $attribs['dojoType'] = $dijit; - } elseif (!$this->_useProgrammaticNoScript()) { - $this->_createDijit($dijit, $attribs['id'], $params); - } - - return $attribs; - } - - /** - * Create a dijit programmatically - * - * @param string $dijit - * @param string $id - * @param array $params - * @return void - */ - protected function _createDijit($dijit, $id, array $params) - { - $params['dojoType'] = $dijit; - - array_walk_recursive($params, array($this, '_castBoolToString')); - - $this->dojo->setDijit($id, $params); - } - - /** - * Cast a boolean to a string value - * - * @param mixed $item - * @param string $key - * @return void - */ - protected function _castBoolToString(&$item, $key) - { - if (!is_bool($item)) { - return; - } - $item = ($item) ? "true" : "false"; - } - - /** - * Render a hidden element to hold a value - * - * @param string $id - * @param string|int|float $value - * @return string - */ - protected function _renderHiddenElement($id, $value) - { - $hiddenAttribs = array( - 'name' => $id, - 'value' => (string) $value, - 'type' => 'hidden', - ); - return '_htmlAttribs($hiddenAttribs) . $this->getClosingBracket(); - } - - /** - * Create JS function for retrieving parent form - * - * @return void - */ - protected function _createGetParentFormFunction() - { - $function =<<dojo->addJavascript($function); - } -} diff --git a/lib/Zend/Dojo/View/Helper/DijitContainer.php b/lib/Zend/Dojo/View/Helper/DijitContainer.php deleted file mode 100644 index 35f0f1a11f0..00000000000 --- a/lib/Zend/Dojo/View/Helper/DijitContainer.php +++ /dev/null @@ -1,92 +0,0 @@ -_captureLock)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception(sprintf('Lock already exists for id "%s"', $id)); - } - - $this->_captureLock[$id] = true; - $this->_captureInfo[$id] = array( - 'params' => $params, - 'attribs' => $attribs, - ); - - ob_start(); - return; - } - - /** - * Finish capturing content for layout container - * - * @param string $id - * @return string - */ - public function captureEnd($id) - { - if (!array_key_exists($id, $this->_captureLock)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception(sprintf('No capture lock exists for id "%s"; nothing to capture', $id)); - } - - $content = ob_get_clean(); - extract($this->_captureInfo[$id]); - unset($this->_captureLock[$id], $this->_captureInfo[$id]); - return $this->_createLayoutContainer($id, $content, $params, $attribs); - } -} diff --git a/lib/Zend/Dojo/View/Helper/Dojo.php b/lib/Zend/Dojo/View/Helper/Dojo.php deleted file mode 100644 index e05e4b8450b..00000000000 --- a/lib/Zend/Dojo/View/Helper/Dojo.php +++ /dev/null @@ -1,176 +0,0 @@ -_container = $registry[__CLASS__]; - } - - /** - * Set view object - * - * @param Zend_Dojo_View_Interface $view - * @return void - */ - public function setView(Zend_View_Interface $view) - { - $this->view = $view; - $this->_container->setView($view); - } - - /** - * Return dojo container - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function dojo() - { - return $this->_container; - } - - /** - * Proxy to container methods - * - * @param string $method - * @param array $args - * @return mixed - * @throws Zend_Dojo_View_Exception For invalid method calls - */ - public function __call($method, $args) - { - if (!method_exists($this->_container, $method)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception(sprintf('Invalid method "%s" called on dojo view helper', $method)); - } - - return call_user_func_array(array($this->_container, $method), $args); - } - - /** - * Set whether or not dijits should be created declaratively - * - * @return void - */ - public static function setUseDeclarative() - { - self::$_useProgrammatic = false; - } - - /** - * Set whether or not dijits should be created programmatically - * - * Optionally, specifiy whether or not dijit helpers should generate the - * programmatic dojo. - * - * @param int $style - * @return void - */ - public static function setUseProgrammatic($style = self::PROGRAMMATIC_SCRIPT) - { - if (!in_array($style, array(self::PROGRAMMATIC_SCRIPT, self::PROGRAMMATIC_NOSCRIPT))) { - $style = self::PROGRAMMATIC_SCRIPT; - } - self::$_useProgrammatic = $style; - } - - /** - * Should dijits be created declaratively? - * - * @return bool - */ - public static function useDeclarative() - { - return (false === self::$_useProgrammatic); - } - - /** - * Should dijits be created programmatically? - * - * @return bool - */ - public static function useProgrammatic() - { - return (false !== self::$_useProgrammatic); - } - - /** - * Should dijits be created programmatically but without scripts? - * - * @return bool - */ - public static function useProgrammaticNoScript() - { - return (self::PROGRAMMATIC_NOSCRIPT === self::$_useProgrammatic); - } -} diff --git a/lib/Zend/Dojo/View/Helper/Dojo/Container.php b/lib/Zend/Dojo/View/Helper/Dojo/Container.php deleted file mode 100644 index 6a6cfe439c7..00000000000 --- a/lib/Zend/Dojo/View/Helper/Dojo/Container.php +++ /dev/null @@ -1,1205 +0,0 @@ -view = $view; - } - - /** - * Enable dojo - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function enable() - { - $this->_enabled = true; - return $this; - } - - /** - * Disable dojo - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function disable() - { - $this->_enabled = false; - return $this; - } - - /** - * Is dojo enabled? - * - * @return bool - */ - public function isEnabled() - { - return $this->_enabled; - } - - /** - * Add options for the Dojo Container to use - * - * @param array|Zend_Config Array or Zend_Config object with options to use - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setOptions($options) - { - if($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - foreach($options as $key => $value) { - $key = strtolower($key); - switch($key) { - case 'requiremodules': - $this->requireModule($value); - break; - case 'modulepaths': - foreach($value as $module => $path) { - $this->registerModulePath($module, $path); - } - break; - case 'layers': - $value = (array) $value; - foreach($value as $layer) { - $this->addLayer($layer); - } - break; - case 'cdnbase': - $this->setCdnBase($value); - break; - case 'cdnversion': - $this->setCdnVersion($value); - break; - case 'cdndojopath': - $this->setCdnDojoPath($value); - break; - case 'localpath': - $this->setLocalPath($value); - break; - case 'djconfig': - $this->setDjConfig($value); - break; - case 'stylesheetmodules': - $value = (array) $value; - foreach($value as $module) { - $this->addStylesheetModule($module); - } - break; - case 'stylesheets': - $value = (array) $value; - foreach($value as $stylesheet) { - $this->addStylesheet($stylesheet); - } - break; - case 'registerdojostylesheet': - $this->registerDojoStylesheet($value); - break; - case 'enable': - if($value) { - $this->enable(); - } else { - $this->disable(); - } - } - } - - return $this; - } - - /** - * Specify one or multiple modules to require - * - * @param string|array $modules - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function requireModule($modules) - { - if (!is_string($modules) && !is_array($modules)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('Invalid module name specified; must be a string or an array of strings'); - } - - $modules = (array) $modules; - - foreach ($modules as $mod) { - if (!preg_match('/^[a-z][a-z0-9._-]+$/i', $mod)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception(sprintf('Module name specified, "%s", contains invalid characters', (string) $mod)); - } - - if (!in_array($mod, $this->_modules)) { - $this->_modules[] = $mod; - } - } - - return $this; - } - - /** - * Retrieve list of modules to require - * - * @return array - */ - public function getModules() - { - return $this->_modules; - } - - /** - * Register a module path - * - * @param string $module The module to register a path for - * @param string $path The path to register for the module - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function registerModulePath($module, $path) - { - $path = (string) $path; - if (!in_array($module, $this->_modulePaths)) { - $this->_modulePaths[$module] = $path; - } - - return $this; - } - - /** - * List registered module paths - * - * @return array - */ - public function getModulePaths() - { - return $this->_modulePaths; - } - - /** - * Add layer (custom build) path - * - * @param string $path - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addLayer($path) - { - $path = (string) $path; - if (!in_array($path, $this->_layers)) { - $this->_layers[] = $path; - } - - return $this; - } - - /** - * Get registered layers - * - * @return array - */ - public function getLayers() - { - return $this->_layers; - } - - /** - * Remove a registered layer - * - * @param string $path - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function removeLayer($path) - { - $path = (string) $path; - $layers = array_flip($this->_layers); - if (array_key_exists($path, $layers)) { - unset($layers[$path]); - $this->_layers = array_keys($layers); - } - return $this; - } - - /** - * Clear all registered layers - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function clearLayers() - { - $this->_layers = array(); - return $this; - } - - /** - * Set CDN base path - * - * @param string $url - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setCdnBase($url) - { - $this->_cdnBase = (string) $url; - return $this; - } - - /** - * Return CDN base URL - * - * @return string - */ - public function getCdnBase() - { - return $this->_cdnBase; - } - - /** - * Use CDN, using version specified - * - * @param string $version - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setCdnVersion($version = null) - { - $this->enable(); - if (preg_match('/^[1-9]\.[0-9]{1,2}(\.[0-9]{1,2})?$/', $version)) { - $this->_cdnVersion = $version; - } - return $this; - } - - /** - * Get CDN version - * - * @return string - */ - public function getCdnVersion() - { - return $this->_cdnVersion; - } - - /** - * Set CDN path to dojo (relative to CDN base + version) - * - * @param string $path - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setCdnDojoPath($path) - { - $this->_cdnDojoPath = (string) $path; - return $this; - } - - /** - * Get CDN path to dojo (relative to CDN base + version) - * - * @return string - */ - public function getCdnDojoPath() - { - return $this->_cdnDojoPath; - } - - /** - * Are we using the CDN? - * - * @return bool - */ - public function useCdn() - { - return !$this->useLocalPath(); - } - - /** - * Set path to local dojo - * - * @param string $path - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setLocalPath($path) - { - $this->enable(); - $this->_localPath = (string) $path; - return $this; - } - - /** - * Get local path to dojo - * - * @return string - */ - public function getLocalPath() - { - return $this->_localPath; - } - - /** - * Are we using a local path? - * - * @return bool - */ - public function useLocalPath() - { - return (null === $this->_localPath) ? false : true; - } - - /** - * Set Dojo configuration - * - * @param string $option - * @param mixed $value - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setDjConfig(array $config) - { - $this->_djConfig = $config; - return $this; - } - - /** - * Set Dojo configuration option - * - * @param string $option - * @param mixed $value - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setDjConfigOption($option, $value) - { - $option = (string) $option; - $this->_djConfig[$option] = $value; - return $this; - } - - /** - * Retrieve dojo configuration values - * - * @return array - */ - public function getDjConfig() - { - return $this->_djConfig; - } - - /** - * Get dojo configuration value - * - * @param string $option - * @param mixed $default - * @return mixed - */ - public function getDjConfigOption($option, $default = null) - { - $option = (string) $option; - if (array_key_exists($option, $this->_djConfig)) { - return $this->_djConfig[$option]; - } - return $default; - } - - /** - * Add a stylesheet by module name - * - * @param string $module - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addStylesheetModule($module) - { - if (!preg_match('/^[a-z0-9]+\.[a-z0-9_-]+(\.[a-z0-9_-]+)*$/i', $module)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('Invalid stylesheet module specified'); - } - if (!in_array($module, $this->_stylesheetModules)) { - $this->_stylesheetModules[] = $module; - } - return $this; - } - - /** - * Get all stylesheet modules currently registered - * - * @return array - */ - public function getStylesheetModules() - { - return $this->_stylesheetModules; - } - - /** - * Add a stylesheet - * - * @param string $path - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addStylesheet($path) - { - $path = (string) $path; - if (!in_array($path, $this->_stylesheets)) { - $this->_stylesheets[] = (string) $path; - } - return $this; - } - - /** - * Register the dojo.css stylesheet? - * - * With no arguments, returns the status of the flag; with arguments, sets - * the flag and returns the object. - * - * @param null|bool $flag - * @return Zend_Dojo_View_Helper_Dojo_Container|bool - */ - public function registerDojoStylesheet($flag = null) - { - if (null === $flag) { - return $this->_registerDojoStylesheet; - } - - $this->_registerDojoStylesheet = (bool) $flag; - return $this; - } - - /** - * Retrieve registered stylesheets - * - * @return array - */ - public function getStylesheets() - { - return $this->_stylesheets; - } - - /** - * Add a script to execute onLoad - * - * dojo.addOnLoad accepts: - * - function name - * - lambda - * - * @param string $callback Lambda - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addOnLoad($callback) - { - if (!in_array($callback, $this->_onLoadActions, true)) { - $this->_onLoadActions[] = $callback; - } - return $this; - } - - /** - * Prepend an onLoad event to the list of onLoad actions - * - * @param string $callback Lambda - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function prependOnLoad($callback) - { - if (!in_array($callback, $this->_onLoadActions, true)) { - array_unshift($this->_onLoadActions, $callback); - } - return $this; - } - - /** - * Retrieve all registered onLoad actions - * - * @return array - */ - public function getOnLoadActions() - { - return $this->_onLoadActions; - } - - /** - * Start capturing routines to run onLoad - * - * @return bool - */ - public function onLoadCaptureStart() - { - if ($this->_captureLock) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('Cannot nest onLoad captures'); - } - - $this->_captureLock = true; - ob_start(); - return; - } - - /** - * Stop capturing routines to run onLoad - * - * @return bool - */ - public function onLoadCaptureEnd() - { - $data = ob_get_clean(); - $this->_captureLock = false; - - $this->addOnLoad($data); - return true; - } - - /** - * Add a programmatic dijit - * - * @param string $id - * @param array $params - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addDijit($id, array $params) - { - if (array_key_exists($id, $this->_dijits)) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception(sprintf('Duplicate dijit with id "%s" already registered', $id)); - } - - $this->_dijits[$id] = array( - 'id' => $id, - 'params' => $params, - ); - - return $this; - } - - /** - * Set a programmatic dijit (overwrites) - * - * @param string $id - * @param array $params - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setDijit($id, array $params) - { - $this->removeDijit($id); - return $this->addDijit($id, $params); - } - - /** - * Add multiple dijits at once - * - * Expects an array of id => array $params pairs - * - * @param array $dijits - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addDijits(array $dijits) - { - foreach ($dijits as $id => $params) { - $this->addDijit($id, $params); - } - return $this; - } - - /** - * Set multiple dijits at once (overwrites) - * - * Expects an array of id => array $params pairs - * - * @param array $dijits - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function setDijits(array $dijits) - { - $this->clearDijits(); - return $this->addDijits($dijits); - } - - /** - * Is the given programmatic dijit already registered? - * - * @param string $id - * @return bool - */ - public function hasDijit($id) - { - return array_key_exists($id, $this->_dijits); - } - - /** - * Retrieve a dijit by id - * - * @param string $id - * @return array|null - */ - public function getDijit($id) - { - if ($this->hasDijit($id)) { - return $this->_dijits[$id]['params']; - } - return null; - } - - /** - * Retrieve all dijits - * - * Returns dijits as an array of assoc arrays - * - * @return array - */ - public function getDijits() - { - return array_values($this->_dijits); - } - - /** - * Remove a programmatic dijit if it exists - * - * @param string $id - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function removeDijit($id) - { - if (array_key_exists($id, $this->_dijits)) { - unset($this->_dijits[$id]); - } - - return $this; - } - - /** - * Clear all dijits - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function clearDijits() - { - $this->_dijits = array(); - return $this; - } - - /** - * Render dijits as JSON structure - * - * @return string - */ - public function dijitsToJson() - { - #require_once 'Zend/Json.php'; - return Zend_Json::encode($this->getDijits(), false, array('enableJsonExprFinder' => true)); - } - - /** - * Create dijit loader functionality - * - * @return void - */ - public function registerDijitLoader() - { - if (!$this->_dijitLoaderRegistered) { - $js =<<requireModule('dojo.parser'); - $this->_addZendLoad($js); - $this->addJavascript('var zendDijits = ' . $this->dijitsToJson() . ';'); - $this->_dijitLoaderRegistered = true; - } - } - - /** - * Add arbitrary javascript to execute in dojo JS container - * - * @param string $js - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function addJavascript($js) - { - $js = trim($js); - if (!in_array(substr($js, -1), array(';', '}'))) { - $js .= ';'; - } - - if (in_array($js, $this->_javascriptStatements)) { - return $this; - } - - $this->_javascriptStatements[] = $js; - return $this; - } - - /** - * Return all registered javascript statements - * - * @return array - */ - public function getJavascript() - { - return $this->_javascriptStatements; - } - - /** - * Clear arbitrary javascript stack - * - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function clearJavascript() - { - $this->_javascriptStatements = array(); - return $this; - } - - /** - * Capture arbitrary javascript to include in dojo script - * - * @return void - */ - public function javascriptCaptureStart() - { - if ($this->_captureLock) { - #require_once 'Zend/Dojo/View/Exception.php'; - throw new Zend_Dojo_View_Exception('Cannot nest captures'); - } - - $this->_captureLock = true; - ob_start(); - return; - } - - /** - * Finish capturing arbitrary javascript to include in dojo script - * - * @return true - */ - public function javascriptCaptureEnd() - { - $data = ob_get_clean(); - $this->_captureLock = false; - - $this->addJavascript($data); - return true; - } - - /** - * String representation of dojo environment - * - * @return string - */ - public function __toString() - { - if (!$this->isEnabled()) { - return ''; - } - - $this->_isXhtml = $this->view->doctype()->isXhtml(); - - if (Zend_Dojo_View_Helper_Dojo::useDeclarative()) { - if (null === $this->getDjConfigOption('parseOnLoad')) { - $this->setDjConfigOption('parseOnLoad', true); - } - } - - if (!empty($this->_dijits)) { - $this->registerDijitLoader(); - } - - $html = $this->_renderStylesheets() . PHP_EOL - . $this->_renderDjConfig() . PHP_EOL - . $this->_renderDojoScriptTag() . PHP_EOL - . $this->_renderLayers() . PHP_EOL - . $this->_renderExtras(); - return $html; - } - - /** - * Retrieve local path to dojo resources for building relative paths - * - * @return string - */ - protected function _getLocalRelativePath() - { - if (null === $this->_localRelativePath) { - $localPath = $this->getLocalPath(); - $localPath = preg_replace('|[/\\\\]dojo[/\\\\]dojo.js[^/\\\\]*$|i', '', $localPath); - $this->_localRelativePath = $localPath; - } - return $this->_localRelativePath; - } - - /** - * Render dojo stylesheets - * - * @return string - */ - protected function _renderStylesheets() - { - if ($this->useCdn()) { - $base = $this->getCdnBase() - . $this->getCdnVersion(); - } else { - $base = $this->_getLocalRelativePath(); - } - - $registeredStylesheets = $this->getStylesheetModules(); - foreach ($registeredStylesheets as $stylesheet) { - $themeName = substr($stylesheet, strrpos($stylesheet, '.') + 1); - $stylesheet = str_replace('.', '/', $stylesheet); - $stylesheets[] = $base . '/' . $stylesheet . '/' . $themeName . '.css'; - } - - foreach ($this->getStylesheets() as $stylesheet) { - $stylesheets[] = $stylesheet; - } - - if ($this->_registerDojoStylesheet) { - $stylesheets[] = $base . '/dojo/resources/dojo.css'; - } - - if (empty($stylesheets)) { - return ''; - } - - $stylesheets = array_reverse($stylesheets); - $style = ''; - - return $style; - } - - /** - * Render DjConfig values - * - * @return string - */ - protected function _renderDjConfig() - { - $djConfigValues = $this->getDjConfig(); - if (empty($djConfigValues)) { - return ''; - } - - #require_once 'Zend/Json.php'; - $scriptTag = ''; - - return $scriptTag; - } - - /** - * Render dojo script tag - * - * Renders Dojo script tag by utilizing either local path provided or the - * CDN. If any djConfig values were set, they will be serialized and passed - * with that attribute. - * - * @return string - */ - protected function _renderDojoScriptTag() - { - if ($this->useCdn()) { - $source = $this->getCdnBase() - . $this->getCdnVersion() - . $this->getCdnDojoPath(); - } else { - $source = $this->getLocalPath(); - } - - $scriptTag = ''; - return $scriptTag; - } - - /** - * Render layers (custom builds) as script tags - * - * @return string - */ - protected function _renderLayers() - { - $layers = $this->getLayers(); - if (empty($layers)) { - return ''; - } - - $enc = 'UTF-8'; - if ($this->view instanceof Zend_View_Interface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - - $html = array(); - foreach ($layers as $path) { - $html[] = sprintf( - '', - htmlspecialchars($path, ENT_QUOTES, $enc) - ); - } - - return implode("\n", $html); - } - - /** - * Render dojo module paths and requires - * - * @return string - */ - protected function _renderExtras() - { - $js = array(); - $modulePaths = $this->getModulePaths(); - if (!empty($modulePaths)) { - foreach ($modulePaths as $module => $path) { - $js[] = 'dojo.registerModulePath("' . $this->view->escape($module) . '", "' . $this->view->escape($path) . '");'; - } - } - - $modules = $this->getModules(); - if (!empty($modules)) { - foreach ($modules as $module) { - $js[] = 'dojo.require("' . $this->view->escape($module) . '");'; - } - } - - $onLoadActions = array(); - // Get Zend specific onLoad actions; these will always be first to - // ensure that dijits are created in the correct order - foreach ($this->_getZendLoadActions() as $callback) { - $onLoadActions[] = 'dojo.addOnLoad(' . $callback . ');'; - } - - // Get all other onLoad actions - foreach ($this->getOnLoadActions() as $callback) { - $onLoadActions[] = 'dojo.addOnLoad(' . $callback . ');'; - } - - $javascript = implode("\n ", $this->getJavascript()); - - $content = ''; - if (!empty($js)) { - $content .= implode("\n ", $js) . "\n"; - } - - if (!empty($onLoadActions)) { - $content .= implode("\n ", $onLoadActions) . "\n"; - } - - if (!empty($javascript)) { - $content .= $javascript . "\n"; - } - - if (preg_match('/^\s*$/s', $content)) { - return ''; - } - - $html = ''; - return $html; - } - - /** - * Add an onLoad action related to ZF dijit creation - * - * This method is public, but prefixed with an underscore to indicate that - * it should not normally be called by userland code. It is pertinent to - * ensuring that the correct order of operations occurs during dijit - * creation. - * - * @param string $callback - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function _addZendLoad($callback) - { - if (!in_array($callback, $this->_zendLoadActions, true)) { - $this->_zendLoadActions[] = $callback; - } - return $this; - } - - /** - * Retrieve all ZF dijit callbacks - * - * @return array - */ - public function _getZendLoadActions() - { - return $this->_zendLoadActions; - } -} diff --git a/lib/Zend/Dojo/View/Helper/Editor.php b/lib/Zend/Dojo/View/Helper/Editor.php deleted file mode 100644 index 1430a02fe30..00000000000 --- a/lib/Zend/Dojo/View/Helper/Editor.php +++ /dev/null @@ -1,199 +0,0 @@ - 'LinkDialog', - 'insertImage' => 'LinkDialog', - 'fontName' => 'FontChoice', - 'fontSize' => 'FontChoice', - 'formatBlock' => 'FontChoice', - 'foreColor' => 'TextColor', - 'hiliteColor' => 'TextColor', - 'enterKeyHandling' => 'EnterKeyHandling', - 'fullScreen' => 'FullScreen', - 'newPage' => 'NewPage', - 'print' => 'Print', - 'tabIndent' => 'TabIndent', - 'toggleDir' => 'ToggleDir', - 'viewSource' => 'ViewSource' - ); - - /** - * JSON-encoded parameters - * @var array - */ - protected $_jsonParams = array('captureEvents', 'events', 'plugins', 'extraPlugins'); - - /** - * dijit.Editor - * - * @param string $id - * @param string $value - * @param array $params - * @param array $attribs - * @return string - */ - public function editor($id, $value = null, $params = array(), $attribs = array()) - { - if (isset($params['plugins'])) { - foreach ($this->_getRequiredModules($params['plugins']) as $module) { - $this->dojo->requireModule($module); - } - } - - // Previous versions allowed specifying "degrade" to allow using a - // textarea instead of a div -- but this is insecure. Removing the - // parameter if set to prevent its injection in the dijit. - if (isset($params['degrade'])) { - unset($params['degrade']); - } - - $hiddenName = $id; - if (array_key_exists('id', $attribs)) { - $hiddenId = $attribs['id']; - } else { - $hiddenId = $hiddenName; - } - $hiddenId = $this->_normalizeId($hiddenId); - - $textareaName = $this->_normalizeEditorName($hiddenName); - $textareaId = $hiddenId . '-Editor'; - - $hiddenAttribs = array( - 'id' => $hiddenId, - 'name' => $hiddenName, - 'value' => $value, - 'type' => 'hidden', - ); - $attribs['id'] = $textareaId; - - $this->_createGetParentFormFunction(); - $this->_createEditorOnSubmit($hiddenId, $textareaId); - - $attribs = $this->_prepareDijit($attribs, $params, 'textarea'); - - $html = '_htmlAttribs($attribs) . '>' - . $value - . "\n"; - - // Embed a textarea in a
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 z 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 c4NZWZUj!aG^Xtdd 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

+$hqIn|&CrFj@1 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 z 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

QPEKywJ7%4jOkRYKOSEg~Z8JxW1H)Y8 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 z

Gp%zB!~~Tn#@FjehlF0dQJf@hWsOtJj)3Q?B)2) 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

ysmubmm;1{o5>dV&IJUftm+8m7}_8ukE~Noq3p8 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

T&WlgYF(F~8 z9x@->X57XGf7zxI$Z$m7X1ZTPB*WAK83XdU8Kv*#n!YAUn)DA>sERGeCBlPu1pyX2#5BvQNn$upzR`{Hi3;Q{wD4$!iV%vcp0k zG^_l|6cxf}(;M*m%3St0o3Bl6B~{>+51X$|b0H>5eUBNcq&94*q@%~JL?!*kEM&6JX$hN6u-R``GTH5P2KkK1dhy~s-&TrjN;TnfnNq#*%eNp0 z=)d^O_o{*n1^L!=XPbS_Eg+*nzB2>Ws}IOHkRQ!pwYdjm639>HE+zMa-n3+tn&66M$`G|R5Z5C*pqvi!AiesNR`Qowrer(F64;zD-zYf%Liur=!%C>_uOqP91*| z&LvD%CP%<#BWx1R6-u78q%M>A+(|gig_w_EvmIVZr>lB>39<*ob$X|Gg{6ti6cRS= zgS8eA-sb2i_3K}j!=(rmMYNtPK7Qh~`7oFP<-$sp8%p+oiKIR?^($yegV{ctdopP0z(eI!UxC%lf*ipTJ? zoPkU-&5*vBkHF?EXPc5oK&bbg<&?yFG|f8}fjj`4vz-}2!c`zt_H&#~O16T~eC!u$fs}AoGLhawHCEDDuU-%IGv*zT^PNSlDRQ=X8iejN zOF4&>EC!*`=0c~(4PujTNvSqOWKK(77dlr82|s}iwlzpS%~`{@ zGnrwv{^;`{Wt_c242^7LQ^rZOqqH)@MzHw|tF}|0Z`1ZUQ7P&=ZEvE;aSy-B z>C7Y}tO~F8@Vd(B!6d%I;-eJ&SKzIJO%~fk$5;G^VAIGM$0WWxZtP5A zQedJujh!V*qBu>QFPKPMP;a@;+4DEA>zqZnx2HL6h)om7HnG zm`;S^{9Ny3F^NaN>z%Kd-{iDUA^C{Y(HSDd(AO@ghj($_7ZT0}p);y@sg zi6uLQ*cJN`&S55bd@j>{(+FoE@u+ z{V+>y3LIKLTnVoSEQ!_+$2%K1a&GuFB2#af;C!y+PfHFk!CDjk-Gew2oT7JA`f-g- z`|@-awxkmoJg2XZ;cTuTb0G_^rqw4@>kJ@K4xNh^@%ATL`o0Hi(0E0)l^ zkOM&8vg9!kT76pW)Ph3&gxm4&DA*J@4U~L~f5$OtqQn^%5lWT3idk}_lJb^x5n>vE zOyW3oMvzyI=?XH9NsUoL$mS^~9h8g%;Z+DHU&$OLYn-b0iq|_DXRUL1tdMOWl;^ch z;rp1_^K`A#`F^q44V$@aGe$|#;ixT;51d&{^2`B{uR%U^`lp{9XQMNZNxb^B(OJYK z*X&36>XgN(?Yxsht^xVTS+At3g`y+v#lmo7Ya~%fET;biQYj8=jAr%s?r2Ie+{u&Mqe$M>*W*&}z@aY*UFzj%fm~ zX&}3u_Cjo%?smwB&eKk?d75o{unktIKwbdZ>x@w{8e}oZK4+Ga`5+&HeB&%ovO>vz z=gkzGk70Ab*~%oxY=O-#knf$=nUube10X*-KQqZQ-@%5STm9mc&mx<+b$)T`Fxl-K zg$=dNVJ-#T)t0^o|3jR^&U&`VGnGJoXL6K@%&cgRbi|qW07Vu;PmP2%BjFLVebnX7#$r8d>d`jzg=jjweY5nOeU=sJAW6s7D z8!Fc^=PMz6M|LLCI_4ZwuV{@3-+FkE@)NHS{pFm-L~5)&y#8|1m}G>rkV9HoI_@+V zVwQqXTF0F}O!gJp2tv<2k2^z!*yrZQoopt%3w;5bYKVN?$yFPFwA_gwcQz?$(Ibky zlZoU<(%LVC%hjIaP#Mzk?B+4V=?a2Rb|_g6(hDS!5R#j=3FHnC*OIS6?gc57C^??2 z^2{+1dOlbrQC~?BjCr&p<&4A}C8a^8fD}z^Qc?qio<*LOs6SESGy$QN(z7+K07aLXgtd<{6N8LGThI{?gH(Uj$hLQo)kf zKsJF?wB&7&Z6KFhvI=AuNF_@?1~~vy)e=hm7m(^Fkz*jWEuk7qT!InVk{V<1O$v~D zmQX8GNw2nq@^b-fu1++6h{}-@egrR?fiz5XQL@jH@j}cIkn7>qFwtZZdF2{|D^eGb z#)(}Ia~x9$q&LX5iTfX6V#l%T64ROFnvY(OS%41ul9-4QV4l< zNSw_i$B+$q-ITaQZHnM(JOiXtqOOqe5)c|8J13ecsclJni4(Q}p*=aB6O%MfwEEOJ zk*_2NHggfVYog>7$>9=^S3qt}l*8=jqJgQEyMTNQG9Xcv30BNNwu9V}*u*5yL{IGpC$_1Vn~u@G zJnqO6`;}Y-vI%5Z;;6={2l6?{sKmT!27kGxEeMSXV-iKD3+bU`Y+|62AxiE`tWlB) zvIlYQPn5|culV{tE>Vd|u9*xQdgd}NFuH zm~%43YeK?()Zj1IR0OGoI1eSv3?ez^YLNOMlM;uNP1u2f3Tc zvB!yInD0PnEf*U!`EONl>o~bO%uV!sLTvhi(6wN$O?@QDG{lKWURoXqJ@(yp{B8y3u`5J`sydY8hNlGirIG9sBhR6#OSxSn5%m!JU*rp^Z#cPRD zPl;C=Y-n}v^~69WSE|>WiTz5h1DS_7Zzm=_EnYW)ECzWeQFIm)o&!)xS0qX@$uW~* zLuc-aME?|<_u#c6F=sY;#cPZ!vHh4xrkMk;wXk^)FRlrB8-#XZtV%3nl4CZ5Y=BLE zqU0R1$qv5I~$J7F$EB>a$ zQ6?Ft14wWw?m-fjUnHB1us;aR^tL4GFv$tiLFioGlDJohy*6!0Jjg`Orb>vjCGn(? zkY;KW=i|h4N=ky%fX&AVN{QyQT|k;LS->_jkD}hPEwP-*J}0vIEOG5ibxvocff|u!TpIbOmfU!AQKR0e`1M}T#%U{ z2NU%dl2?v-3gmf^9~1qVDmG?M56rP)Q#N_a;y7|TNV()tCI#V*@S-*?pB$#7 zniu`5M(m+{0TX%QMNg z*QQp<>P#}iY~+xxU#*h$#KvBQTP3?OiQhqJmF%yC-a*)nI&7VMOv&?zvk&C@t+5IQgVB=-mjZ-h-_*z`*lUQTJn<4?cjp|^;{Y4uB%VjEoX;YHWe ze#s?Drhw2qynoVto4oSO<7#tzvbhqvS0k?h$tRUW`+M(5&Qr2PZSG8#eMjO%`-BH2 z>nK^FX$?+3swCPuJcRo*jnDOPC)5e$8fwXPAOk=~DalRi3_^Ln*OERULtr!3dJO`h zw+1pS84E&h4P;vK5D3j_vn`npG66Q@Etvx{17xx#uY)`dGR2bhAhhpmnkAorP!1op zu{S1lO} zLeEN;Dap0_7~imDI&6-?>n%%WffTtMvs@cz5y<%<>ntIgvLGLxM5=>)q9iAcY#M>= zwB!Sjwjleh*FlgjAm1gQ=Dv|@ego+a@_ll-l0rG?ryxHh&wrQtSgt7!G8p8?WH}|5 zf{Xw;lze)n*fay7rvpDH=cf>Q!|0dfG9`myb055ZNzQ*yydDCf7Ce${{l1VVKqkWG zx8y)2Z-CHwaWpw;o!D#ynGT!Zlk=7A0eK4KkK{omzk$32@>jC;2jUe>MO%TKNX}uB zXU+wA6U1?QtS6iJ>`u7-Q^@Q}SQT=oFp1Cir27PuT;3u18f=p8n_#rIllj%*0$3q_CULL{i@iQp9~Ug&YMr%bllQogc&Qk;)i1-J>Zs#X-(@3vHmt zvbsxG^ECGoCK9dh_B+xA;cNVWtUj-%QujTJ9(%MM3(*rnbA3N!%8- z-FH*SAhy|*Lg-3e*ZnMokWF3pTPE>ZcRly)O>zB^zzn2F z^!)v5x2@XHet`Snb+tQO$sl-TF?mACSdG)reL=}XAP>Q&p}SRxnFT_5Zs->Oh|ad~vPzs@PHFBpjDX_Z;u5q6cn=p!ejr)!e zQ|bwj&D`^Vy z4wJP^^307OH1aodKT$&YSp%Ev++9i@8z5s#3%BSNN-NLwfX!yuv~(LO=?g+5$@OlQ zl7S$f!R7|H)K>9I2iXnM)~%x?2jl?Ajc#)#PlNmf(!tGEvJm7CkWTJACDGW@#m!d| zjV(93yOc!vxz#QFv828PaZDA=TiiR9P<{fC?rxS6D*KrrJ>7?uL}l;oK9@phhkqY; zkrJwTS~0uLJ*Xrf>^a z9poNWLNi7oZ9k>R8Ri5clh+`3hLY2s6f)R#w~0-fk|FL8B@IEUA@!kd_!-$?&k{&& zkh|RlOfq7K?U!^{Dp{ET$#Fv&GsLg(m7KnV0yNyYvISfK29qsN?FM6ks)&WMl!55Tzd@UI5p3Nj4 zwMM%aFv+y%;Apq3k~vRF4oAC{lq>+Dv-@7RhLU^`8pH2(8z}h#q%U$f#%(HuXZW`> z>6JpLR_}N3Od(Vo8SWe=8Kw=^?TCzX)3$RRn(nz$(oA=}k`Az;vS+#jcZ$sbkYR|N z=}r+6jsl@O)+~1hlMFKvguJrc1x(^Qmn=7*NoF{3mXtKh-J&EKX|vofltlHDcFF*S*~_k8zUjWnM0(V1i1VhqO^9)^4t*!c+is=9rY>aJ7j_`o23!NmSDJ-6c%qjHBl=@4K6rWEfh@ry5)9{-Rz{TI<}? zf0MFPTF=4e1Gf~Dd=sU$-W{kUN^8Blj7f&+46pg{TJH`!N^$Z`ZxA|jH@JtDMCbBG zx6$uXhj+q;t~;CD=1g+TL=bA_P3|-%xn_ZqkKCh7^2}Ngx)a~*&iI4kp)2E`?qRhV1yT%g{&bHh zq1h?r=P&oD6588*9&C=ge=4E3#>mU@{!&6aqKPEE@%Tk7w78Rw$mKvh?>Qw?L8>sB z&m=RP144b(^Oh@l&64#>)_~C74A0xDiQTRiVeCfW8q1>f7NB-%&qd*3Vh0bVtb zy6+v6IJmfBwU9{@pYoi|q#4L*URDZe15(6WnL@gNoaueWBr}Y5aToJ;D>)O9Y5XbX zeaqwlQwpRvyw37|QJX7327sLH{i&oS$PgxO!1>{EjCxdY?|dd%;bGWNZItlpEAd{6 zNH-=}2S8iAh~84d>!~);`$Q$Y+m)1n7u9?TZ>Expmb{{*F37`3y@a63(a^zu3wt&n6IX8;z z{R%?oS4m64`BL*SDFO04yv~bkill*14$t@SP6u+BWyos*Y|i)Q6yn~?_po$+mG%~$ zE+p#D7kZnNL}$T;UaP`l6P*QVUS}oIxpT3m9-rNpSaQY!$xlo!`Uknfl7$?3pJ@ZK z4mrHUdsj&(CFQ-1N_r}(;B8})VFrNE*?p-utO(^f!`uV%5#m&|`H5!ll`M&J7?UW6 zF^O_m$vei8M$YI(OXDKJqfYIz5Rgi#J_d58Ytb(Be- zx#VTMHHOq{c~2MP_Tn+&VvxGtawgfP7Hlem)b~1`#WrDdo;LKlDT&V0hTd&V;=LIS zy?d2JUlwZQEn||$^?VH?H}W1$hRfvo|S)EC9LL!wZ9)R-r{$eFC}FOH)z`^Z}T42 zIMGPk&wETsbcOBbJ*8gJRk)wGgh~8lwx4&DiRAe#q}AW6Q93RKrGAIkkV%0Zkp_8f znaB*Et`38}u3}@?C5C!EnPi18pnhnaAL`x1BtMKszf>Kzpu9uMjIHPpM{ zBFay`iAK@8ys}E7vG;E8G9h6!uHNlcV-nZ%-CiBFiO!w7y@nbm8UgP1nv0h`Q-*tE zHBNNq4)?N@M5DxT?;$187&Y9R$|UXy!@b9t#AoGjZ%zuKz0Jd;^S#K&sIlxa=)vAG ziR|nEsfM-~>FrOW+9)U#jgX_PSCqq;MEM!z9a67ov>E07#zgW%sgLrUG8{RKQXlOV zQ4+-&?Uhs#r8U}X#6)@m#To6jWD=KsjCYHAMUlsN{e_sQTw}ZmY7<2s>rGJ-r9Rf1 z!6eUouvnhdjP;H&k+eG0z)HGT>|!ZJ6ery)sU%80-76==rk?I~Qky8P46hp#iA?=4 z!yEXwIODuge~UBD+od*9>Y3g*N}|Y_-VaRTyZ%hCP+7`zoK~iHZVI81B+IMFMB3|K zlr+n`ib;WOuLr$mN}{wL^x7(k^7EiKN{B7{gWe_OPELKiSA$88>Gvx3Q6sGhUJoXD zJUe|K6Q@uG#qH%1hw?auYtDNd>QxeT8r+PmrIe^GVkmsph@={4Xx-w4n zE>m*CrhcW8B1>e}G}Wu8B$^xNdeFC6v(v}D!%Q+v z+H3M2>yutsiQ?p#%Rma%#L9>_MoAM8x~HDy&0vC=%s{yxeAX*fnY=R0&9I@_^7Gz| zDn#Nu&-LariSzt|x95tJ^ZcUcR3#GU`9<$+B~hN|d!?Dgd4AceqlDI)=saEMEmE&2 zhYLNY+R6D@?48ae?uSdfvzf#>T;d%P8(XWdc}1=~Ift)#XDW%(dfh9_Brf}#US%e6 zTFbpdLTu#aUXki?4r!LM+$+H(zK?s`J5Pv-<`QpvX=)Q)iQe`qFv$;3=*>2*QzjW^B-*qXdcwP22PQct9ppTam0tZCl;<4t2nel1 zuJ(@Bl=_KgxvM?57LnYr05-MZwc0yZ$qA5am|Ui$>e7fbP}0|uwoD4bXk128c#DMCaejkWlt18*Z|7_qyplrf z+;4+-R7o`V+vruUN2%wVXzsVktEnWK#clGgW)i2q*=s5`wr6hkTB}XerklO?N}`^* z+3Tt#>Y1Cpo=oCa-t66;LWZD6ZT6;%mz^zt>dj%2?>vt78Vj3kUjO=3iY#7Xpb>Jr zH($xiu%R{c9o}{(@rbnBtJ8qI3i#cB^7`7lhKb~dQs3*fQ=4dI;9IXh6B)J0>!8=? zYKkLX)8O@kHzb8T4f2yWg-JXj{puBONM3oS*fKnUfz1(b43ivlF~|~--@PeJ;ynN1 z4Qq6Ao{xF=39)NL$Gr?C(Vfe2Z@hX%qs?)zNn?tWVXyDUz1B+VAa$A*9QQgXp|f&1 z@^jp~g^A2k)-V~!q`(;iuZ^V zwUWaQAVuNj`aP5kw>JHiOaP%PzUv=TG984zYvlTcnn;{EASF0X2_?&HoJ*Cgv828b zvkQbu>iWx+90s8^E96;;`zCAVTZ(w{0QhF10zwpQ2>E#yQWg+EQ%tK$as*-{*ul_a?HIT(?F{F zg}aDNF395`)%;=IguDRq49J!K(@GLOvC|NwhQA<%yarO!U#^7mOs!MPAJSdpV5ObB zYWwLaguLqb%ayzbujL?h{YpL9i`PKjWAcR%^BHW`fz-nf-$~?OLAHQ2@OvmJvK%8H z$kqNHAz^tCI(HiR2bFx+HzJ3XTw`sHDd}j5+l$i*hk@)z)L*aUPmn^jiFEEwsplB-DhkrfZ*&`x z40F!g(mKukflPADRUjo{)6#EpyV$e_DFbr7KSW7ikSjpi_*<3S15zKPonL2wcufXr z0@B_esN_|UmLNCzbB2k{R*()Lo%}USa?CLhnqznN#|#&nlJ7`QxY_S9LI|zpQb}*| z4=bVF!Bo;){3avCrX2{`-0C}{gk*s9gw3sfQ6+Q^l1+Diw33H3t?vF@B`<^A4zC{m zS|#*FyP+Vx{LM<<*T{YRLib2oA1S%bFRA1U5UP#-eupt)^F0Wi7X$osCBeJcp#z(N ze*dv#lVdIgc@SiXzg|gAkSQQ{`RnhKIBh}lK!*8!?q?E?2BE$>+#e&v%mAUMUBmrZ zOmfT%AkV;SxPMf=-UOj9CXMuOO_w;EEqPeU4{j|8phZSh8OT zpMx~6j`Y`OP~>cL95&_ZptSzHaY9aCC1i}hBr~?T0yg*ihm~9io7x~5e)lY~xeBBa zNTxqf34Pm#(#rBXJRmmo6pu!dY=1eE_{rmge(P+q$uu`>oCp0eN`@&J?`I1Mr-D$e zPVkqg%?lvcA@vFV{s|N(UQ3ze9~NTXhRrRondFb3NH!T}y+)qw&rtFmNI%$2@%Jbx zoG*Ev>KA{AOTl$G8aBE95+UI<*ie3E`pcC>YYsF0d?n9WoApYTSh7{gdm!Txd8Uu- z;jf@bbnT8w#np1xKhxjNUh(tX$Na*RD2Fn)p?ZGIufinT&XFG1$g6_rx)YP=Tz=fI z#a?miJnlDTl5d|2Kki@0WOt#O$Pdjfp77f!8KOCS;vc1WGD`i-s1#57o!LwB{4C1; zls}G1b{Kv0VYWX}Y{EJPa!r}-Pi2x3-Uu=uUbFqhO1fLJS-l28T&GpwY zk@-B;>OB8@A@&=sFZq8cse*FR_g7!?!zq+{Hm}mm2AS_yRkEiCR;NG~_>Gh#;6*ks z`)ios%l{x$iiQ4mCh^x+7y3UiiNB<=&^I}hR=$bKzR`D2d9o%s<8i-{e8N|B4(g^Jh(?IJqYAzRWJ(^p7ez z2ZVN^yydr@E;iMbEcf%3+@R!b|B#a2Aaw11$4|=>ufZU+D`urXLrEUUaiqS=zvWS} zSp-t3F8ZJUL<%Vi^1eS`$$HqF53<%jrerTj8j~qAB+g$T6+zbf@^PwMQ+f?%rXU;q zSu@2Z`j+x0f0GiLnUl>Hf6`-OQ%Ai%_KzxQ4^js zPm0ZJ>h+~x|0y9~f>5pQ^!q6JNy#pMiV}CN)ZuRbsFHI*njrN(exs))PBjpUv)3P@ zq=Axs{x&9=;ZGp1UWGkE{w^hj)}dvX>=(k){O74LTU5PFVo>wvvWG>=d6uitNp0`{SY+xcQ18do4 zzYrdu>D%vV!NGT=6z6`39m=S&GC|^9BAFpYrdBQ+%vm9%B5XcovQh~5IvTOd23v)2 zy26$ZMktvLuS;N4KDaN%i_$6|=qgh&SiVYZ3XoP4*i;P0td2=*CbN`mgAKi5eOcfZ zh|Ld5E)SYBk*iEkcvT7>Od-^Js|9mX$lb8HGI%wG+zV18Sd&7ib!rEb->0;)!{!_0 zieD#qR7ocg+VN5+n587zWm-3wr{p%+Q0jGqSD0jm_kz%U!BxQShYu0}xxCG$ZjKaGN_ zO5O&cc~s+|fs(cA)i`LXWQTe+4sKBLi`rZhbX0QsCW(Aa&|OJckXMkOYlD7DYJj}X zWQdZcAe4HOV3d*$Ak?N!f(#+%wReg9mq}*W8#Yv~X2C)w=^#|DX2CKgPpZvz z!3rfy)#kcjt&)u(lzQ{vBPIJlDD~#S=S-wO(>0|%z1L?hw!Hd=g+Xl0k1f zHn5Go#&rq?GRfrcP*K^t1oN20k-G*hHcINzD0)lKnn@h_mS7W;c#hpI*ePC|7R`IR z1xJ`ZfP0=Ogwq9bj_|HhltTvk;mw z`VEK_O(8Uj_6=GpxfNdY-o$M|7bPP=sGj=={h7q27!bUrB%0w52!3M{&+rEXwYN~} z@twjQL4PLkox&Z#048xy7#NHZ!ej48X!k+E6HMZo9~xBMN|EvPA?+J?2b(@764(5Q z0RP2byl-$+u;~-74X$}A*Qj8hkZ>nTN_~EG@BNIMJQd*q}C(%rLr>8XGiXBHwj94=s3K z&_%p#U%fx*&m^v&j9}5WlWQY0X!{uvyzzuQryBT!=$&%q^}%UfY$>&g#n% zc~Y=L$(!&Z@^G+A$tsX5K^_VADA@|q3}jlcPsvUtj|Tgd&@=HHVe?q_ss za8L<7l_r~Kf*+L7xkKdn;E<3o+K=>N@Ea3Z8K9ZNi-Gx^>N(Gh{{&BguO^btq#%sy zXF-s~1n;N7rW9-z1Z$Y&nx!CgSF$MBreuSX#X-q0C~}TD07B1>mjrdT6TuhYwKkRn zn|2C`YU9lS9}8uhs5agXsw#zJ zV^04RtpoC5aBLshVnbhpd;m7z1>2NVhs`4(2ZJ+z5StcC zehiu`=?n5GY<><3|0p(hfy@Ru9JD>eB)lJlp8g*RZc*}xCHf_#cN$AczHqF-t_9<&xO9#_SyyT*y;^T&gMN@z^@nd3a6gx)$l z3Sz>SgxHmwM7T_C%C*Dw^g`TwhBbbX9MT)aM3UiXA>nl7@C4$x;W!~SKW;c(y`ucM z;WJ7oKjj*d*HR^vANrb>7v>AG`SHW8Y7^zh59=R3IX^)-Nl3UF`MDgC!*C`O8S7|g zS{Oc?LTCrhX(7swzk(t~zK~Wv-I7xOAk{%yB64ig5`>;^TjF&AY0EbAIjy)K77mw7 z4!M3PKZV2jzfvhO%**hi7Ca-&XOd|)gY-t6Gr~=3vlrw}kfP!CBjgp&Th0#q{6-|+ zM^roh)ITdA2yG| z=De`zUy`3sKxp=LURXzn`32-jwwa~G{}NYVkn_WQC8d>I5EehqaZFW^1+Xa<);J;g zxdvnjNa?TxlMK@ygQSIZ5(#Q|6ZN`_!>gFYy{>H7gh`&MI27wl z@G2XwNs<@dwB3Q75sk2V5Dw!{6QjnIR0wByVv`3F!sgO&i7#Xs$eAD&!^29}sm*0! z=Rj;e);O1k%anYpHkHElq1Z&KHRr06WR0-=878`#j+6rl15q`u(M%s%(s)dJ` z6xjY;GYpE5S9}Gj8CE@miQVH`GrV32%@gR(u4b67B--6qD?H33-g#9woN^|`iO;xt zVY#9bIqLKE!y0FuoO*+>o)DYE2H{cu2y=nWPlK@JIT9yIy+PQv1d$ALCCc6jC2bV8 zJy&dK%%q(~jl)sr35oVhUK>tfl40t@i|&b$Ly70UU*vq~<&>~D@ zl5h77wg@Y#O>~8A6;@Re?apcy)>aZ-ms^EbD~a~$wF(}6?+x6x3@jA0s4 zRLas|(%2O-CTk&zs3v6V9Rg|z+2qP1Zdc(vHdWCqfUknq6s>@WWKEp&x z4Venx7=e4iaFKW)N`@9y2=Cm58onZCkp%a}jT8%5R7*#TUG(Dd;NIrfL{e?cCskC3 zeDE7;Z-_1=VXXnk7m)KCVjN3bkX0aK#X^?8AR9r#BA?}Tkewjo#R(~*7o4Nbi^Z#! zS6F61%uEvN0W4ki^S%U(sY4Rnt2R-@N5uRBF%v}(8RO3_Q^ZhCrFwpf$bJxW4tjNp zSk9t)b&5F2qQ>gGq6@urUDgLzDH);{Nifr9iat{OQI{zOa*W!_nPN-b|CT;o9Ai;s zO&537qZmJ*_e52aU`BdR)aDp9Bh3_XENVuYDH^e;8EK|y#-e7Vnc@i&*)AM)GsTk} zqpl3h6kS-8po)ynkU|5QT?1J-eytl$`k1j zCP~oGd14lcJV(RzSf0os$<$I0!%7DFdATUt1Y40NGC?qAg{Z_b2L#91N`FtmW4CCA zQj1~={A*vU#R!?oKR;b9;+kR3a)!iIt3?kf{*1I%yvU;3wN|{$qIzSk7{Q|EjkRKw z6#q)sT5;FovMk)caNhVv)MmkB6Ut_hz=HELUgg^==8?dc#t*|U#ZbeYLQBMaGPErq zcx~r(aM-y2tip7h_|xFWpU zqzXyU8&|}GEJ0b1umoi#kjNwTfo5=(SWG5K6A4G<5u`}WVNv~4B<7Q3h~5x`zaI(%2eU}*C&|>tKujUzTqH(x#8zZ#?}D5Fxhmcv34TwxD$=F+M~AB-^c1F&XC*iv z-W1(f)O>h{zK$eA`xSD=nZJZyyc4DJk5)oASybDF9>b#gN9g59g1t%Tl_KOk)LH0t zBIFu~sdsxC%L?8m;p&Y$qoirhG5D?aakw(6KS2^)*^bd60R9z3KLRl^5EG*($y9U{ z#xHT-sn3%l+CWS>h$*G#a6T$kDZOMDS=RFqgX^)t^*JnyL2xZmTA$DI4G69`O6$2S`&i28>sWpR!7IRJ_2Vp8d^t-3@5?$0a{ArR${2N>zr0?PBvUJY0)Fd;ROR(V8AE-D zX8{%TAa3)aKBNcb?5|fV>**~16;3@q zS;nX%V->xSMV-}F)02D37_o!WXl zi#jsa)|;@XJ+8LioJAcgYwN8^f<3Ob-Z4V(mx$W>bDTxQvCJ&1A5gLWh>Mb zst5E$k__!37#m|?yFZ|xBaugtw?OLX+Drd!XdKD5`Lp)y8)ob4p6Q|d? zC7(FGKF6pn7^jcuhh=4GPeFaMp!A3J=_Fb7E#vthkLcS;g5z?$zK0~}`FQ;x$Ecof zs2^rgJ>O9OgGKdxL;W0!>iLHHC6b`$8|v3NMy*8~>hLiy9MAMFT>NFfq27fgL+cH# z_!8>eSkGe_46+X7Q5`<`g?pU#I>=^_$MmWs1)BOTyNONoLLdio%lN}UC?*Uz!2bBCw&E`w!^S_ya7b4kM5yHKAUP@gV(-ys;2q2+?$@uI7~ zfh4TubIh}Px1ksV_mqPC0I8nSL&K!}4T3Z6^ZK|EQtXp5XOLH9&b2`bAys!>yeg#~ z$SIIyz2-=nY9I*a+)FP$N=g{y5=d`7k0lF4ON9G&bZv~xXAwvVkbZh6lCbs_hzl}M zPfU^d><7V?4%O3NmvW9}m_GXrDaHPPUsoX2a6NadlzTw%UYb|+s^d^Hv^pTwAZC=F z&e9&F7RVSqJuFiV26+S|MbBfwy9iL;(2ugb1u+RACg`zmN%;+=Bcz(BCryxYnPcA3@0^Gd>`jyO@+@kR6nr1 z?8`}#3~e$rB-%rTFu6hCYi0-*=0pXXu|qq#6$SWawLONtLPZ zW~mFQUW1rS{Xj&jStK_(rZeX}LoYE&w!JUNClE73cS&TAZ6b-2BEEr`-5@jd#wBdqXHCxY?;$J8EK>wU$ww{rxKG45p`4I$D zeW0&nIRaAi3AjT^&u6&`@({^R7Wb@-nWOJxsR4p9bM#+Xnt(I{nX4aX=>XE4}TNzv3jT}$-P zyO=7N)tBnsSk$b(OossYx2eR@WO+yQa{W^oDE-NbCAy}{a%tFpH=!JB$?U-&S$m$ z6iJZJ8hyYm`K-~aX3E}B*V)$S?WOqp={o%x7B&B@)1PNiZC|JNCJC-xtkZwKC7-YL z-=+Agl&|$mENZ>+wcc$8)+a-&eh%JE3%#*kpPMD6J_tU?u~FZ`(i`MB#B9=wSjMqz z*5luksj^tU)kl#8za?$e&#|a==62fdu@}J?$)0skuAk< zYVX$jkjSrNYt7+4A$=%G@RjX7`dAXV1#v#yqi2%@zY6Wux3Z}5vsd56`KWhv?9~r& zjOzIx^+Fc4j`~qQ!J@X;kNQ~_wT}8xzd#a06} z4uFh-e16v3k_5l>9n^=+#hBn1v0wFc68Huvq^i>b?$gtUd?NF?1kw>=A?d!1-}*b z9K`&gTT3w}Lu(H)IG+F1=dmP%^nsYudf8l=&nqA}^PkaENaXgyt#d|CBMH_Cf9X?5 z@`dX8zx0o!XsYM`(hG0N=bV1(mV7Sg=Wog9f?jk>J{RUWa_ zzm;6ptFfrDdRecfFy&j7itC#iqB*9p{tT*8pwWnOxo09~kU)I}mjM`KF)}LWf zrT?uz&!S5ITkp-HO8;Abi6kifZ+-A>GU`igd+@u%-})y~{8{v>zKBJYbyfd@Mb+@C zzKSH6MX#!T$IgP0@IH)K904S-5v=hPGVxk2=TK zjJ_=D{JoeFS{d{qy?xrKO%i;iBHDPEMLjtlZ9FPd`TZPiB$5OpA=*eH34VDjVH9#I z)$_V>f<=uD-8jplwwG>PW>I59H?EQdV?#HhR$(jT7Q|JYZnz}D6;8vbz@kbwjLIyk zEW@ZJ#ed(RVI+}cXss^7$`iJiY1CYeWo4240%956SUN+@F%V-4fvnDH0N2PN2@X3k z#$l3tO}&yQ#;CZ4HbvA($mTMniZS}JOaQqKa;GtmC5vN98_8>Bs$7;bM!T=1tOdab z@5&mTS@yD&HwASGJDLBuGz z9#aKBUsN_Kk`!pF&XtWg7FEM)Mo$)1!|FzV7FENV#t4$2hW8myZNRdE&0fpsMv|pX zhx+t{`qVOJlF0fD2B~A@k`(xt;_4YIrTBxlp7AxusEc#;jJ+&s_o`>i`G$Ix9#6p= zXX1>7Eb8*uBgS$TwX}&hpu+GkKl%%(;TWh-17DWCBoD$3eaXK~zK2wJ=x%6yLphHZ z=Rk1!X=H3A35)2eQ>8y<9A{CbH!)7KsM4Dlr&v_!O^ov- zLCy)rb&gRvKW>!Xi2akVshksyI2M(2qS22<<(z0tA_J1BtcnE7#ld1 zDyyXtpO0n1i7%wefK;uFP9#C;?Twn7WqnlX?TvLTs`U28CX%q&)JOJel5vh@7UcX9 z@f<--O z@|1CkMNLsp8RuElboi8UnIzaRo-+RB81>WfQ-;`rH4IMCo-#}+{tY-!8KpQz9o{<| z6$MP5_v4Zm#8Hhdm>WpOMn~Hjl(3t(V>rVibb`wk8znr zwX}~>L;{~KhyK9}lYNXb+o*s1+W}rQ>aeH_rTvYzEb5ZyAfx6EOcmA=As@VmKG--% zlA(10`2~7@h;e8q#$;$iScVyi-^o;OgWv_c5k|@HrOXA%jfG2tMgq%Xju~leU|G*G zqm3cEWvbmQV~j$UBOu41^w*3|dt}T75Inr67$;ex|AvJ-#Jp~-`$5KFSyw>D8v9vF zLJa2frjfK4V=}bgo|8S6YGjkZgC-Dzbsldx`(!>%Sl%+?Se^yJmZlk}N#NFRkeiV6 zM5FDGGSxerYLYRTWgdvp3La}Sl75mg%R#U{?;0~mf>(7;HDLB$X)nX%uBu$Isn5D*u zQy7z~wc(hhMj=ZtkVcT|3!~PbGG;W$yXE1>8YBKRxM|$pOeVB7q{tZ<7X-U+Hb9KSc*0p^1%_l*0{tn*_V_H)IZc4A3%N9 z8Z$}K#5WLw>#?tmk63p3vXJF42!5*NYvYTEd~geXZTu!h!?JKheQlg032U)8@xCX zDlHr9485`2_)VtLKLUBED#{6#ToBwkyN$nODzO~|^Vw|_am;a!*<)x|us+B2C@o5R z8S1mgNFqrSr9g(0bRmHo073Av+C9c3DgOA`W31F&!C z7WGNn{l;>Zi4cP?^V@H%W0?W+4vew=#wID+ND%D#1I9L%WgzcC%mHIJ%Sujl(AdxN zG00SiIb<{`!nPM^Pj`cP4&*lj{)=LFhqmK>aoCrBw@UPA5Ino_W1{gx40iBvmU5f{zNFFg_#+&V~OlK9i|vzreBahq0WbK&Tp?GB&cP8lEyPu&5fI zGH%LzgnF6iDWk$w>Up91`IJ$cMfLM3BT^l57RO*sd)3$%5rbp?n(<47M72Tr z^OjWCjmspmh5}-4816M}yOa=!X5K|o;BSj4^FbE1EuzfkQv7WZWp-y#+oG5`gj1=p zQOq39F>31+GvDJFwRMV{IUJ+5PI2=p$EXqYKl3_^8d3i3;5!$X_UivO9G z6dJ2FNm4lG3)rT0L4-M;zmq2iq5awDI z^>Q6yZebC3sF-~$rF=OoMXL;gFR>P8#eZq*X!nC`1~JS=QbZi5GR>AOZ9uTjruj5W z4-h<3n`SSTp}q`eNdR49K%2 zc`P?Tl1aW|af?T3FM(L*W)}Q(;>#qvr1+1>+h(^LvNzPH;cRm?Nvi18TRw#CnBTB8 zfPC!W9Ea5fm9*$2Fq%Y9M~2i z^X{88>ijVlGHa3q>x3Bd5t86o8Dl;sMRfR|90@VzGc2!y;Q3CB*@I;k$J}X-WLd#6 zcbel^c5_TgGn?fC$CNZbB1si@mXKqkl(~{)9st3yTFSi0a$=)g`;{`Uu{47itWPPk zxONB55~3@oDsA4wGMHmZn>9&N#akda4$GK5NiyJ-BQO#wpp0Ny1%lUU%bVFUAL>J# z$10ju6qXgtbrsDG#ZU^Go)S?S&VF~By^Euy3bp6PngdDFgxcd`&Cx9Cbyl(F1QxXq zRx+ov6hY3|(n{vXENZW;Y%XPqhV>W5R5rh2i2=brtYU6ssl_o>%>69QL9jQfn#Wi= zf#6E7s(Fz`%_P;#Yb?DurkYtiTK2q}TdJED%P=mhx><@v%?UNkyI9gVriNLaMa>B{ z%{nX}Kn#9Pv!?kbi<%|wH7Bzy<(PZTUs=?=ai4jdMa=;BnP*wljC7xQh2H%qbn%2La$%5oY6S539eaV%F^9yAw_zzw!W6n#MQA@dg* zBT9kb-d)!`&QcWwXMlR*EKx#AN0vA<76i{zdVpMln1{_gU2dJx zAlE?R&D|ua+6<8BwkU-%#vkDg&65#=BdVc!K0+Eosz&BDl3*`*)QmQ;EV(McJ*9~m zA_-!emLt{>B%V>W`|I{a~S z7{}}Z!FBlK=9?UIg7Zl<-{F{lIG;rGeU6E-WPK9Nk2$6q2-YXjT*fhv`Y~%brkx+N zjbnQIF()|Y6+h;0j+yGmXcqQHa7`xBEN)Y;YV#nb8T5RjnI*;FUQd_{Nz%08c9hl% zVxBNpajGy#5=e7Xb7Vdv`@)MbL0Xy26*vf58lSHP%(ek8ODnf9@*xsxbA-ERpXvRed_H!q*afD!5oy;dlg0h}A+egG; zS)I+U5rSoPHTy*fmetK1B}L>w|KJbK-OX_%VX+2eIONmad^;i))~AP=9U&Og!<-)> zV?dJ4l@anLNH23sgiHqMV;&?4TG7wELh^gm7APH$AOp`fBZ zQXprn&uiu?naV#_zGiM*fR& zb*y~DOlMKY$~VlDB&lLO)DVxSW6g6c`+Ojx_~~I>L@MOG?rH zgnaPae4IH)iobV<&G{smVyqjb?S~!|rSCl!o26>KR zF0nl8OUb)r%s`Ny6cfkt2FOb!omkRA@Varfxs)VBdvOQh8R4We`;=FIRb*$kv=tdk;t6?g`7V%f0HqqdI0M)^Bl{m#qiRu zcJNDsSu0kKjfd`x(qcdsn6ReQtirqJAm<+{_`7b2!dg zpPP9ka=S}eM-t4dpPTzgf_ZhZ8C41EBWKa7Q2G+{PLg02U1C-vk+bLn6ca}xXVLl~ zxn?Jlus=V4VOFh-Ifv=R$+&gCG`p}o25rY0=9xJpvWED3T%NgB#?buJ5prH`o+K&I zzIshQG`7M#Cq)c^eDJ#Q3bRBNEDK)c1=1B#tuXIqnFWGdd4<`4WuY$#Eb6zm6=qA8 zHGWJI%M;JYQMbYz#j+V<@XTd}IhExYNDnG~8p}mLW+6*-NtG&(r4)#);aZkTzHF4D z)%H^zU}@&dIhJR9iLFY#q4o47iDif{<5;y!AZwh&UunDhr^udWBV zL8%Js%9!mSqCJ*gydK4fLJ%AqTTP2a9ly4k4rs0usGRP@2MT&nt z^R!v>ahXb86FzN@V^PVa_5s9<>7GZ^%cp=89{XPTct_l zx+RuU)ru5Y+mx`HkjRx)O^7LBbsz~=Rwb+#NYeb5wwADlusqNcuESBPq6ldKA}rAg zYbe)a2_U*PghZ~#aMf*EQ%S-?)!DM%V^L$(vgVRxYJWkydO|*ywV%Z(4`&=8A#9J_D&@?TwIJkm^=pgscLoX+6<~`bRW|I^!=9_gfuFQbiI7Zo&JlQ5>Vze)n7B zSkwr=-=-)}7u>f1q(fTby@Qmy!>m*6OhBb_XzfRU=7OY`I_28gZ;@79Ul^r2ipB~m+lAu1x*1`zEEA~CDWhAmbt)Z-5)*2S9PZIpSVCA!5eVzg7 zZJi_u>eI&(Npjy&+pCXNBSNq~FIo?h1oe5zijR}3OtD^NQ4cevSZ}Z-z~1x)U zkeS8D@_+?T(DI=^KVvEU5wGyJ7lp-$MYd=0nY zVfdS1RVN9?&qOPpM2-!-k~7gtAdy?}6r`GHC37mZbtYLmNV2qc6{EDv5Hrcz^$eCJ zQ!R^!`^>EPE`hjk=TL^Vf<%^uJwMIb5+S7_Cd+!LE2au-S0HDcN#3`TNHSod0oR%! zW|p;|V+<6i^K7f=Sxl9ol>(^&F|)0b-K0DUQWs>d^*%|e)(Hf!U3_LOAPH+dK@uQl zzO}BqEPXV~BI{7H%x5A9UdvrrX!VQ^}^CqwF3~-6=aDunPo4m3X(yVTGM;WRvd?zp&)tI zewGU$qd=Bhb6=D(#@+CnCde8qw=d;PqizYv*H(cPZ8F5*w%A~uW61_t1u@@PZTrdk zd=7%!Vxu*gBvbnuBp+fnT2B8U=bu0dta1_Z8^{)`4oPrbV!IX3qW13XRsu<|cW<|z zk}>iu3G&%)C6fgAnC-M~M8uqen4Ok80PB+`)cw7?tTIw4pNkN)%c@Eu*AoAL{9whC z1Udg?jg&Fs9JCa-`%l)`h}>PC`EGbElD9JO+WP!0WYc-%Tc5*E3TDzPz~^;>_j6o6ER(oa}LG8NSs zTXDilA0D(6KmY!RmGDZ?u6do{T7lIyLU7*r%NiIVOCjc>RV0Oe4aC`|$g*Fhe6*v< zuwnwaYQ?e?gEKOW`Nw*MB|_B;QalDHJ(MCzu&O5kyz*Bx;lTqVWqIB^Y?rCn@eIV^{(jTy!;%d0E99fu zLs$lb;K_B#!!gk5|rrV5S@x?PeaQ_F!=7a_*5^GGtZZ$R*c0hV1njHxoT?I4rk zS5Dh5PZE6W%eE`CsE>Ww_WdMj{%4aNyBS_(mq6zMxU_8R+O~MreV%f@N+k%?8+p3odilRZMT#{sTM;_ zX?p~V`jlT;J9&bvVQbjqx;{&wOjZ)6;j^J6P~qCC)AP*fl50b`^u1v8AzgUzYkH*sGQ7y(Gb%GnMRa zZ&NDT$}*-mNzfaW>?tJj8c{aXu#!E8Bxq?R`wN-MuX81PJ&C;j^D(5VY=1`*rg`jh zkg9g^cd+zS|M$3R_H~lr_qZB%okLL%2%_^HgA_S6W$w%=>#lE_x9 zgR<_kV<%Ht)Y9e9W3}uyBpKQm$axFI)VBMQ1oxagV4o%l?!~HOSA3Ux%zqVSUArnv zI^=_;*R_YT%mn!!a;|5;!J?jwu4ku_1p8?{`&|~bpVqVA<5cRSd~x;?l3+iLv%iz# zx9eg1FsD*y6OY(`v8ehyVqa%b^?AhBr^=7pM7w~kyZ)rowJ`NDbUqCA8&W#7?DP*3AFvsANMm@vZ*^XmTFEV`2P9h0wv5@mKkaG{aXa=SVYxO{SgCyI@SyI}7 z3)6bs5 zqCPj#-=4t|$1(lwxl*(w5S&Q{*uRqm&-D+qPqV0&4z!!kl)a%^I?(RKqV~9f_G}XQ ztLt0Pu7P%8giHo`*^Yf5^U0u>JwvR*z z_TgmvLWJPGj#KPnv#~6h3h#$Zx9=ngj(XGViV=eA`DymUB*A?t)9n{Y}4{BW}8b8lWpg-;2Pjx zkoWCcA5gnAb;O@#C$gwj!7O_eNpKI$YDQk_@QmhLCF%uYrxq}XOufh zWZPv-MUvxDc&+;(iWyH5ToIaUr;`L*XRe)1BKx@wq?&7QAqmbsKeZF)V(Gzl|J0sJ zB2)E*RG-?bNP<)g?bwh0n`)sQPa;zdhExmfE+j#!9DDUGsdDTS5vfujRgNt_#+-vx zOYILxf*LNhx09ra=FnpkAk|X)2bT6A_*?%{`yh!Ny*M(L+Ts(;S@sW}d*<3DNo1XI z)Gf1{eTp%e+BnE36LQY8$C1cXyX(Mf0`2`IVeJEm!JOCFMI>@$&W2QLZTB_71;N%s1;g)U6Uj@lls=KLlUge zzO@_382{M4#qJg%xZStdEf&dksbBiG+3i{In2c@TW_KY;)$nQ#$$o z^~~Sx4xCDj`QPpCEI4DQP(A}W)n+IQuS*=Zhj7eZkW`2{Y*$?-OUFG0QysPIvf%!O zpGiMvCy>Y|>v6Okx06XywS$lk?kOkjlO*sfIml$l=MQ_}mzZ-f8=tX9kp#2x8G9T_ zu!cNiPhwGP$TRl45vlMB)fxMv2*EYvd3zO!Tti~a1v@zpOApqNSM04UYQKCQw*SvrM-r@>gtLi7 z%>csL#-e5b;p`@n{exHDgma8Uj!azb*v_R0Sp{Xe&K)bMhP3bCa}yz_JV~%$#5i?G zWX|}umKbMogy4NLC7pFr#4>0F?(e0Xe3tbfIO<9{J6O~`Ii;Mv5&7VFF6Epik^9bi zs9`Cm*ea}HnpWyQ7%gx;s*F>TBus)aWgTs;jJY3T@Dsb`omi4ots4mDT;6FdgJB2Lj9<#QN_8pd$CU!tR&qJywo#`w;g5VtWr1KHW@4hTyIq%C_l2lQmR+RPv z<+F)n)KkV!I@?*wKn$*bo^*cTRJB3+QL2M1EkQ<*93_EI3V`H-v~$j~=(VLJIhS_J zp2s(vZGf1L&OLijWUAdDPdl|)FcnH?rxA(VFMa{(>Lii`caT2obdoXt`#_#`=5an) zpOcX4IcEb4=8W>Zb5N$D{Q`6D;anj(u75uoo<)PUCp*P|z#8UjDRAc=?oG)~97#}m zvhz4e@HUcUryt4h`a#GC@4M*f4CPe+8za|0J)L)0S|!VzdpaMIq=_<6L)@l4ozFuDfID{hgL9&qAGXUDw~~z@o1jdTV^#NgTSXy?@kIRRz8=1h)|3m|Ve>qs)R zJ`YA|*FoNNsvg9)%cE!XbMQO9)08C5e;2_-rxnXYNQHaKM5hCb`fYTg(~YD+Q|}<1 z=qzPXZ|{8DS;wN@-uaHRnMJ+5bF#CGBzSx0yUs(0XzTc+H{EGKk|7)zhxmq&bSHsC zw&E>lMY=O9Lb5<+IA4$i>y7uFRZ{$yIhNeBaseE0!L-1$34(g{3?xYv@vG!{ z%4g09mR=B(12LaD*_NK(ZVkZ(b99On$xP|O9{3N_4e zYO$;W!C4~5+0UY`b>}#REc0Lt%9xWZn;;eTSdMd^1n!Xr!F!|^JH}aA)=|!Ru@l2m z#HkiL6-a`uyu_(WlJ9>WZHd#DBzVDat}|Dr@;`>Q%-O^FsFmk3=Kza(>*g}2kVUOm zmpLa`@b~V2VGAyE{v-+3^UIuzByz0oOTd^ie_^|VnIzA-heXa2_zt%`rw+%cEA}g$ z#w@Dzl};jys`E-`pcMbL#4DXD=di4xKC7HZZj+WInOa<3xOcZ3Jc;AH5Fz-C;c90n zOFM`e0WoWw6cX94*Fe@fvm+!OWTSJ5B&_v;R0j0VHs|yOtWQ{bm1Vm#5Su4{u2<+UXrjj5$c1p z@lGfCimV~-O*k9xbka$JPZNCS#QrT~rb8;+b9Xr#Smv_qajyR(V-|wY8NE~U8cL?7 z_OE?T;&qDg_tOJTTb7NG3ePwWI3q|>#U7B)pjQt#yI4+uybUwJ0cStU6_6Z?DP&Q5 z+yUn#NfKj8evqUQOZozpC8oNF} zFOGHt%L?ZC-<%O7!N~mGNg)aL<=>t0B*DJ?yR(HP*q4tu+D*(kc!TaSr?M3P4Z6pi zds)=Je9WoCqV}d^PJI@&FCTLnk_0t8<}~9NbtZnyc|r=!{CK{6%n5Uhx@z=?Gm%A= z^@lT+MeVtNI9Vh?S${YmM#v`ErhhnJ-jdIs&bnLj`O~?`qUMc1o$C?#Y=?aQbVg{! zp~up+CiUPQ9Uy0%lPq0X{&KoS$(UDJ&O5tEGPG$R2O-r(=e=SW6I`jd;(W}a`sa$X zK#Ko?mn%-_4oc;JjPY-0HjBCn@voCmT*jzt4pD9rNtSjQN?wc&C zpN0E2i|S|LrjrEyEZl4oIgjDT{eF{;iXw=Rnsy&<PEm-b%ud_VEQrnGpWqtawJm|J!d5z^E_j#6SAb8EZ zo;!qP9tgJUVRtP{E~l#R?qK;AWE|AFf!o-_vQo95K_-DTaxax6p>;1_%WdqIDMcb) zpCwmuP277}iugU`P23tRg^&-fteUtFvYZ9MBS;gsKFdEKxRsl@2_(T0Kf!%2Lhy*+ z)a}Qjj`+>op)wz;VFuLsad&Kl;HtZYJ0n8oKulYA6-n?Z^$za-(%7!xGc_GuqYR0^ zUvzXmDgN8|JGx~_g5!Hfw+W|G$M=qIBBxTv_l|Bpi+a;OPpFcaa1~*q(0UU08aszrWzNB?;!A7u-%H!Tj@r zn@tiNVf(ndWGa8P{E~Zt^HFouOYT(`HAlVVYIkGl!8@y8a!atN8R;e0BnfKxl6&WE zvM!eLp^ub`W}5brdqRpoTKc(XS=8*;&%Ml|YS_=cP9n?7g^}6MEn7+Etmg0m?pzi% zhYxfYOYzGZ=;m>ZTAdDbS8|LRhXdU;9HY+l2D;l=)EFD=USd(>aHxBOMUBkBZ_utrAQRlSB*FYM z*)4k?#squ86gO6ie|(?fPOn8Ves4^1^H@|LPI2|x7?Y{BsxR-=Pj_Qky8F_eBq%H0 z?Lrdlap`Ub$EdM7&CO;}d($*`4vQM$)7;Nk)ZR4BT|^S>P1D?E9HZ77)7*6=LFv=n z%N(OhpYC2~QKe6J?|4A=m@0j`Yp|%&r@IbGQ2KPYG{>mYr@OHvLFv=o?i`~^&vN^) zsM53Cfh?-@EO$7IDm}{`NfMNv<&NbTReF{?kt8TR%Prs-ReH9&lSP%D?e1k!rDwYb zSybuS?r$VP>DlfHj!`S&Z1*%thBgt#Mm~(pY&ZQu?9~kITM+y%!z_0%%K?z@A!fE) zypD`H2l5lh2kyfp@@y18T|UQc!lKsCpSZ20_;bR1H;F~HV!qp%MYVmt`#wp~iurCb zN$`8+e0N?%Oc_`$&v%PGB*%v8=S8kA#owD2xfNN|OuNWEU6)e%``72LRZoiAzdm=T zOYvK=#GOSFY{4b&B92k5$aTM9QCl$AUB#l>p6jk>QCl$A-AEF&J=fhv5}X(0x`i^8 zf2HC}w=hoDSDLmqs$?eU@!* zttL`dv+Qv9vg~B}&W&p-V@|N_a#yijX4&JeYbIkt4d7`?sLx*4dR)o_AfrKkayzjk zf~11{?B7tCJBz+=iJ6p{F&{Xo5Z4KwsUTFE7>l!pPqLYww9vy?u+gk7PZp5 z>~5FhxBZH{hehpiSKJ>-f_?dldyHdLZxp$wS=7E<p1WWoS-A zcm@h$j8GGjpr6f9a~4%+Gt`bnwbTqfLlU&Y40Y!ib<8zGJ*D`qFhjFAM%|(9g+60Z zW8MobW>KYkp*$8Vtb+#n392 zLB8xFkv04V#zw`^O_`6sU&My2B$=~1=EjB&NfGJ@8yhO*7*(IxP(r8w)~8bFc@kL` zwzN{{MH%ClRXOxBr&48A4#oEPZ$6bnkCMPQ=B~qid{F1gq0S_7GvtI^`3BD z=RSCci7yX;RDzg5YC}F5cfnmceoTFq2b4q?|4h!A5Bd@}1@7^Lr=kK$0KqryKcr&( zI@j|B@1n%|#QCCX7zozzL8zfG(e0r=c*ottx23A@3#NJ$QU#I>sqku80~HfJ0;CPZ zG*n_w1nCIU*q6C1kNUC_1h2C_rX*Um-4}Z+$0Vp2yJ6!fYH1+7N6T~AKw3cz*08Cc zstZdqUtVN++?SCoiN3te@`Nuc=jOhsGw2q+6hf-*(Ds%}qN~Cd{0g>UD_>Mg+xnum zaywtnLO!^6Cn>S-cr;3js~IWkci|3xjN0xUeNkJ`m*{$sPk*RkClwQ&2!hWgJ)^`Q z;hlZKe1<|QU!uD}s!iI!_jOuw`qKhEaSCDFmiiy7CG1>FOd{Jc$_r-%4tf4Q|ip?Oe zs2INwU-hLjq{97cq!Pb>e6d?V%tKY-9vBs4ce_nSfb52{f|!Y%^B9#X+GrA`{Q@z8 z#DW|KN%3PI0XYHkx-VVf*^09uWB(&~<$t^qzg-i2!MP6WJkb~RRNdQ3qE#Qhqr`3x zrQ@6sNDq)3Q2HblGU)1<{R|)leaTpEhzNqb<;R|l}((o6Enzb_h7&U7JqUM(A zevF#6X859Jtt?;Eto5ERYSzm3Wi+>arZ4ZXyzk3rAXTBxvwTrU#@W8?%at?j2fpBQ z^tdeoDUl#Y-G_cm>D#3GZ4!T*v;e{F73A|Q%N&)nzrE%vv4?R!AN!I9g4-jInH=+p zAG7o}Sr3Ax2Qg|Z&+}7Zt_|TY5Y=O!`7x@;=KC_Vsr=<=fiGh~u&jl?OyihEzAWOH z&wcrtV{&}i!!e6}Im$6hd{M1f>I=4_CH(mkU9%Zn836f0#YEQw!K1^MO8lcko-dfs z^Y9l)Q%KbtWQB@}ZU@pIWTh|NIp@_%{QZ56FRBmM`l9-9T_~4UdU9QdSHHgsZMbE9 zxIVPymi6KK(2iTyhwDR^WIp0es1MGW8$#Dvrh(vHRU1Ol$;CCiyZB>{`6gtutm2q& zLZw;o`JGf~>Bi9AEcpD+WRe;z*sd&)O`!)_uwAoB;-&a^?&XJCkjRzrGKk3!b%~I* zAm4@tNfGK9=dGbvS^W2}hTdTLG+*w^TSI9P`Rs*!wuU|MLJ}6EAs^hPheG2yA9Y@EC{(sT z=A0(n82MJ)UqbODa1RXMTlh;Tc>vX!-n3s0>Qfl%D@9AkoJpDv#F$j^2}nbbBcWC- zYe4$L`sYZfH%V~zcO*2BB)AH3B$UlD>TL8_Xby|I3UMs7K#Knx;<33-p(2@zo@2#lVNQfbzf9Z0za!{mXgZ6k;mOb} z7FC~oVhRO}X`UKA^{uydVlBEq# zly4FFGnC8{W;q?2&hiP%nb0bdpgw0q8zKa+Vx0}`CJDyj`Opz5{y01zI?XX^jGYhV z4y7LRug_ly?UdrDx)9n+67>9q&=HPNBjHl$6pQNTOQG{Ds-G`~ida-XUkY6#3EFij zbjL8PkCd-qtX>M0lOmcwA&=%)LX}va2AKrwu`8ikBw5yrn0UG8{`!)mA_ZuBdN>=8=T8jlNVJfiYq2dk_m!-3aB9 z1lJ*NhU&b6F~Rc%n%9>kO)G>{_;pCloBb-aRQn4A@75^h{lRhr4$mAZW4z`v zCfbW*slf6-uN%t)AQd512``SZ3^7kYs#0E8j@bu- zvtKE%C(9WSJffBI`g5x27I6L!sY-jpNaWZUN-{1&@C({yys1(|H%Rp=#FX{kW9bKy zLNbSCILMnM3nKEtZBfqK$T8|1w!F9PmVC;4dv3|6ymyf0BgpxE$hm@dM2df`tl*uK zq78wqvxZ`Zq{yvP0I4>E-0dwQks}kwVI?n*L_YDo4`M2LCrE;8dR4qjB*7gfRlH8G zQ_g-j^)us(vGHBT1^( z07}Pg@u+u_W7JXjQ7jb}d$vem~s)kA4VUnOeN!}@rQNKGRd1p8u9MAX`{Uq-ii~8N6gI9bi_H%~z zP;0p20o$~b_X8E=;?ppd6kO@O;El{g z$rAWQl~RzZxAz7~nm@Pn_R?5xLe6;oxwrQ&i_=C)7E1+?3Y5=>EcgYAN+h4LsB1gD zy(KK_+D>n8l@zTeTMKkR(;J+RFDMjrA5t5#>Ozf5v&aEY(18-7?NwE%WhzV-0)jr1-y1hCOS8 ztdIIdb%OWAH&XDJg1@>>@;Z@ZXe}Yr%_JG# zXDn*(&hQqK1luCRTh1|RZprXgN%5a|$nfsj_}`wN;Z+FqoiqHg5*QYEN@(ajKQbE@tO2l-YSwT?L5Tb`tJj8FNtggesldpujpG$ z6|C^*dKI_GoIjon+v;9;yN=hGrS1T@e+ugSi8q3!I>=vl!xMa7rWDcop!{~#XWm?v z8LQ#Q*#w^8^A@n^Pr?(#Q2J+HF6UDcWE92RB*}np*}=2+6jN%eY*!O#}=>_7DT-qjE@d`*ukVW2>?J}P?LGWz}Ii9_PVyK@JAZD?5pA`SAj=5f4 zmZOlW4aDSn4Oz~D;M1nLUSdQ(-6-a`6b;`sjWhphujEcypXhdSk6YtSCkc9fjaU3T zS;KM=gIjrxSBvFAkP(pc8gCR!QW|ek8Sq)vJ`^62QdX+4$BpmE#9jAGF41_ zxuV|YZDFYi@)4xk?ww?54ubu&!<&0Rrg|0x+rHB~%`%*0c6!-A%a{ou_)g33yv)+z^Y`9PlHhFOd+z{=eDldJiaEjZLK57g2(rr?cL;M%(*}YZ2HEX>AjLo9*zM)s zCMAE7sc@#noOgSjNZ?5m$Ol`o$J<4cr5ymd1~GfQ11$ft{NNoW$)FhfCAjm-JN+x> zoT1g|0QrFY==J`M+D`Sk4`jbLnIw(gVG;*&$SYYW>r-15>g%Y?qgA_rlVe67WGExqh3Q2Ig{WPJnFTQBE~>IxL+Le zI*=7BGjyvbP zIxK7U$yMbgFP$V)y9&pq?$FZ9-a3*DZ6Vb8C6Fs#+oPCIhFAlF?=vs*o+k;`^F>~7 z7InNR@&>S|<3*7-j3hW-6nSGv%SX6IlF|9}ng!<-`7SlE&pRv$~T1@X-@+lVc#Vz?1kNNtR ze2T~9lVoZGpoZCyPw|-e6WA`fO>y=9znG3v#At}Yy{SY@vJ~xY5L{W6h-rxQG{r=al=epeHweEZ7J+o%bnlBTC_cY> zva=^PS@M&RT8H@6IZx^(i+>hU;mLuXY?4g+C6IAuCr|o$vRTq$nUI4$8SKgC$t@tK zdNRzDieyeC(uNZ}*)mx!#H{o_VJ|mLn*SQ|5udPknkG9&@=AHQ12t-kK=uUTDA6?8 z4}>F0)1>zr`JA{$K4-3x&v|R)GaQ6tc++HbB6=r{k{J@ESM<%3g~*4R znBV`EWekHkl2={=98ccV$$lD{rlnZ6itF*K3^|0UwT;t&@Hr zy#8vP%mm?a(I)A)N^<6L(Jpx#gzIeEB|ZNLJ|oIEK2(l^j>#C1W}ZCh>(w!t3bMWW zd>hGiW>-(1k3K6vdU^7yC!Lf2e}>FK^mXV}= zqieDge7N6tO?Cs}e&03O8-%@g*Q8e@=|0^xIb3{npYEDW%lPb;OpiqN={H{UZpo5L zB<$rL$sV~<%{`NzLUh#Xne+qUUhbK!0O20oFERO$&j|CVZ=afeJlrqoQHVL~w@~&^ zCV_CD9*}e{iVyecfyr)>j3}RTxZL4AI2jtrxcD1NYW5K zZ0Ez0EkM}Lhb7HH*v^L~Z6ZnA`LLu@B`WO0(nA7dysdP z^Z;3;q%X)SB||_qI-CkG2iac99U#4xJPvZYlGz}aDftrQP9-ZqW-8gRy434)B~3wo zQ?esSas(Cj0%@+~M3CK-3)M6V6WkY|;g3G$heF(6Bo z+y+wncxrwWq@|KsAO|R!4>Cl_a*&&q)UG4-dQ!=jAaj*;1~L6v`u-rBDd`WgqmuJM zj!-fdUj{Pjgpxl2Pv5gaWRa2{Ak|Ky zp1vSkDj5Q@r;^J-PEc|O$Y>>xgWRuVHpnMRz63D?So#W(EtG7SNWJz}(iEhxk{v-V zRMHFNMkObLysBgv$mdF~1=;Xq>X`zvwUXyR4pj0!$Qeq$1-Vg)u~Lg?mDC4WsH7E$ zIfbR~2GUr`;UL>9IUVF6B_lyjQF0T=7$ws{?o;v#$P6X(Kt5OUGf4haDlB(WuWghx z2I-}w1IU?5_5m5Iq#ww$O3ndUtmI0Nx&vAIogh0XnGSM-lD9yvRk8r&NhQC7EL2jr zp46*&8p~=1(o{(okUf+f1ah8|0U)<3xd`M5CF4QfS8^Z7A4+C`Yk%atAnz&Z2=a%Lo**sGU|Gk39Ij+2$Pgu0gWRHI639zRo&s5< zjUV1C-1HIYY^Oknu{EgFK|9c0;MxTS~SBS*)ZpNS$-2XMd1RO8SEwtmJ%< z!Ai!0j8ifhWU7*9K;BUDF32xR7K0?`QqO9T?UlGqrC$3f*#_h|CEY-VDmfHnqLP6i zk0`kWWWJJ#AipYk5M-mFR5%l)m6Ew2dns88a+;EAjieT1lr#dlTS`BX_? zkY!4SfYdmT3NHuQTFD(CU6niza+s3YAcK^A339cP6(Ez8Y`B@!>oFxwLH?;^N06mT zdV$#Usrf{Z?UW1y*;~oAAVZW)0l8Vpb0D86c^_nx3s}~-AV(-MjinanE2$51yOLHQ zGnDKG@{N+iK{gr2vQ7u-u4E+08A@&f`MZ*7AhVRb0`jwxc_8&KWLZCh?5L!CbE((S zN*aS)prixHR3-a>e59lw$gfJy0on8-mVPBjS0#6X9HnGB$dyXo0(n8n0+8>N{0>s@ zVwP36Lh98?Ni&cEO1glIQ*scmr`B=$CAb%-9fr5ITGX;C4)gmD;WhcP01}FZz_2hMsfoysS z^?U}hyOL!f1C-RPebNy|!1<9OQ5%yMPQ;(i>#Fl2bsYDH#s(wvq`TKPj0C zQvGk#^CC!lC38S}EBOKBd?m%EQi};n8iG8hq%FutO7;Z#SxFxdH;Q`B1Zk^e49Jm6 zZUY&tq?e`EL2i^E2-B?C0l~j8%>3sLE0|5Q&w-q&F4<)9B)Zzmr^+Eon zq!q}9S5o0_AloQ89ApnAr-SrWG7{txB{zZGsAL+*qe@-@`B=$3kRO%&3{t#`3d^^V zdNowi7^H)e4j@M;*$3n-CH+9IRB{f;6eU-JJg4MNkPnnh2U(@$Es!QxQ}Y6l&Psj< zIZ8?0mQt^QN}7R;RMG|H1|7(RBkV}*- z0hyvC-%4unu95~ItCX|`X)%_icL&)=$&nzZDH#lMt&&k7Pb;|vWS)|TL28X-S+9X? ztK>6~-b$8%oUNqhwoNS_INe$tsXuN|M%6uQQc22f0(pE+8)}=?(I|l2btHjA!Y?LE0&q0CJ>~ zsUYVlc@boyk~ttVl>7j)KuNKU)FO91OK%9WwUV|VU6kwza=4N{Ag3!i6XbFwV?b_F zavR7)N*)DyQOPWjc}nJkELXA|#7$r=YPXeowN|nv$X-f1gPf>je~?R+^ar_H$@w6! zDj5s%y^_fw_6F*C2BedccR~6pSqw5#$!d@%mAH0NuZ2ps0V$ivvbuq6spL?Qy_5_D z>96DxkiRLJ2r^m8gCMh%%mi7YWG+a(8>we0$o5LAwU=7-QPK!xn3DD&w<_rY@`94S zAPbZX0V%tQrC$!xTFD(Chbnm-=^rj%KmFx&| zppsr7gO!{JGET`bkVlkU3-XDQDIkSgSo(7y&6K}(y zbCv7{@`sYcK{mUUdQJ!Freq|@kxFg?8LVU)$Yn}i0hy*`9>`oJKZC4NQog;^tHEv5 z(-@?^k`5p}mFxp@f|7n9S1LIN^SJe^=54WQLN1K)zNo0HpRE)N>KYmP*Eh?4;yAkb{-X069U)hal%FSpssk zl6)tr#XU+IfIO?DHOMR_-9f%kawN!aN(O_}{X6S53S?^~w}9-YD#O6Gu^s^kZd;Yx}-N-geI(hy{plC~hq^Fg ze6M6O$nQ#?0cms(^}GwRo07#K{gtc+xm1bkBK4Z0WE+s@lyn36Ov#}j%asfS*67$=58u=5lMI6o-*f4c`~<=`H;+!t?xC#o zH$ab0YJ>0{mSd8Mdjy{m=C+mcp53v@Js>kcj!PboB>kn}h2j!FJE?_e@iLm(;lSkev;lo;;-2E^=;TcIi(Ug!IKk` z;fQjpM9+!IGa#)z3E#3fFmIYLN$ zBlUxBfn1o0IyL!QC7lc*Rf&Xm15ZmHizIyy=(OayNM0%DTR(%6mqGZJ z)}UlI2;T!5l)MMRw}%EL^Fa76-k_vMk62TEr*BX)LP$B^#T%52j3j-ZXi#$H8ssTN z@!jn~$qXU!{pE){8#5>wzK@g@`dIk-#~H~|5Wbgvc2e9=e8M|);TK5HOJ?sM$T;(; zZ}}JeKD{vc9OOBWi<1=~Z+bG@`;15i91!!-_x?sEgFx6mBa?GL*ghkZ3nP)5e(LiX zncOU-yw@N8%gLUMPVPb!`^M;GdZnmeqEFH*ls>9_q>l={2@E!26$;Kdj=Xz|?283^gk4<_AF&vS`Cez__>b?Gp zfKB~ZUy>Q{;W#!nS$bqFOW(>ImuzrUAfw`!LYw=Vj!RmCe7!ms--Et3=>YPZC-?ZT z99)|m7Rfks`WgOvP22dl&XQw5-t}LJ-^i2k$w?BW-}<;d83git3)!dFC+C8c|4DLj zBqPe}dD6z~xjq>k$t&f2|NZ)8yb#0p->*+5L^7egnU7lHM}P^*tss;9Z^R3k6iNC9 z--P5X_?)ahb0U%68)`Zs8Q3SZPrBc4NXADp!mRRTh0$hWG96?qlQ(;K%@dRUN6S7v z$baJ{jNvyWCxM)zEnMf%=_Gy+yTPx()>NC=o|Y+JerR5^_rCQizIE0yOXiv zqkDOBGBJ`@%31fx$;}|F`{d*{5Y~Ni@^=u{eR47dgms^sJOskJPfi{eqIJI~c@~6q zzbBaq!n)s^%m!gi?@O8;6Ze;4Ydny&jbwy5-tW^e{!B||N0Ro9X-P%D(!TMJWOyWL z-5*Xa1!3JEPDX*S?hhxIfw1lmCu2ca_lJ`kKv?&OliP%7-5*Kr24USFNv49Z?vEvp zfUxe5Coh4p?oTGOA{kLW%GW)76XTg=NhIUU51x$lJ>i*Tt7AjmBZ!75T0{iOsOn?v1Rx^`ZK{zXznM?xVIc{che@}=;7CT8 zbA9_C%s>>s3-MMm8-xnqO5OvZ!ncySAlzSXC0|66_Mf+sC6T1x zb9g%$K3Mk7qzC*Ldi+uFZt{Q-{j&7C$)h0bWA7$UgRt~>lNUkQd*4l7jwG$uyUCl8 z$i4{QZ+SPFk0{Qg-b)&sA$zcUUV6fNNgt2{{`BAH@Lz^`FBut0`mO2rl3OBqMZZM% zUUEAKTjRZCG6*%lmpllpnmE1B9i| zPl{)WLY6*1sTE0D`uxPgho#R?8VJ$vEX_}b!G~onN-hOqS&Nd(L0HzJWLzX^S&Nbz zBayzb(9c^IB@b32VOFp>nJL5!^?l>oO#`VtB-G+k6Goe%eoXi#=>sy-`waKwyJR{@ z-hcT%M17wu1DSV>ME#I-KU?w{=c6w3QA?AtLdskFsOvoWC3zb@ldI=q&dZVp=SUl} zeU>MUgy^>fmnW~nhwbxw@)ii&=lA3T5Vp_n$-GF?_W3F=^bp4)uk0|E6GFc`> z$LE#F3J{LZE0cLcqh_5yuS!-$a$Wg9eci*;Vylu9&XamE=T*tTNYasHRWbxV)Vw;m z0EDB&>f{m-)^v4p83;#-)yY+nq%~cgTp!7}@_h@UXLT~Ol27<`iPcH@`9a|b{VtZV zy)F_m*hhulVr<35fuvv0^FAX28E5YEKA#N^K3y&m@{T8qJjvUBAPYQM>PgWyxKw<8 z^W&Xd)Qnzl|PBg)&J?7#Ej_g78Z0AwQ{70z)r z?Fk@FluQ8Wq+~WoPbGhV9PdfqU%k|{P5u^2A5ng;`m~HhS~Yx+v8L@pB&- z2S|6HPnbDW*j^xqdJ@)%D(n%Fq_em!?0Mo7$DeQ|xrH4K622UGwkKQKrej5O_;TQI zPny`b#|e4U=PcxVkaz%dd@5mB>ILT6z;ZHInq}f=%tb>q3$Q~~9*O_`%IZRz*%|O@;z`)=TU&R1h)V0;!nTb>M(mCK?=rNo z_ePS=pIg~!LUcrGWoLqLL~3QPygB6jijGLz+NmJ?dil2Y(OaUAo=@A@rz1&6q&9XI zd^jStv+sa#L~3W}fN<@ro!#$N$(dtRJKGzCV^lkPSS0Bf)z0>dMCu;a^xE0!k-U^Y z`VzTbZf{?X#9xE>HVi$gy`2LxQOS284=Gs<@~V=JZVL+im&uhh1^L~R@TK(jwxbYJ zUY<8oBIyoN&y(;a%~SEiLAJMNfb5EVI@*gtdcmiY9Sbr5KAr8$Ldq}j zBwT6kVCR9{rQ{cor)Ermmg3lqgc_ib^Bwtqe#^w=r3CL5PjPRu&X=hHAnzA+e z*f&7f8hz}$AZ(33_TxxW&3)__mBWz-xU7e%njb~rHAu!O6Dlp z08uQfuWb-XI{x&vL*YY({p`h&$oD+M7~ap0h7ar2&t5J0l(Y1H_D&F%-p}5PD2`+O z>@*OLQT^;Ak)(C+XP<^oTGoq^%&b(_hahQLpCT$PYXL}F*4L3#F6+lieHMhPg`@3E z5Uv)Ewr>d0)xt6MT@bDoj2I1$ zwF^KF@jl^qBBt6UAOn;v0|~zhanZKHXBEi6J7jJ%)z*4Wa^9)A%%7*)3XltZK7D-Y zQ*CpQt2F1fAUCK_XCdYuPp*h%4Fm~arwpU#ej9Ru>2 zC*k)v9kd~^58C;W zq`hUD?fyc@XHl->LjNh@-Tg|teK3+yQ6PX1fM;SBPK?e)5leZ9{qUh^Zie3p;{{7Unn&5U`> z&Uh=3app+xGuZn)VH^B2`sla!r`t9lyeBo?b^>W}y8o4FU(@Nfs}TR&y7~AG_UZNn z_*~@4FrV|2_B4aNqZs43!a24sVD6ykS2@#^@nebr|eiEW}?q0 z{O;0IcKF+(`7Tew{P}4+2IK)xruZ+VKW!h3WJLKvulSzQIgq!+NB7s$c2OmAt=Igl z{aK=-&&{69uua~PvVQY9hkDJlEkQa@mn-_2w!aWlZKJ%oJNhgJNj#bA$;!yMVOtQLjd_2MCYBS@s~1?Yz%h-e;CQ z5`-iFEPEWtONksiv+Q7y-F#FiYnGiUB-TA#wav0q-;W9-sWrr}NZX1JQnI-x@7XSq zq<76evcn>IMSIj7dl?9O)EqkjgbL@_*Mu0}JDy`#fbdJabL_z%hSFat=lOk(y#j=H zljqp0L3lTLjvX&V?8$cA`w)D1?p|mg2jL8Dp?wyFXZ(eBCJ5(j3+-!>r01`Nwr(#k$9$3NS&=t0F7jXF zw|jvc?$BT?s-xi|nKQOZ6QDsQIyoEO^z zK&WT2?eCBA%KK}vJxqLReBh%hV$?B+qMpTe00{LgwiV~Zd}>h7V%t2DRL^32%ehjP zZJjrZea_$5_duxU8{13r(f;#|{X~3f9Ok3KQSgoZ3Q^Saja>plJ>S?yz9)sfOg-P& zrjew2zOlo79}RV9`+RHf2ce#CZ3o}~D!0$K_7U;X_W9O6jVS8**3JZ>o^Ne~3t~R1 z=UZD5Nvh{tYc76(6?G z5B5j#sqv1FIweN^hA6hr57vAxQPlH;?JY$6&kwdwB&nVs?C?dUdVaLOfKbnmcF7l| zdVaJk#Ygr0XbWG95B2)$^kr5J{@%M_W;r^BH}SduIQ+J0eN-{A7#GO7;9~cLJfF zpY4jKrFwq0yNi$N`PuG^DC+sy_6DJzpY0SxQP0nIS|q8SpKUMyj9S=V{f_jr_nZ73 zOgkEcdVaC<{PkPq@$eUWjri1<>7$;CQ8yrpdVaCDfl$vc_6|f*&o6dLB&nWX?65Ya zdY0KoK&WS#EeGNLT4tXXqI#Cum*7J^%j_%=>RD!IBZ_*K+4mz!^(?bv+Lh}0)jkhG zJ-^!KAk_1#eN~9+`PKdtKGgH8{SbtDezkKDMLoaT`H`f0ezjxTm+Dz=p9i6y<+cL| z^(?oq3Q;}F?LXl|JzxU0XBM$LT*x0*3sOL93 z?I`h~p5N^K;#1?;WAdiS?IG$BL{ZOg_8AcB`OWs}8}rfe=QrCwl2p%cw)qLAdREwT zL8xbi?SFi!o)z|D@lic1>}W($&k8#hgnCxk<|mfwSz+5olImGuhYTpy^Dp}n2=)BS z&X9cc{Pi#UhWMzSf7$mCMLqwr^FXNQU$)iBrF#BlJ4BM|@lj`$>iOMnK12xh{BFme zDuny%ce}OtsGi?#8$?mh@3u1t_55zHL=^jv&pDD*&+oRw1*Ljc+Dk#GXQdr`Ua6jy z_6qS)JuB^Xh@zgA_7)K8S!ufri}`5(S!u(!|wvG7c{P_>t2~pJZhwTPJJ%8ANh~obG!w!ig)$@lfJ|$)CeRAGxJ=s5H zVUGc!p4Im4>7{yB+mpnn#xp*uU5pxpDC${l&jF#H)pjVNsAshu9!aWawO_B3vWA_S zH#hm5|FlhJ2%(-oZEg6lKmTc4icgKteAJ{EwH>0U=TF-OgnIt8S0ajf{^(d~|;qw=bfo$GF}g)MMNvL{X1%QzJ?B7&m=psh*r$ z2|_(NHxD_peR8hwa*R?vIaf=F&YyG6flyD*^+y!-Z z#;pXQp1dmup`N@eydip$)AQyNf0oI+T0&G$-Z>EJ$-4oFqMp1P97(Dt@0!0OdTI^w zD+7o7HCA^F2=x@)fVahmdJ66&@u_j9kDB0XQE-D0#r;)qLqVvg;ASI=dJ69SNK!oo z_nN;?5RP}wpNsBK5b7zqx**h3bk#SEQ93^?x;jF%eTuF=2=x?Q14L0z(N#o}>M6Rh zu2fH%dliIw%3QBRe5j|){Zo8YPnr7&QEZI2ZZ@K*rg({%))o|>*RqNt~)>lR6>r>5(^gOvW+IeF86nlZK9AQ0-Q<%V}IZJ%21 zT=A)~@40z%dW^alQPfk*jRB#aTJBLqQBN)ROeCqETCUs9rR`JOoeM%ewcYz&O7+xs z7mJU!Pi;3EQPfl0T@6A#wcS`mQBQ3*F_KhIZTIM|rFu4Sh24Zu&jxOI*HS$jxLV?) zdNyztQPi`6YY0L;8@NV@qMi+0(@0W18@L7sNm<>`^Y?)MVa$eZcM$5?(Dgd7RL_QP zU-7B&ppP0AqYg$C^=#;l1fiY{T^~eI&xWplB&nVa-L$?^7S9)T+}9w~Q^zgsQ>v$q z`%!$fed@U15Jf$8oblIY;i#mZI__{GI$y2h`bCoJspAHoP^zb{y9be2_OZC)s z_lu9}sp}p=6!p|~&wx-*U03_Wn2+kI>s%zMp1N-O04ZyyVR^IdBmUV`_ag}PY~;F} zRH|nq_nY|CxZ6i{icxgoQau~FN!Lmg_gCV60imA6 z4Y{UNPvTaJkG4uTRzs>iy~ z;-h-3y9QCzW8Fj$>ap(dJ7PYn$GU!zqZ#|(OFnx3s^@BnkLs!CETX8Vo@)d` zJ@wo&MDcj9=T=3M>Z#{?PASz>-(3SjJ@ws{_lOVAU-jJ$;-h-%yW0^(J@wrb5bCM# zRw0Ud>bv5-A?H+&_lYE(uWszR-dEZ_8@tZ%p`MN1UgD#AHg*Rfih4G7hl5bh#%?O2 zsApsMXe6ngja{DyO53M_yB&n>)4+|rzqEZCxO>D$^)zq~A&Pn$xW_@Lr-7S}DC%k8 zW<-+eY2a2oT&iaix7Q=3?X!s+`j1jQo45nSNA+yt4nq|6Y~uQYP|qf=AEKyd6E`4| zRL>@E%HySa8oJLx*gg&2%*RUgG<08!kLqdYenb@YG<3^BsHdS@fhg)}=*$x#=TuKa z_h@+`j-scH_FMe(E1SCSK&WR^H@3R?u>Wl8ei5GS^Srxl%oi+(Y71W2KM!XN-CRQPk7O z%>bdEM$Xlb`KX>ou2CeZo<`1WT&ia?*Aj$!Hgnx2A02--bK8lJ>e!kEVHQV{BC?0UB>ZJ);O3h}A&xsU4Z-@j<= zu0s^{G(#_nfbh6z;yw|g>o!f?SMXuInz(O4Sg$5-38J{)o493>r1fgz z%u}ML%XN9P&jUx1tPgA!TQPk7a zEsZ4A)6_M3N6KP9+{&E_LOol#6>pX5*~*?j#WEY3APltW-}kH%NSRTy5sgMHKZkbHhQXr5dbV~OFA_pMTf4E6j~*9WyUoQ%^=$37MiljI?b?D+&(^N)*QI*4b`2s) z^=$2i)hNbsp6%1zJpw{K&0W88@nQdI?w%GO)zjR)gedB1?q-2dPjfdLQQTk6-TRTG zdYZc~6{UJwxGO-Yr-f_OxKvLIcb)jCo)+$AL{U!*cP9w-v~ZIUMLjLt)JRf2EnMxb zO7(2xb_b!JZQQgbrFyn;`-+e1*~T4=DC*h9^#P%tZQK$>QO`DRStO~RZQQ(;rFvRA z+e!%av~(S|Db>@`Z7M#hr=@FxDC%kHT7ghcOE(Nr)YH<9j3m|L%W7Y$r<&)U&Od8cC{WTQ_b0Qa!ER*C5o>+Bp#F zY3+U#qIz1p-{3<%t=(!6>S^uF0kJF{e_FfpNK!qm-Qa^u^|W#KfKX2x_soH%?bF6R zBtELAje7!7)YHbz0HK~Xu6gfLJ#AduNK!p*+=8P^^|W=H_7y@sZQWqWN5{jqu8H`l zp0=(fqNt~>>i|MMZC&{>rFz=Bx{;)M+PcNZOX*yfXy-chFV)k|%{W#F_g6dDReW?^ zqMh3dQPk7U^#Y-uc5Vuy*nir&X_2IQ+PQuwOIbXhws$vxuzlLQi33XYw0F0QkDgE4 zyL%8tJ?-5z5b9~~%qcM+?LX~Zc_gWx_O8bnQWlS|?cBv6)U%yiJh)WPc5bxz=>FQy zU4tm<+0IP>p`PvBL`1QDwsUtxlIq#cy?<$`o(`_oNFmhI!HpeJs;7gq;-h*xxJ?m7 zJsn(A5bEjR9z_)Oba2l^lIrQ;Ui(DKI_B2Axpj##+q*wOsAqe(Vs5FP?OpYGk<^&s zqwa}Ob%f}BqU~J+5bD|94L}t2Z0`m~lIq#s_4!@O;{NLBt^=W-j;_y&Qav5r&Eli& z)6w09D7H^WHx-0>I=U5zqMnYj6SNo!lHmQBNl~Kax~WCwJxXrFuHMmq4hev+Htfsh-a64e?Pu zo!xtgqMpuf9tibxcGLUEeDwJ0>}Eug>gnvppIEAA2lo*O_3Yq=olvT02lu)7sGc3% z*NCE?9o$k7>e<0{kKZ*)pL5v3^^7Fdvx6HFzb}#QuN~d}Ak?#?s{rBt+R;5CMD^_G zo`w(g?C4$up`IPxOhj>i?dWDllIq#f4Y)??ev@DSJLp$qc5=6aP|r?o;?eIhy10YI zNA+}ZM$_Iw0(AV$BU2d zubthgh@zgI-I*ZNv$Gq5DC*hS4T~hzv$HEsld?Ge?BaF;p`Kmb()hk-dY^F@x4ZbL zo?YC&h@zfdTyGHS*~Lvq6!q-lW<-+e*~N|dq*PB=_dE#obahkbl(tV-_p11)p04hn zh@zgZZVm|bbaeyc`zh)1)zuA&B-PW^8I$wxH2H6V_`h@Z@J~>ff_cZM$pZ=8Kg%Gz zBK*JqSCKPcb`LghK8?0uKJqqiie^c;J6{o;!oQr!*9&R?MtSh_=?y~K+wG(EcT$kv z0qI?kz5#ZHx8ZLU(k<$T_`K$`9n#&R^=~g_(uaf7UXS#R@Vg6X@>1)+d=a-74E_E( zZvFkM%BL#+IP^Xby{{qtK^5s%8%sNf_6zOR6Y1k&+1_jyN$1R+*gggJ6WC?Z=FJ~f zq#0Lg{rjyAL`M@?=11El^1Rs{+xJ0Qc+MOQekAxYYfTr-Nq@I%(@|D($mfv}w6J#B|Z@9&MS~Gumn>uev!jrpryAXmjSx z(B2ik3&el^%O2n|j^@qvF`XGteZN=~dEWej?W?0Lnp%y5t}?T+w|P^|Y#r17`>?@Q zNGV}Fy*P6J)yU{qFgL?*CipwxGR_yxSJ+Nn-2XC;`ucAs?GeX!Uoz7&zUGXKLwUn- zSNzCxW)9-T=FNPhWqk18J6LPFV15U$);N@(H?^Wo$ECWJ(xF9KA}!-p-t1IqduW$k zk=|z=mVS(1m;Wf__W|rG*y84*yLPk%W1}tVd9?wyH;y)ES|QyAY34(}&fv1$zp;%ZTI^eWg|6;cj4^JBcl_J+~s%-YXydBbtPHT<%6>n%e$etr@y z^%l&!_|EW`xPp;Pmz#!LPEbJ8e>?XmWF>JaO{Q)c$@apA8&;+fBQlrQa5Ft=lS zmfs7`d0uw=y5jy_f0m=?`=-*qU840*?q=p0pJV%ot;Fvd*juCZZ_7tpFyyTNQ`pXU z&S#!SJo^L3sn@{SuRcP)-+=!Xtsj44Kk@ThaL!Aa-{#FkC-&_7h`-OwnMm1`FJhmhU=fT@h~1x|EDod&NIPZ`bW+L9{v_1-^zX= zo@w?co@ahQ-12A(W@WTRlk;y~hk0hLXsek`qOESWj<($F6m1Q&ceFM2`YPlX_It=L zT(^b%!hAI37v>QmKjY^SAwOdzKmQ%dn4kZieaz2)^)ZuQ&fFNE4^I0L`{T;^oUXqv zh&E@kY0e-1#CEwZ@$J_xl<&`fxUOLOu*mb~xL_;1OZ=BJr}=dFI~#EqWwt*M-~3Lu z2mg@&-(cgs%%^Fe%EZs`>G1b@v<34n;&?q1wuk%{W$bS;oi~3*TQEuc;8!#oMEQey$y@_ec6Dq%Zb1{9P7p z!Ayv@Xt;ec{GKead0ij*-`+kG$o=fm(9c<}$B z#NW?rF^)=Hny%3?v|r9_7HwYhYX#1@PBC3DdwLtrH#|>pJUIyQoUh4oUNn7?&;N8g z&-Yn766KDIwxHMj)4{`j59f`Sq2oPpjzjC0&Y4ob0_O8+{iI#leg(ZQ_**CGpDgbh zq;HRw>u^PLPfVAYN20A}IBwEkwimFysN1I_KZz?Se;NFpXmf_wA{*L>t!Z%I) zmovKsUV)_V4>7$KyJw8gn{2+^?_5`8d0BoC;;Ex5zrW^beR#YKLA^MCz8>jGuv0VJ z*^fB?rR9DqwR!U-;!Al>_wz5OTNLS=c=V||4*#0=SzZfmogZvYrne>Qa{W?IHCt*A7|1>_- zpY;to!aOYM@H~_owu?pimHas_tf(h`3laY_;!4v6^G6k&_ldYp!0W2bc9wi;JI8c- zKZt3TFY!6k6@Jtw>740-{J39P4%6BF%yFih5bm@b+- zqAfFzMO)3h5p8udKUnT>-|jy|o)`a0Jmy;|{V(_xcM0(Yvq7*vKKO;dhLL*||K&^z zpRS6BI9_i(7O%SsX1kbQ(R7Wr%=C=5S{x6*`v;N2U?P2^L82l%XEMZNZF-wrFmNw#?iYZ8h__w|T!mUykW=^Fgqc z+9&7^f7$)`SNVtiu)g{KRX$;T9 z2hR14QtQ8WfbAR)E{$n_A1B&^xnr%{{dMSWQl9wxbqVyV+Ph1CX&7xf?zPCIr5~s3 zIUTTFbmYyxYfTrVU-^2L`jHpW-*W2LJLZ!&Cq`Q^=SEvJW1=mS=LdX#^t%y$li(-* zW$>@2{*s^nK2`Kv|9C!!Fb8pB^SEE&_ha|aenrzD+MH<$`|s*oUw`V6ev#^s7UuSO-gv)Y?Dc| z-%@|4xV>O@h2LJ$`rjJJ#Ib)fj?X!imY??9L7Dh$eVEUP5R73&0I{r818m*ee< z=;z1h`ciM+-&}k7)R8my$GE(C6y-dJ^lYR*fc+G?!(oh&Jsn!c!g0 zx7A*vpZR3%!nmFNG-rN-|7vjFkC6VGH_duT`I3LpNd9H!fXJ(v{?YpD!c4tq?j7Rt z=G|y><_n}bACvYenjbw6<8?Tnhw+!?{)xD%?qja~er3+^zAo>>Ci{qvCeh}Mq;sYt z_+A;#G}n3l+WId)#`uC6ihN!`zHfnl1Wp})l%#WJ@V-*-OQOx2tE2Vj4e)8;PlL<# zc+tpx>h!)k>qXA=+HKw(*i*_~`*yaIKR;&lX8pI>Px9#+tsf7N7VED&;_+0_>ybm? zcXY;&>65Yj5^ux&YkbC!{GqtLi2HJ7<`wvTRN|jApU1SnKL`E`(yT{TceDMazqF6G zV7f({GvxdDbkNls{P<}7?^eZp{rnf4urKOb7__MEBHOX9+P&~SXp{aF7z8q&;P>Xlx1X6wo4 zj5d$?`R8Baxa;p*Al(h+$ofga^Z>7_UDzJkdS}~b2J(3$V?RW?;epuS(H0DOR)03l zagyf~Zs++vo0k3U#|xBmMzp^E@qYfAd>C{|TtSa_uJ+IMr&jF>|>-CoQlYUSzjbl1z4mebJRdKwZD(5+WeRPEA zDdm2>E^_}x(oFfi;V=5qm#N&;A(q0AJ$7DYKc|gQpnu#xM*PI!T z?d-?d?RUlPdGiqbc)alZPM%HEk9J8F`7oY-Of$b_G0s27lPRBR83*%5bmw5x`+V8@ zu>G=}?S2ix2W5T2nCtF@Ny(|1>K9xQP$LDE##_a`jB>c{dHg7Hj{~P!{;Ey9M z=cBw~n)aoPAJ6;mM$Y+MQR6;`|6*)sKG`@K4~se<{1b82`bv9l0vqDP-}iR51}dxK}&We~XJpEqNCI^-kQBRMT6@XGTdX`ggE zpPQ9(*W}0d6Fozt%|Tb*{H;l?~t zdr3dZnTL->`$g-2#|G&zFAn~1A-w?GWq;(2^bbEDkNZ1^`MQ5DEynr#KF3S^R3!>i`-{%wqRpFAk!F6v{k#S3!TR$!za4S^ zKpe+~nK4~3Z?7k(-&fv0{QZKskPiDHcS5lKzCg4&L!Py~zTPhS`E@|}%kxgmH`OK2 z$1*?v9v%Eof@M3%{Ww2w-6iNK8d+Z|Gv`OYYKHSR_G4*>oZKs^Vn4;rfi&uwSzIFdfbt;qNEp+h?Y4Ccob} z4%9zU_9HF($$pU+%u(3R`P*qo^SNi~cLg1vx!=xaTl&Gm__Kl=%-v{&B9aaAyzoFwfg{m?(3i1Z1tQcill zljGaJzk}!M*l#%wu;1JquSra&?e-|rPr*;t7mJt&l*PDk z|D4yu>++uw^Qnfo>KZ3H`5aflNO?Kv%i;N@^tt??Bm9MLAcpfA=Y<=d9O|>?dPd;k zuTk7C=dsG^s>p;Z_*`N( zzrT(v7pv^Uo_+5%+oIYi|D;<*h3|yPfZg)I39u_lD8>^GCG)eCcf% zm-yaC;Ng$yosix)`lt10J^ydD*ZQ_cwmtcr&DpU&{<(a#>!mTB?sx7V@u#1!|6j)W z=f|=Ax@gx-^LV=h+e_zH{ym}+?w?mI$%px+mU{RcKW&z0>-|#9w_x5w{`AlCg>ie{ z`~bgfdO5b2pDF#TL9|8FJldS;6fM`?3TW?~IR@KDV*6E<(xLw`&F7?OC&2GcSaRCz z`i`t) zd9S1^^(%}Aa{Q*8y5)VT^nItj&X)2|$ymNu#eT&!{g`HZF)fzkTDo4$b+4CWIYsj} z%H#SK*K^jj?w4)9s^WyF>z&zhm~L>6?6(e2|70sTA=YFLw zmXl4BXY)I#iu~x$e6sCCp7mooTaL7U`rQ71s{5R%*N^-0epS(29Mk?itO{vQ=1U#a zIUem*`MrkF{@kAR&!)5Wm-`~=duY5)<^7Udpfk&v<~rd$(3Nek(tcZ}*P-juRe78U z^<#Ump4ob2{W(wIc`|!m7Vf`4g5#doeWm%xdx7gy{@UZyc z$KT%^D*c1&^qkjqi#%@*!1io9+aBvXZ&=^+e71eF(@&3W~I+MauN^V$33RQkEUFB!`#n5UzyiWkkx*v|XUTyN!leI8e0Igd%7 zPh$V4mG<}Vhv0hh*bC%%DQ)-kxaN4p_s4mha{u!DpWUzAzgf=oy2d9S_pH}%&`CWF zhpkO_I!*>e!=$AKNz@Pnn?Uwoc_phtgcf8?vUDbH;*Znhx^J&g- zzAfih^1S&L?LfW??NfGqJ z%1~EpEAvd`bupceg!ib`N??YzpH^X*J-CA&Et{z$ha4NpIz$9wDhAKxPM*@ z*Bj!Orr(Ki{`wTp+0d4br|d`RcupNWo|*m_I(S|7RVK~%lezr|Z2to~$}SG|D46=u z7R^@Crq2s;T=;h_+eOOt?oa6KLZylRUy)F2^E2Ax%>%0vfZ*C&?o|yK(PY<5epG~tqufhL4 zSnA1+%d*|Sk3B-lll$N~^90gW*^@5`{^|F+&WdUO+zxE%c0O;PGs4%L|50zYK2`Co z-(T(L(9(Qvy)@2$m+VrhH`|Tv#QnzfrqM5bKCm>Ov_3q4@;M+LcYNNJ+xc937nINQ zpz!p$DXymk8~(!cgrUdmi@3_$L%%sS^1PAfuGgKWAM@cjBhQ!1cOCw!+<&*cDbOeN z<#ATTbHnNL!}2{lZcoqq+#lKf!*sA=e@{pI@Op#KC0EY(uly?O`zt?r&sKC+_LJ|T zrQ@G`ucc_@do5-7UQ0E7UV}RM9)7le$vBy=6U+FVuG7AV`u_E}>%YGMKaRUh)AD*& zzW-J*AJmuQqm-xL`=GABo|jaun>sijX^Tezl&m#vn5S?5{WnA{XYrY4P zeSdddoa@O$|0exN=5INyGyCV@BA0X+d6}j@#y`A{co}c*t@#T8D0VzKHYIbY6H1@{{xFn)C5Hv7P&iHk%*$`q{jBAm&>z z&m#Zq_i3~B&!*R}oHgsSt~lQRZ#!E0E1zfLeeZ0#s`gKPQF$&T>lAsV;J9Pkx8CsK;-%zS(s4z8mLtyzdtJL--RvzF)}q3jOyzV|%U1 z!|@jW=3?CD_rO@sb=l*QZ#WLaU-mv6`zg=YrRjo^<2QW{bX|UY4~TJ0v;QzH+Y7o* z%=uxK%Xuli9^v>yyRQ0kd$lX1AM?Fw`7Tfq^VXc%ByLa7n|vOZ>+&++Nyqc-a}X7X z=l2vnnuabYxyaOF9kJokV zm;COgTzC5KmcgIvo!_Cn<>3Ern$H8RD~{K_ET7lWyf4Up&3PoP93Sa*p?v?5&n^1( z>iByARd1Je;QJ0d52xw1w=df}eZS(b{nB|1+r89(ee+5E{!j0p+|_da5A7R{Ki1>_ zv<`mXljXC2(UQ}zvhFZWkkgNroca8}9=Ao@pS-U2*QrR$JTSeV)dpO)7vg)&VSM9x zxHGoz9<9G_jkaixjn>~^hRwmUooU(rYM=f7Ko-*e%0Gy9>8 zk2%A2GWI|6tY2w5U60^6E9a4dc?LSN=LOkb)a`4JOY2#>J!jazvi*+z>7OW<>A6U^ z-(UJ8pLgZ{%jU!US+3mwDHvHl;P*hvv>($?wx{m}@jW1JUspc7UzWAfUU|Ha!1of; z{mtWqHa|}GKkLWmjp~APUYPxkBKtM-$^IUV)ML$ZSx?3>pKSgdANc&7*z~$6yB}Cy z<#|cy*MWyWc|Rb1e~$i@ZSdp$G}@}>=Le&GcpbuZvJ=30ogmkPYp%y+uM^oGSu68h z|NZ2cum3JD^3VEFN47rlK3_V|;rkTi%;$RKe@C?byQ$F@&8yLt;eC*5=98G_^9DKd z@5Zq`OP^Cn*UkUk=LclmOYaYGe64DoUi^8#I=z2H&f`GZ(ZBD4`et>r-Kw%Oj&Yuw zGv6T}<}2;yzta+V5$)~2M;Fu8(B9Rxy%{I{-oHPG{C?b0+IA*Fi=2l~w5{daKSi+n>3vvaa>aBKEv%i5AwQ_e1F6ph5V?G`;+gPWc8jL{nP6s z_OsHs^gWWnYso*1XW8=u%jb1C*CmIeywS)<(rb?2SsmH5Y|)J${*%eAD+Ws7Lx~x^5|H z|9&$1*}CF7UoY*>`-$uF=kqD_&;IUBRlh%&9Y?Zh)^mOB9?*S2wETTN|GO2qpOwv@ z=hLUvERt=hKBhy*QvQq$o0W>rMa#z z>;HcIfF3!n%gm&hPS^LV@|y}jKG(!`RQAton(MY%UYbtV`>8{oGfu||(UUjwToa#T zO4nbq{h+kIX}x&=nAg*MzksodYaGq$o*jd zT|l&})H|Ke|7YVzdVH*FJTBeeYmP%_Wcmw_`)t3-rvGn`2ifOuc^wtrlMLffw*Rl+ z`6eCr*bc1c4cLG3J1Ob=f7yKb-u|ud=eWyx@`q^eg|I)svYf7Q9emAkSK8ly&v^%_ z-x~WB>ldqIer4*nu68KRC)=;qoo2r{XQGUgoOf_Oa!KTV-7L;;(|L7vJeT?6n&TbE z`|S2o-37c4u>AH)Yg{tnRbmGi^)Z2rOj%*uY5@>y;+?thxDN+-)pZKj?XeI`?{G~Y~nuEp;X zU+>^wx!ps$a=T^I>#BF~U*F$bx~@{Yhq%gVEyswyu>E%LzmZ>unz9z%8~N@3$$kv) zTg^m%Z&ucm;kgQbA9x49I$TjObG=`_qG*;xTV|@=RJq@l{{EWQ1N$x1BVOlb_hY5) z>(hS5>#MxqvgQ15rGx(XJ62WbuS!?8-v4eoI^pg@xD=I9`>ia zSC-e`?Pgkj@1EQJcLQU-{`ZY4q+H1-Z#G4F)I+~5OL!W`{mSLOE#J^y6 zhd;}gbio`5o?S2JdJ@}P_KW}B$p)bwMQwLkugrrN^!w-8IIe3-e3`~mH!b_C>~DUj zG-sHu{QKo$Kgc|3&FjW2=X|nq{}0az%I|LT_dn9(FVr{Ozj_z#!}r2It<;Xe<7b}^ z&sF^a&ii39Ut06H$@XuV*R6Zr$Lk*1pZ@or;{4hFj%2iaPMgnb<+NY&eig3^*Og{D z96#8fxW2dhrqYi~)BZb@w+QEUvA&;!vppC`fA+Ir!(VuQV{PxdvY&B3FwOGVZ+M-+ z{r%VJbRCHEYpxIex7HJ@y06H2J8ic7?D}e(*p7MA5$(zS!nmCy_rJ4@?b-Wte2$LK z56SWA@B7sY`z`$)PkHV?eV%0i@{{|v{<(Xs-_r8Ej`QF*CfdAVn(uSauTi`oUeNDV zjDvsa{mLS~+g4_7joYi42coTRo{6^HydP~1^F_40Z{~jo66vgEzYjV>|KfWmm3bIX z`2L@imaEY%kkeaFDW-o^Y=Enf4F~X*^a!QzVoee+%V1S@>1*Hle|s*ZjCl? zCLzt^NuCQS;Cz+d&tm@w<6)?`Jg=FaANf3OcupaVcht@PL4V079jADGynffU>2pmo zF0Z-HRMm4zELY;v@|l+BQPTaw^<0hz{GLr!e!_j*j+ORhe_%drzx&bNPr|+ln;p+t z?z+aGPY}NPY{l100Bh({r>PMS?7rj((dLOrxr}en8e#nRC*Yx)n|JpyD*Z#Zp{|LIj zfbP$b*xiA|5M)wKQzDp)9LHK zgMF}H{!gcWXuEUz!J*^ICwBQC8voGGPJKD)IQ`_%&o`Wo;R551*75f|?7#naXnM|P zXFNT%PPYT6Kj?n&-}iz4TR(C7k+Vc7V(|mpo=MVRLc0M2AaS`i9w$As?{@dsO zRiA06cOzT;y}GOP^>9^S-uo9nSR~+RvSJi&IZd`8vAO4^PU~=P9ixd+_fVIG-1= zj=%41TgOk=C;o1@{r+9Td%%Mf%vq}Jl3|(@8lNR>6~lp z^qKPYzl--r-Rb|%_viIG+K~7DoN=MdPETLQ!QVx8`kS-pU~Io)Wf0uzTEw4MB)+V!FF4{cYvy&ZghYNYD= z(Z3&Z@OO*oGnI=D$375`0|(cwPP_d-_1pgz{@>QgI=*4AV-M!@(0TdLa(AAWJMWu2 z`(pq5=SBzDGyiSeJG7pi&wt!^q4rPd)Bgn2H{F+{+Vy^DJ^Z(FaLV!jZoU4ua&yk- zl;0T6kEsgm{G89$`8(#8a^_#B-~5lvvq5xq{%5F-V|2TE50=U$N}q#vFv{&RJAa4j z*Vy`8JKxT_!C4u~4&1DAyBbe#Qc{2gBQ!}E6g{7ycc^Z&VjIq4m`E_ce?rF^TXzTIjtTfA5J z7yA6)<2&Kb`p+3(o%Ny9-<knKTcYk!qs@C&E#0t8D@$)ANG9Mi_E7~1?*M8Z3tfptOkD? zXhED7*!AWjV?AsuKDTP?e$)I_y=mqF2Y?bFMQt(GyRr_ery_9?Vap?wPNGiaYd`wZG=&_09K4XqnmH?(eO-OxUV_BpiA zp?wbRb7(tIemkJ;K>6)}wgXy^d6L-!t;hT;Yzb_N`oet7`~un+<`b|buqo07+y!kHw69UlUqkyE z<@`0Yuc3Vd?Hg#{K>G&TH_&>a^+M}~)(fo{+PBcYh4wA9Z=rn)?K^1SLHiEcchJ6r z_C2)kp?weSduZQ7+YN0uwB68lL)#5)kNK&&2ihLL2WenPyTp#22xXJ|h|`x)BL(0+#Y3sU|C z+AmOkf%Xfuy@xb44tsh!HwBMlp2JJU!zd`#A+5u<>pdEmA0NMd)zeD>S+V9YQhxR)(WgRe- zl?Q8L310%6q73VH0OPdfF%4)2G}F2j$OE1-OlT%F3z`MZf@VRppt-D9Ocykl^%zhB zq$oEuH#9diH#9diuXT~(h32&`fh~beQ9jFb`JnkM4{Ql+it@wP56ur>KQuqI800wy zS`6|W11$#H0B8fC4S+TP+5l()XaQ&eXaQ&eXtB^@p~XUrg%%4f4q6`5n3X&A=VG(5NJcJpJ7X2Q`AtD!BA*JQ3gYy4TY8j-y~>B@J)i21T6(x z3bYhxDbP}&rCN8oQlX_<|AZ}pO;Krxmj*2j@zS8BK}(004lNy8I<$0X!=Md=HVoP@ zXv3goK+AxZ0WAYs2DIVOhC>?;Z8)^y(1O+*t{}9awF$NaHbrGZ%Y>E*EfZQMv=Q(f z0c`|)M?f0^Eel!}v@B>@(6XRqL(7Ji4J{j5Hndsl?5Rp^OH*pDD*wAu@1_&`m(Av@ zjxwcspjE3!%9R>7jMy_^=Yfq;ql$5}nxxcP^)8ksW3rXXG`{v3>Wd64Qrr(?FXV1? z4?nXEu))Gogk=gFC2WkaJZ6+ifoS8IJ(;Z3MA1rwO%+zbjC^M?%bl&%d}a%e!F4dB z+}8+O?%s~~5ps!Bc3~CP7=wzSn^D zL2Gv3vPh|Xdi7f$p3h~x+%2X~JnR%{9O)$F*EK^bWZ9}|FwH|CcShIUw zi&DqJW0&|gyL+af2H;U(k_TN;fjI}y`J16NyKe)Fawuu9gZWi8*m20!e8cfDJPz|S zJAioejqHg^`EEc?)s!VV<@M^{xT1$fp?*EvkV+$1if0$tK*XDG#A07~1XzkE87zDq z#iNvmASIo0F2_3>pHBgsWt?~sQbzlmWsHZ%@EaA@=uTdm-4mf51Ff1vPXKFncj0>P zK>PFmA>L((w*@6M%Ja&_s1?K;TZ7Pabvn+w7-bL; zmMtt%*bL)5#G{mF7?*%O0FN2QbYb~m3!&8*#9l{f1UOgoIc3K;pd8;s2~AW^XrhFs zOKAEZG$&rRgl3Cx9&6Nwvc+S()a6{G57#@if=Z1_avQFEu91Xy-AGF@R;*Lp4hqbp zp;3EDG4jAt&Qq#HQYrEHr|MQ*;<*r^)Xz&imw>(ZS7K9aZK~%Muw&*ZHJjVjU8vQ0 z#wn-|5AxUSUV_lm5vtkWnEead1ooJN$@6~pxD+0AMe~daU`b%JjfOLnx(M;Aq{TM7 z$(LGj6^E{bZ-wV6XhY+Ptrym9Gu?9T;`6%kUK^da**y^KM9yC-81HE{wDJ5GC1~VY?w)UtNHxY+DW=+a zI9*39_OGd|YRn9<_?w6w0hWt?xK>hW_FM`r8KHVCp;}n)q0wSEv}V2z9&tl zDn>45Pa<@qr%yCuS~E(Wc*IDXsG4w&#G8o?Lm8xjZS?GbmI=1aLp6OkhteoOXWQ<% z1XpwlGe6!(+kvv*-es+p?W3&FMK{Go8>??R|H(r~edy0;C%q1ud^M3rc_sfXaY&IeX zI^`$f(JH>1nbCDn4z?RFA@oD?FlfyFghQPv zvk&nG&ckfV+An9L42+avx=n8P91V5^LNmRiu2Jel)OnuDheoqdo;t&3%iSNv<5x^k z28)ad(5Pi^_e=((a$dwKQ;%9?IOC)qfloxrqr9geR};aijj1bix#-dRT4-auk06yh z!Dbm-F$dlUmgjv38Zm?Cs0g!8r1Bgy8qr?|Yv#6FjPvSvRI7&h4MHhb=#6-Lg<5ef z=a0shdLsd2)01GehBJcH8j}(4##=~p#*JFza%ePy)EXu{Xr!q%oN;ZU*J*2woHDhc zCgTpo`xNn-jJv_U0&5hHM&oE`Z5((wb{6 zSd&3)Gko)8?#?qGLQY!|nrA)*c6mCn4PYCg6_}rc(a4Zzehaplk zZl!voG4>LiLyxR_j6E!X?UJj*FbD2&~U8a+(3a&va@mbz4 zv3I=}=bbBBuhD~4sLp#Or@d0s^Cez@Yk}HTz)XG&tCrh{Ic=y)YQIWqKVUj-C}2`u zX2TUmcql^X97tjEct#%zW! zjo!;S&ub96UeWmXDCVf;-fo0a8LU?~VwFa$#-z35Nf_mu+2d{U@J6SgzQHznX%6@Z ztiyXjmdUHM4)3L4w65#$ULo2wVE1EH-{HO0X4}0v+4#G?@U2njU5P%3(0x*p`@9z- zlt$ov-s!@sg*{?3!$*1fol~KeU`(Y_xymW=8ub<8ZM_zwna>%4Ym|j&CdVUQrti4H z7}vl?`JB6$spc?*((15H`o3;|ry-sWoq-;e>AL_U`dQHO#5dDNB~If@rtdPOaxQyZ z2}a{?rtd~DE>oFja+y(k(TwhUa+T9^a=1lM-^!Kx&6j>Y)jWXoXl;?{TajS!c?T=% z$vbi0d~S6#0&C4XpK?FoFr9-!Nv}X==S*MR)tEnnR2oj3%=C?f2VKV~-|=9_B9%;E z2rLh*Nb*-K>1FzU8HB%%%<*11T>EDF-UFiI8-IfqTtI9R80Do(%4Lz1 z!7Q0q^&G$ZZ1Si+%TO1SuX!521<;p8Y$Di`DDmYyn$c==y(*uD6*JIbVp~jSv~3fQcJb(x z9?&JMQ+&IG^>8R%QK$LyXuPpnh0$BIF43CZ>+e!3>kfr|MyKah8w2qi{dj2AMh;j$ z*nHo;laxAxWyce(okXzkEyq?HsHA49Wn zSG3$WFv(Dt-ig}xU3DzpvIiUQqV?nqFg*^<0;_P*40ac@Aqs!R8?3=s1rKTw6`mKs zsD)K{HVC8pTDni^mr`?COOQ$m&f71g)^E~X`8g<&fJLqNFoe1+XO$6PkK>^Qtbv$C zXtyF@4F&rvv>aIr1gr>Brje_VcXs$b*%}|#b4tK+=HGzz0^-q_7_gj~xJX9Fl`=Q3 zG&@J)T?XVz-@gsS*@}3SC#LT;Xid}1_dT~D-dZkQO1YWY^UyX*iFZioHeq9op~stQ z+(NW&<8ZLT6S1O|5nbQ^p3R|~67f6GDCaRov&{^%03Ou$#~3v7(;fF1<06T7HbV8t zPjeKlN;7@))?v5oc#7xDOwGI(M61^^#=RKPOU@-W2fmYV-d!>(k1>vtluxr+y5+3G z)4ASgr0kpB*PTGW{ZA!HcN2+V>peF^%OH)%h$A_a z?lAreX86aRh*2KQ@4pfI1@v9f z$C3j&M*&~k9%#81t;d&KMa)_0x5*tr8?VwYQkxqNglF4es*N$h8ge^f*p=ZZM)q&$^q~ zb}&C!f$8iM7D>4jS+v7K?V!k_9Tw_?E#|LCS!>Q5KauBO8aE8~U4itPP4`Kd7nmi2 z(K@V}$Bk!L8;+JlJ)qe<3T*aBVugsOwPG-;g=TYUza9yv`kncsL~4I6r$;*zE8R3s z(n`NrO0v|V(Uw-+dViA2Z@r8R>v`vda#bPe&0hxZ zUPfpQGt!m|TPb;2?tU66Q#;kZTxvXqEy3B!W!#-1+r8cJYpqsud#?npE*~NZBs zql}%6mUESjlG8@386Laf(Zad<9juLWMR%!fGIr|S%YUNRwi(X#7D%oNtjpigb7%pN z{4_EY@YytLctWqyF>YY2BW)$GB4^d0WyjFUgT}hSG0u7;Ppz<5;nhYB-nxGP@v4pI z!5#){<9lqnV`=A{(j7~u<=mZga{Hs)R~x(G@fJMVgZ_qlA&e>oTn3wvmx3M50p6X2HnxV5zwZ26tjRI4xed6IdNB48Xr2RU*H%INB_H(9MX$U1>)GBtPsDui* zHNA(FyQEzeShOSeGc>&h?gy*jHdMA0EAtqt4|=LFKZaI3#Ps^*R)lu3FYV^_um{c9 zz0wzYrM9~GI%oyoB`wyk=H0Bzs$cq%i`U*Xn^tpK(YRY3Gh>21OU6{%40B@%W|0Rl z@2m5k#tz?TVi()2M#{M+Moq-u=XsFwOnru)aMTz@(C9f+jZp$dCA3{;zkuW*(M78p zUh4@PZ&kx%HPS1w#=oRh_VgD9Jt?uu9wsz6FY}Op(zCibi^)V-d-G_K{ zIakZU*2k1Ui?DVrSOeI6$@6^4^L)wke9Ou6e9Ot{e9Ot-e9Ot-T_TBT2)kd{zlF65`%GBB zu+)p3vz=hGYU?_%_+{ubR{N2L%3$_1v?G}HfStfB`C?O@#%vncxy;spUBc`au*;bp zImuMlGMfZ;E7&$}yZ>aZ7FrFnHn4v&`xdN$S$c`7o(J0=a~Rlqux3l{#s)Zhf(=&M z$@+d~y+yT}yd3vYE^4uK_n9p{FWcpe+0{lX(xcVQVD%2z>+ooH(;bipV{D4&qgbWh zhL+=U?yPgAPfxXuxkUH)YU{a6@iqZgWz|+E*eA?B0;AD;+W^Wz4>Ua%^Ef2=n;J8< z6s>6mMxX)o9OrDXsWJaR-=6@sUR5LXKbaUSz0UQ{HCIBT-8X%0bdCy7D>Pb-?DA{@ zdxX;S(7K79-Bp`=pwU(C8$j!9nrHM~0`2AQlJP2EuCh?BvdHDkp+zodpSqaKl+Ii1 za_;GhxpZlVrPSrD9?CgAT0P9*^l1K_;d174e}Kw`QkgC1ohRolmpzIqm#hvs9^Df! zl6Y0JHA)VeRPw99$-xEkO~EpduWPD!Oy%Dz+5>y-4mB)u+4Z;bH{QlT|S zsmpmL*TWt>i;G7oUlHA(&y#cXN-Cu;XBAn>d7(MJR9aXm=Y{w1B)uxhbCu+@O`hJA zx||(?T|Bl^S?#ipFVkb)E^9JaRRsN2>Tjs~4eELJj5(<)(^TN$gfIdIFOdcnB;JTECP~KVK2ub#(Zj z#l6d~xPNoGX&j`N=7Z1L!q zlI(XmcLX(xcEM1`3`Zfv&Pf8@&D#B6ys zJ6qQ66`ljg%QMJd3Fn?#L`h)O<@kLdXj21Yz^IN4^NI}o_E;UBAOzGEc!~!$H$Z30 z0jmyBiBr6qz+{A80Ieo4%Vzn!FF-l1@GP9J&(`d&1zUo69sYdO<#Mo0-`mihrSy1* zh4Qj*z&2q?U`8%Xe**ml-l1%#g8ep0F9>Q7-u_m$S`~T$M|n%O%gVC3Lpr+3?EVgQPr9 z%B4_RqF(9K8%%4Zy)-i`X~0S$;Oq_W@=+OFO^+<6{maSuK1D}4(0obs%) zU0UpVPLD>P2Hs=*3i0$?L-f|w#=y1L>SsV31J1j7RZ<33QU+Cg^|3EOk3GdtQK^4(~wdQW;CMwhLNbfcCyzjd*?}=dG3V*2;Nn-OgH|R?b`N zrr97JzV%YNjgo`)Y7MT9RwK1;S~HxCcn!vz(CE#YjzH3NdVbTpAJn5d0wbUi%XEzd zqZZZ?m;ciVo~Enu`p?+D!9h37w6q&)zQdVELV8HxwrU4a*E zR$#mdb}zIs0oq$y3RYlrL8G0;0^=*NyD=7T{KI)^WT2G@a9{!ThY<2sQ}J@45?2U)vg+ z`CV-`n`?XyM(_X4l_wV+fnT7}j!j3vf4x529&04nQAlrN;6yMQeF}_;V04uQ##Auc z-5(Qh-VbXqW<&cK9t}pd&GJ+&7(FA+Q%~CaG;@t-p$!b7$IDYoeZRl_8I(}0v;G?# zn{b0}2Tjt#nxrQiUg|yc%pu!VHUYoTh`h8&Yig6$lrOu8`4&Be%3X{8Ch`t~OL9uu@0bwF6$&05>&&j6#^(r-o3oL6961dUpb zULn)^rI=SiG-G#h4rs>il5uFC8xO?QQAnj&)+#-c=U&P47{hsUppQ$4Qtp$US1jwM zeks3xPK9QBmxsnCezGU;{{=j>j-b#)2~C&KbP3It&^{Se()rCjTAyZnoUtz5Pk-E{WGKb4tIACHhGcU3sqTHm4wg&R~%X}w|3XM+jP4hjYn%r1jQY^8ez*i!~to%HFcfj4hA)i0DvpaYCn3R44H42OLTjjpmmRv8T@^<)~a za`fAfxDMSbrZki0tR8as&2M_fyvs|^5#2A+3`V_{t~^)TORmS6aVENk{ES%y@p3s8 znvZfl&i!CMw=23IEaY}Y_k)E}=eZtdty07(bMFyWDy)c8p&nJvsZfua;c@1&86Iaf zTrMe>ipOm6m?!b(iSKOjC>D<@@mM4ti^M~(Bj}ykD)B9n(kPNLC>E_)v{KPZJ8uTRYQuKwX+;(YR7{&dK-jc6y{aS@q zf_QUd-FN7@vBE`j-fz(6$7Vw#k6Etc!DvpNj5yD zAsT!Y2L2AgE5z!caa;4zoJ`vM*q5PEdzl~G4n`y9{MgUIXeOQ?>&!y)V;zs`Sl6AV zS_Iz;7rjTj985o(eH2XZt<(EgDclliEub0gw`)eBb6xbl#mTRt&%`>pS{XYLDbs8^ zHBbUZIfZ8DbY*NAG|JUnE|&uMHc0LpB=-%H`!NBUna<>R3*k%iY6GW7tC8Y^YiijM zsg)j3FFl}MT27<1@d~pY>2*X=2Il)2N_av$%?z2+e_(dcrGMutx?)lqx9Mq$#a|JxlQt{OPp%8!hB;Pes2fq z>GLj|fYCx)Y&)k+vqrmz#u9puw%y~rN88Tlp!uj%uBcPa(Jmu{u6^iN&fb^uddc}a=+Y@^htVs5>MX;(3ST~o?SdIQ2tzA z8b#^uJs?`5uykfL!X0W2nO%ygp%3zG~ zI^Ip8zBuAYTQrthK=xFY1V)a$%oqQC#K525=8(6^JQ)#;~a?MUwI&NqLdvWs#)ZX*y%hKCbEaH#<9lU0}6*4jTXJ zyFd+7U;mo`Z+n@5WPT5+4#Sp&CoPWg=r$!VM9 zv`uo=Cg*LFv$e4=-%E12(8{-mTOzHbd%VsXxJ$~aljBinr)c{9$=)rvf0MbQmvc|` z)+=SuEA`eVwa_Q2=sEtBPV#W(lwQemuh)5Evdi0bzwWEOavi(mP5geT%YM1?eks3x zNzcU|G=c0kM<*K)F}_>aU;{`JPFZH`>0GcqgAOt?xcJ@U;5*!;6YyU<6g2U-CX`kb9H9gp@wstjigt1{@$klqU#97p$MG-3{pd*DGmo)-C> z5lQc4owN;mzI+bqTSffNES02Ty#bGEgy!)#hH1Z3e^WH!V`B7u;uNrADbr%fU$M`5 z-c!ouOwW7DrTmJ0&RV6|=d54Kr6gx?dNd}^mXv2pZOxNZ=KaCLStHGm98@u*E1JP& zMei*w;#8=YE#*|G2P~CTW{bym4?T1J3UyQ^IjE8x)JhI&#W#h^nQAp9u5_6$=UpDU z^M4QbLKU8WL8G_ZDm+i#tKW0W6pw64xn5GPmy~sDqLlOH=}5Zl=cMy<4ccW-m;I7P z$#apc>YF6x7CBp+Xl-(~MhR_~(DpxsI(q;uT!TDz`sgl|zV+53Z#cL3oR-)kWm?4F zf1~w%k@TJ->18c{$TPKAYVAdGy}GT{d`WHG+3U-e_cF5O?T&2AIj?@}x#lbMLDOA} z_o|rDe)eZzopQELX)m2Vrw!#uXpZE*i#6&|UA~D(@2FkG=sUs3fsKm01lmbp+L!u% zhj|$^>uZd_l3oL^poT*0;9VD5OLdseZd8ZqyzQE+oLe|XztgTmSkI8K^PR(QDhjqrJ2RkK+9eW=l9Nc)C`00&9#)c=RG(o~H?+^h*PIo~W>QgncCJb74Q&OusW0_dQnE{=$f<{sJ~J zj>=#g`odZlz1=$++D89<2t5%@@9~_=>@{eVs~Y1Suu5q9yA(^nX7NZv>)5$6=FDf- zi%|Wo-+{Zqj7L}Mw?uQKBs{H zWu@=SsP^}GE-lrw{VvxMT+vSCuOZHPGjo^gC1~HXM)NPdIoizSN51Qs^&@nB9F1_E zAJNvh{RO}};;0YCGjsaeHuj(%uiv7+451T!$Jd)`I+#A&qVtG3Z!d0lO+zT9+z@vy z80BD>q_RiyvYl)CKZv(aLifde29M3G?E$0O-xue3T(|puac;l9Gu+0$A0pm1SLxsN z+YWnNPXC=Jql$kZ%`-Ft8@@$I#rTPsvoCM>=o>s*qj$<_f6egG_)I$|RZ=rmGF~l` zl$S~!RY_gevIni)YW>dWUF&y7`C5N6b|2~6#&?zZ5$uqAm(YoYpKKvDwCD!+okFv$sQ$5CZt9q7gmx}RH{BE>MvOVf(wma1Y zYW-LB>wDiN-H%lZ^vx z(~ZG?@(UU#u+26mvmI&N#5TuR!FIIK!Zz3VjO|!sC)<4EH?|=|mt&z3A4BP#Wn{4} zGIH5YFivG#Y@E$@k}-vCsc|jauyHqAJk92EoNmU$fn7q@a@HRKF2otIRUCF7sBlKJ!Vo0rNGsgUoN)CYmD#l3%hp zk!`wp6WgG%G z^UT*^eX7#@iEWknE8B(U@34Ng$aKY%U2OW zW(t39G}GCxF^98lGDomoXZ{5?4&NRe$)BTa<5Zh@B!Aw(HV(f}dNjw|Y#zsYC)+su zw&w}_xr;68-^}B9J!U@Z_-#wJz5E&d(Hh6$+15pDM_OfUbF7=#j<)V*izoMN$68Oa z&9~OE4Os~Zl;1+@8n$Oy8`&1w=}xe+6DhpdI*08ftCDT0^*GzG)y1~l+Rt{nl{19m z&#)%5ooU_4cDD62+c{Pz+j-VLww2alLn(fhHJ

s+>rtXtSFw$`v+YHeh@%=&?C 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

s_dk&u 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¤JvqX=aYBp@}O{n|Mm8(K(@ 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%0Av{Jbe*rTB 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

KiCPV++jbAVR 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 hNA+8Jgg~`#-UvpxFQb diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/build.bat b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/build.bat deleted file mode 100644 index 6a444217b82..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/build.bat +++ /dev/null @@ -1 +0,0 @@ -php ..\..\Package.php CreateScaffolder -p:"./" -out:"..\DefaultScaffolder.phar" \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/index.php b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/index.php deleted file mode 100644 index 0ebc4e8832c..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/index.php +++ /dev/null @@ -1,63 +0,0 @@ -log('Extracting resources...'); - $this->createDirectory($rootPath); - $this->extractResources($phar, $rootPath); - $this->log('Extracted resources.'); - - // Apply transforms - $this->log('Applying transforms...'); - $this->applyTransforms($rootPath, $options); - $this->log('Applied transforms.'); - - // Show "to do" message - $contentRoot = realpath($rootPath . '/PhpOnAzure.Web'); - echo "\r\n"; - echo "Note: before packaging your application, please copy your application code to $contentRoot"; - } -} diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/Web.config b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/Web.config deleted file mode 100644 index c9c2671eb1e..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/Web.config +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.cmd b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.cmd deleted file mode 100644 index 6883c926224..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -ECHO "Adding extra environment variables..." >> ..\startup-tasks-log.txt - -powershell.exe Set-ExecutionPolicy Unrestricted -powershell.exe .\add-environment-variables.ps1 >> ..\startup-tasks-log.txt 2>>..\startup-tasks-error-log.txt - -ECHO "Added extra environment variables." >> ..\startup-tasks-log.txt \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.ps1 b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.ps1 deleted file mode 100644 index 5ebdec2a689..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/add-environment-variables.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -[Reflection.Assembly]::LoadWithPartialName("zend.service.windowsazure.ServiceRuntime") - -$rdRoleId = [Environment]::GetEnvironmentVariable("RdRoleId", "Machine") - -[Environment]::SetEnvironmentVariable("RdRoleId", [zend.service.windowsazure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id, "Machine") -[Environment]::SetEnvironmentVariable("RoleName", [zend.service.windowsazure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Role.Name, "Machine") -[Environment]::SetEnvironmentVariable("RoleInstanceID", [zend.service.windowsazure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id, "Machine") -[Environment]::SetEnvironmentVariable("RoleDeploymentID", [zend.service.windowsazure.ServiceRuntime.RoleEnvironment]::DeploymentId, "Machine") - - -if ($rdRoleId -ne [zend.service.windowsazure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id) { - Restart-Computer -} - -[Environment]::SetEnvironmentVariable('Path', $env:RoleRoot + '\base\x86;' + [Environment]::GetEnvironmentVariable('Path', 'Machine'), 'Machine') \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/install-php.cmd b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/install-php.cmd deleted file mode 100644 index 64bcb452db5..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/bin/install-php.cmd +++ /dev/null @@ -1,12 +0,0 @@ -@echo off -ECHO "Starting PHP installation..." >> ..\startup-tasks-log.txt - -md "%~dp0appdata" -cd "%~dp0appdata" -cd .. - -reg add "hku\.default\software\microsoft\windows\currentversion\explorer\user shell folders" /v "Local AppData" /t REG_EXPAND_SZ /d "%~dp0appdata" /f -"..\resources\WebPICmdLine\webpicmdline" /Products:PHP53,SQLDriverPHP53IIS /AcceptEula >> ..\startup-tasks-log.txt 2>>..\startup-tasks-error-log.txt -reg add "hku\.default\software\microsoft\windows\currentversion\explorer\user shell folders" /v "Local AppData" /t REG_EXPAND_SZ /d %%USERPROFILE%%\AppData\Local /f - -ECHO "Completed PHP installation." >> ..\startup-tasks-log.txt \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/diagnostics.wadcfg b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/diagnostics.wadcfg deleted file mode 100644 index 10bdbba128e..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/diagnostics.wadcfg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.Deployment.dll b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.Deployment.dll deleted file mode 100644 index 230f75def0cbfe4afdd03575f3c35c48f768c1d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1201991 zcmeFad7NBD)yIA3cF*me+cQaeX3{g0g_#5rF1<{afslk9AqXNQfU?TIhUG#xxTMo@ z6j4OL1#yXj5XD^-0YzmK5qCudWC?@Y^E~eQ__#0O{r*nfUM9h3`Qv^6d7aPny|tV= zb?Vfqs#B+y`{EPc;-x&#OY?i~InTR`xBm9G=YRj0Bznf^=Vy3#^n7cv>YxEh~RJ?+A=GfuncqWIFW)6W{KUUt#gc^8cxbmY-v7sh9vHQpEQl3-qYu;(4# zmGZuI<>D7NGy8$(FUWOeJ#SXO=Z(40Z!b*T`|}oY3ZLc3#%1K|?M)I-c+nrASo>dL z9{laMxfEc3uLSSWa)EbJJZS#mKXnMtsr_CruOBSv_vSU@{x|P2&!YsbzbyV2wtSv9 ze(71SycGYVeo`)#)#z*kk>u3zYOQ((K}H)i8O#{(j=%k(e!P0t1u=l4RWuvi(jDLq z>`3-6=f61cFAn^R1OMW{zc}zO4*ZJ)|Kh;EIPfnH{EGws;=uopIPfXWtNGL1)c3l* zt6!Ayj(I%vdMwoQ9{y3cclWtn-r6zdph?(&_qzGERTu0r@rF(F&w9y)nbUXuK&E!U zuV(Kv`CpIz{fw^&wXEB`TB3JSTgX*-=^w2tv%rK$NrRi z(TkoQKIP@_*!Nd!o}It^{@afHx3BiBf91!2x?t|owD(2`?DD+)CMN7*=nob8y$BOW zP{~E}390SGV?*$8K#8MK+|d}1Tjb59`n&4GSQFOq9^h>#q6Ng4$I?j{FL;)|XwyQ1 z*PnP^v@`E@rBr%w-PB;vks=79ZnE846g|xCeJ}7Xy3`vK|K=`Dc^~2JLubFYZMJf^ zq`7|2Z_EULzh@bwV@xIC2@Pf0@1>(f_!=Uu-y3d#iuYgxLj~`lMxVX?#teI>8Y)V^ zSBNldOfUV^M8CIv0eh36Xfau2I?IvSz8o{Wb1w5HRF1`dDjiY4klz4h`U+w2IvBM82m=#b4~;h6d85 zT?lSW*XKmi78uH%m+m)QvrhDV1CGo z5(b4T^>gu-VDdu3lXAl|gBfYTj2O&N72yGPxVoE5Q*Eb7Ln{IT-uqw?ct=;?5KP_; zfD6fG3Zvy4GL!eTLVB}>(eWFyllQhl`g$fwoFo`X=hKDJy>7^-C+}|u!kWV9k{j~f zlV5BH26?hO>4tnT`2c~#M!`TPPmVxlh7^^V{8Ag9x+shmZ^&mSA8ZHqZnfcc z@H2onwcV+Su(k)!TxMvfwgN|QkoDs|ab)9_JTry$g?JT?#hG|DuV^nGeN%(ka*&NP zxVL7?LB_dytS!!sln= z{dxCJ4Yp|w%0b|$&KA8cqj{zmjx=e`c=L8{(~Oj<&(5c!0}O9EK2Uh4W-NY~?y1ZA zx!jbOvGN;T0O!3KirmSMUI1|MgQ@DvsD!z$EskvZDU~s+t6J#tE>5SSg8+%Bys$V} zTyKEYh?q^PvUm;QlY%cck&Uat2Wp8yF>zCsEjJa~a#N=*H`Us5Q@JfS_1kh&$t^c^ z(sENXEjQe4x#4ij4VPPPIMs5)t(F^RwA_@sRh_}Ad^s~=WnkY!j~tH9q_;QiABe`|q1m>&3_7Dy}TO#V9yoHsr2zbtSyfl1E4 zw}7+T0e`T7s|gr#wEfWnK2E@3?O4(ECkxox4*0VL^rpOvXV;Dv#9u66cLIi7z+Wxk zI06zJf3tu~+W~*KfEx)&2-{`>UpE}aqkmYyzY{RF^fJ$Lh@Z2-d1(S^21y_exOw>W zz%C1XIe|$Az5+%Eui1(2gI4UyA-^uh)8G4bF?≤@8FCEx{bWE~ah?=K6Ip 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

EIa!XF^c1FGkK4D&xusToMS}u%6 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

yccVFOlQMa3bov99c}jH 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�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


-pifV9RhERWlEVaLzmr>&xf=UJ7A8$E5c^HpW?hT<@Xh3tmTQe7{cFr{~uxzk_`E zek<0emakyuhwbtmij05O&y4Wt$vUEv^jO}spSVN({PD;7m=NO0dyDWr7hX5B9curW zGn^-5`yiwUB(fI?u52P%%WBTd#^tm8D2gL20N{9E$vR3OWkLMBiTtd3P zd7RMZN9z7(`MBPw4mih!+4m^2T{E5R_h_^n8|KS$G9J^(rqBL?>*v&_*G1X=!2BwY zOMJWb-2dtG0qOH|^sj8aAMdBpRy9692KB@15YCgG0?z9My&l|fJ|=se$oj}y9q-Ef zlS8`lUS6c1^`nk#dGvX{bezNIDae`5O-TRlVCB83!4}PH!It59kZR_m5axP=ocXo! zSf8cq6w-O~U%P%l`@Qu30Q=Xf=IPa+_p8(UN8~&Xv>xSo7nC=voAp+e)qafQ+?@Fa z=`dZbH+fG>;6>E8ypJw~tD(ND$NFYGZTIs09MW4EY#!r;0`^DI=yw{*O!XW5@mrkCws)Su%l z&NmcI(@;MxoV$cM-Cru?Wo+iz-nOWQBkxw0SR_Nvxd>AIf{r874%~{*>7d%dpQrX1>*6!1HGQfo6+ZJdI`3ZGtBvDo#!dUd7jeil$;qf%BLgm zZ4OqxM;OxM_rByk@7R7z72C7^TEFsq`T*5eRhZ|Ou}ELT{7ww#qj+8LYs2z>7U<3P zbG&axUAjIr-QQ1TbW<1CpTC53r^9kTaDQ3bf|gbwvfpO5GDo9-{R8~tvmA768xn)8I5AKX-!^ZGjfFZ~Df z=y6?U#)fb@zh9N#1o&}X6X#LcKC@xY+h%!bIGyjO4qa!Q_7kcnZ**M~*DP@2z%^{Vw%%{&bpAPm&f?5|E%SFR8{+9(Jt^ZBcv;ThWZ`Tet+%G(jay~129_4=Gc>lvt zPqID|^~&eV*KcN+*R|De_T?%V7c8F#rA^1Jo4ek>^!VNIdP&bqJia&FUI9HUN4A}{ zflluK?EWtG&l&wLM*3ZfBar?VJNR;Q-sFG2UEfQQH@%?m|MoD~`RM&%c`qR9Rm+`@ z=l{F@BRxJg)gPDc?+yE*zh>GCkNa%9$%g+=_XpYax4e$>&q?}zDBJ!w?|hT?d#neR z^JeTn{Z2~y{9iU*KDU1d{MqkvocuoOdjafsu*|1(m zq*oUGHdPO$>15m0ro(I(=a12TlH(4JM=lFo=FP(RHXT=I`*R&HZrIy7O}%bV_h@@%@jUs-d;vMk^jFX%;!(u%;v|*Bi2)~U)1qkI?oo4&kE`4{eKnV{~KC45A^iuRk1x+!SDCbX1?Qt_}-7- z0Xn&Idf1*#-}|3a*)Nkn^UcQlpN6Z_$^25ADQ8BX$&@QiH&dS*@w-gQ?fom)yAM~c zw`_P*<@WxY`@N+bE7iM?S2-N>F{;mRzf1hLmU*c08_~VBZ2xceqkrCN3etP4vYrgj zRmgqdjxsx3Q807FFJDnKi-RpQ)o!iaZcD$v7R!PC=F1VTbF=%g()P`%KO_1o@3(9| z|Et1YfB24775b~vl`Z$L4f}Mrt5nZEz8>eLJnP4L@cvCCzPFXrsl1)@52gKB+COr8 zRhH}Q^gZnby!T_n_5G#iC60%R#;*_b`m@{h`j*d8%KZUf4{{u^pXRug^K;b4axmR& znDIEzoE=AH$IBeI>wVg^e5HD``qTB6jIa4}{wEzjQx9!vy7Hd*Q0{bplx|O-WBwd| zEbq4=Trg`(INu{fn>Sg%>bL3s;JCzpf7AataO(8d|M9+2W$yQoz^^<8_bjPx;3AHc%8ug{mbEW9*E;>&JX@p z^NCg6SLC>zHk*HTezj$&$GmBW`s99LynO?g?<`|`_Wm5#(Q*Bd9-ngGZyUeg((icc zy8m=NOJAg?_ibg}J?3v|`CP|^@Vg?|ykVHnbI`A0xF24K@2eOI|I+)FMZCAI%-j*S zS2K?UTirY#Y`K{gYz^~Su)J?3-+@FpYuWC-4&T1`+(~8b`x8F@r}@bHl5icQW`{fPinW|c+#C$bgnm@z3 z9wpr`oX=%{!1viy<)>Wgc7)b1+XK^K{XLBOeg^g}*ld5!d^gqqe1!OG!#uydzj~n0 zU&b?yR7WY#8GXJ`)*S@@0{qkOSA8AQ+w}GyOY)WH9z%ZeJR7)v_e#Ehe3$CTmXBfH zuVepBuI(nB=iV0SuwH(-KTgl%tiSETyjJ=i2996&{tAZg2>BGuL%|l~`z`FsWc5v0wS``iZok$(}zS zM?JBB&W72KDleFSplWh3> z1Esr=en+`{&ja88%cjRL`_s<%X*=NYpvOVg^T1UdCp?ZgPrSM5ZR&jfhoDcc_n`Bp z&@ak(F<3r#R#kXIJ^<-m5UhN!?o2IzHeIgQW;s~C>~YR<3-=T2mz>Ap-fcCXo@2dD zzhl7g(7@&U-mr|P`%}Ifj`er;em`zXuT%M6SY2P2z9&}01+$a*`*CI)SiUE>E7Cav z+=socjrmpPJpTFoypE%Daor#Lg_Dt->2{Ytn6=pUD5#iJ-Z*Ost4BN=I+<3>W%ra{#pk;dGkByIXYN=$Gl*8{^fD= zo1AAW+5B*4_9Eb)LSp;%ks0qFNAK68#q2@zcn1&$+bMPUb}?n z;&FwB1ZQ^e?XQAA`)L{1hxHmcvm9KvbNxXvZr5};pDo|v4e{iDJMyOv=3jbzF}>`# zob_Ea<>USSE;CyPE9(k(_Tj4ixt-%b_OBct@_6I%N!u%=zu~$G`e%>N(sJa?-aD$U z|KI-KRS$Fb(eh;N{}=Z2_NKnsRetT{x38%yzm8@<`S*VEug>Oori(dH{$F4IU*8;L zT<##Tf0o~grjhxJ*puaVin%6tir7;n{;3lGG_#ZZ>dUW(86`|Yrd9qr(^h`o);Ir_-`nz=VY(LHGu;XwNE#nV_!9}QG8dXP^6&NG zx4iJPgiWrl{5qPP*qqoT*R`1BmKT!T-lkrzzGD?azhZ=C$b z=MI%$*TRFjBg})c?V;S!=HcA2W>W5KGbMM9{JIw8SDYf6Udf$rUd>%3zmD>|(7chm zM1CF3RLNtiY@a5+Z{;pCZwZ^3yIg)9&8*y2W=`%p`E`_E*Mj_tbHw+v+-UPz?pFDA zl;246jc8e%yH|eR_AuWGTOs9KC%+o`ZiPm9mur--Z;lpwwAf?w51G@&o+-aeW&1ty zdszPci2R-xpXbHCn7=0XqS%)u{Ic4z*Yc~)Yx$1yTQ9#J@~dyA=9}iG3Y(hWO>7Ub z_0604{c~>$dozEK*dAi*n`!wYa?^xO%O5SahuHe&t^BdMw}icwKVEDPvGvV#@tZDe zy7)~OHeJ};`M>1e7WQ`jRIxq8);I6wAJ4rj?A`p+Vta^{b|dM{5H>^7n;~q5u$lSk zxtYRd=4XiQA-2AmC2W?kS;A%snqsH$Pk0?0f^UJ;c^G9}4?W*oVSC6!xL8Il|@$n zkA!_B>?2`w^B2jlqx`;>Uk~}!Hy;c8SlGwHJ{I<|uup`2BJ2}kp9uRz*r&oi751sH zPlbIdY@V=r!sZE^Cv2Xu&xL(1>~mqC3;SHy7gB#;2>U|n?+amH2%DeZJ3n98{QQ1m zdx))X7Ub{EFA%mMKTd29vGvVDiMvqPLW#Rj*g|1n3j0#nm%_dj_NA~z`Q!78ge}VV z65B&;ee+fRR{3?5-$nVagncFKYpLh2g?%mc{I#&Jg?%IJ8)4rF`$pI|!WIi#ENro` z#ljW~`&QVu!oC&ut*~!}eJAWYVc!Y+PS|(Cz8ChruEwnW$xVM~Pl zkpCqAgRmd+pNs7ww!T>^eoKWd6~CpzmI_-YY?-iS!j=hJCTw|rVSc%=?dKXg{>C0TG(n~tA(u*wno?*VQYk~5w=#?T48I2trfOb*g9eBgsl^{PS`qO z>xHcswqDqJVe5tcEbM1tKMVU=*w4aDVSUaNI*QH95Wa`l`X*PnOn%Z&7pmoR!g9j$ zg-hhuQGO5Q^1|}M3c?D)3c?D)3c`wo7xG16#lpSv>mk4Trc79wurgs~!pekIFC3ez zF06Xtc(Fai);Hyae6d_ud7+xv9%Ad88WOjLuo@D#hOipKYKrEX!fJ}g3t?Lb+d|lu!nPE)rLZl9Z7FOkVOt5?O4wGy zwh~rHSRG+?gw+vNN7&ZFwidRvu&sstKUAF$d{@)|$IrR<^LKr=YOVIS`mF6sF%+X> zem>d!iJ`uRV(HU&iy{=E2unjFY6@k;CmWiEVrUGXY$%4NPz*~$5sFY6ey{iY-2293 zkJo)aKkswi=bn4+x#yny=kr-#_>$pEhA$buWcZTd>jz&y`1--u559izrNEa0UkZFF z@TI`l-~P$!4_|-#SJ;WL>1qJlU;umr&;|qG8vtJ_VpHKuMQkd3sqm%4mkwV#eChC| z!CgdMA&qd4PQ2V+3;noyC+tTdDa>3y;EfFj4KR zg;sdCNAwG(mNLPHE4zR?sPnbX5R$(mT>HqpndQ) zdv98#Q~_$b(t8tp%d?4=f}TXa^;|Nw%SI;Owb&C(7lX1Dwcj@6%U0__+d<9VbuCIA zjfhqOia9s)}DrGcW?P(CWT zKT0ws=X1Uz@%cp1EIsmkl#Kp2OOHjw;OiCU=x$w_z2o6K3ce~%Jr30D?Zo!phW;1) zN4|@ZZ!=nGnD5mKuvd_8gl{H%hYV3_wC~B&mHK=d_O!kezBNeAQm0_OOV9=(pj=nFyjA!3G}CR6}g2w$}(dIPNy;#$q;lHJ&la${2@HAT6pDUzBcsagN< zx%qM>HCJLsvyb{vu0)KLeK}X}!}boCPOU~QxeZ%BSEu4#H}a+Hnsti%!5HgE_^7|6 z>(QX}bCjAWrA+h%rc9iGCc&}IF6Wuljpr0aS=ObUG^w?%E#ZoV> zxH@;GCk)GUauGLwb6Q;y}dyrxqcZSI*yvXBS1G|Up9NmM>NZK z7w9OgtwApa(NQ*5#=o(u{zAp6Yq@?j=FH{xD+V>N?_R8}LB|kFsSWywiROr!=!wG@ zL+V7&X3*oH6?}BlC^eS%?@RDi$^NKjic@*w8_WMuf<~?t-ucdmRIR^Bx75xp z38ZfH?Gqo7@##`G9})S+t0t@? z3gUgV9ccSqzJZ{tkZ-T=Jd{lNCURTRo|(c#?L1aZLB7XP)3NGu&}z_1Z!L(%_Lbh} zK=V<`0d9kZpzZqjEc`!crc*)RAY!|IeTF$wOunNoL~B_0;Im1-E(NO_Xni@OsU>o*;@V1MEU*#?c%oQbDp&i`FhX8 z*_3_1oq;yc=>tul-0nLPbQn^z{ll(QY9#jgXjK3oorOlLQyp62{UjN`Vv06cq{qQW zJ$t)v5{TM)5tmFy)FSPUlV$`SiIRu;PeiT8gR1nD8q+Rj^u8Lt5&nl!%I%<8dMnO> zi$SCP@4-i;`5YBv+JaJ^W1ja)MIp(cGB@_mkc zP5Lg-H=ss|Xw*l-*T$(Qg5KuTFR|Yq!g?F^NcgCfMp;{S*gp&?Q+!8$cW38)JP5qLE>=^*v}4=R4y9Gy06S+}#ck47 z?f)RRt@iQ!k7}?*(;SY@h@DcaZt<;Ez8lOs+GLB`rA^z#*CxJ|-VacN^qXnF(HMIn z)?r3gGsYegHY4zE8NK((dVBt{-my{BlDj#TTFqm*HT76-t)}xHq!yp${~GtM_hY?t z#kX5`qZHcbyQQYPWlztSd?DTo)UQHT+M}4Y+(P8`p-S2Nm9qCkmfMFy7VXPiM5J*2 zjt6B~HxI#_5N(Ud-w{{5Lza-Jh3>|J#e$YIV+KI0lh=Kw9#E|2(A92zhc$tLNmdH3Z?Ru+v3&g8|2%1HAb_5I|5fL8_!IRMZWC7F?}(vfrbU# ztC%U)K%~;_uuYDA)BjFJK9f2FM^tv;T#V?a!#7%Dvjf!PG`?g9E=DP5bHrsJ8h5h; z*MqoCkDy~KU-oZ-9OqN4KT#gdEwTeO{WPz)uc9M)C)QiQ zy^cm;_E~LIDdwzHQYX#9TM!GA~Qe6JpAVzUDufana7&!YwP@luYUK3*>UG^l6>e|t9h+VS4LSqk^Gffb!!Wnt)X6h(G-6*?=`-OAFCdx#qPkQ{yDXA6m?h^` zbB^D021QhzuGIw;Yn_a50qn~m8V`B`Exv+BGn#F#SLL%XV@AI9Y8q1SU~+eu1=Qf4=jP8+FrF-K!`myj;={!&YXnx?H z2}+&H`Q+@!Yol4gJ}#M#Kg zw?T-mYw0?rM_SEeFGVToSZ|NCT8~9n^ z>;a(vgD+3!0wFtwl4;~B;yXKhootVdnsZ9XcF(^d`vv5qF)?JjXX0WR9aqY^aiz6o zDBfj2t<3dXZ>+7DM|mQ1twD2|X1?yZ3HjD?>r%&;yRORN+GO zZha`IXe4H|GNPO7-!nM%?G*eDG}?KDZgxmpV-P{d{s>JYKV5N;(C16OGmvUVemY0d ztTa0?ZyoNI9ZUJ#GgC9)3!>TU2z?Jm^oeH^%|Yx0taq1;$|Lj`*JNGu%1~HV9%lnc>%skl(dD8aH-fNDd-~OkTq^pS((0bpE@C_m#j}eD+DqUgx zA4msBjl?Jq3I;C$m4MQN0o$C9cKM^V7|l6?u6l0(We2HWQEN>1{fr2{8|9mdd_==I zm0D<6knVlaQL)k+9A%D~mEJTE-5Ja0t)x=&ZTDz2Ggb19v5rMP8r$=2cP?PAiawPZ z&^pHOw(W&4-=_Ka(#wh5nSPsG5w!7qjZ)j>+Ms}2^3Xfc$E78Uq$Nl5c3g(k(ZS16 z7dlUyE5pU`1r=SF)qtjRo6_}Qi}dyu>w6q2%drP{`Dx_ZhJ0omr#d(2ILfo{BH9iL zg2q_xeZpdCmtvdluuwlJw&@NF9fK{_?$+;jYRKL66Vp*gk&dAleJf*0LTm5>5%a=Z}f9_t$cHbZ26vm&Qq& z>6b`LmfAGh(u~{OpQQF%FC)WxzH>sgnl9zdVxm!CF4KJUp7rWcEEglTO7eABxhI;w z(P144qS@;_43h^0#J#$J#S#1PHv(#03#*(>d%vAnid zkXp?|z7;|%r7kPHPoZS$rzVzLjmNO1SX;S_yECL+#^@6Z&AGzttz+*&{dm1pmyO&) z`%&ixSz8DDQjWlw$UZtFZe!o+h&5CKS|5DtL97#GwvFmywvCS{*|v?rbBoOW-KGLH zN?nPPHwGucNBd)A@LHioLJteA0a1AygDoKHFB^kfguWB{!=WkCy0c|mn=NDAY#HIE z`{GVJpVT$2Qk!02<_p)}gMvw!WU zQLl9|j$eBPA`Uwe_cG+z>Ik~yRY$N1vE9hm5nPFUL=)v&V-b%&b1tXYO3P9eOz!=I zMK;~HFsbh7v)woMzxb76w9s^4jk87DeSe|k;Y*ZSX1g<#WiqZUlUi+;e%0VDKGpQA zTIoae(ua0Q-!OCA#Zz&gK}u;7+8eAMi_r(`-5Y!WM0cq62A>4c9$e{t2DAgIjZ&*d z89N(ocPksErj2$pB6cC7g=_T}sEunySE+3>cAC4FcjBmR)9&_;ky?$hFL}?LL&xyQ zPb0$^UYntY$IToa;|9h$@~z}q;#&5&{)?u!JTi6RyEEnyh>N&t^50suS!1; zdJxpc*VuH$(#|!dE0!&`dv&sf`ybW5O7B6$JBVnP?HF(OITP1H7*)n_8@!FWjJFHn zyA{5%vK^IjPoYwmAeCCTQoHl8F$tUMl{ya*<{WT*F~xQuU;JKB!WSSKxyB~^1bUNw zRx!@lI2OhxB!g&tF=xLWlxows#>X@t74*zuO2U1}N9&lL;9k2-v0s3X+G>jZhR{}r z%z0}Gp6X2DJwt1oVty*cXlbU$Z`orzS6#a_kTC~BcG z+?zf?$(_=##@KX6?pOHC9JmKGo%>MPGR({qXn)XCh4~3I;~_Hhmz$B=$+2`dubU(2 zjJ;cqh265ZI(a*22HzYS%=hi^F11rAk9J69*D@%aBd_fwten4u>e)w&oydd^g>CxWPjw#(TsBsEC! z(CmiidO~CEDnzVCc@yoiFPqv=wB7UXSo>|~_*ls`81n$m6-=iyrTiDOSJ2u78j;Qe zRm+iAZ4W^z?cZwq7@?De&Jwy%=n|ppgdP%lR)~7t|9EZf;_Gy%Il+6bIV#pCoB&#k zd~>;0D?sZLCc+nE-_@W7(0r-$e5vz%sq=i>t@C`_t?7K*t>1jxt>0YxR+P5}<;~+B zLG3)(u7;1=V7~3vbiVD@bgum-QorH4d;t0Zv_k5#!v4~UU19$M`khlLg0_5xZI$4v zqk!lT5Upc{eX`KGLYD~LDs;clDxnQRJB5Phxg}=^9WHc|(0M}F3EeC7tWc}a7eYNk z8RxreJIu`{7y*VtNX`!s1v}U(Ci>>36qxuC)?Ay8C9fjn*;U*9sraMt1o&gC3^x zd^B&OXLnWBUifG$5A>pWHl1h8RRZ11-6i8yfox@wY-O>>J%<*1-22oe+@`eN5|4XL zSHi7JcUVe2?(CtQ%cI%D3@(q(zcW1U`8*h+cA-*c%X;U@dduY=MWsh(hn$bDi5E$} zO1a~|NJ=i}JG0-6!gwGQRFf~Z_)2b`qS2eih-I=JwL;5e9rdz~S`W=o_(_uVp<2n; zDES(t22HX>Es|O)>#di3<>Ff=C71I35~^RNhsJiA4VQ~=uZQlVAN4S1c%BEaMRdk# zliIgQDQ!}}cBw(Ttaq=c0kPB*_j+Ch(O%dhrIbqBZ;|r0NO_%7UZ<2dLcfPnXbw{9 zai7U`a|EBoC8CtKh_27)$vSpRDWx8F7Fo)5p>uqx^srK{3*W<&@+zgyl~U6-d3sao zaqkf9;<26DYL|U%nHlSL*^@w(F&yXI6X|+umwg+h!nez=b}0KFsn5W7FH(p7!}l(H zD>!1C#Jbnw9rmboW*)oE-i=ghp$6-^a!VzxB)S|!&^jG9UZ}E zaP9ItuHQUf8i#0>8}iZ&nP#~uUiY{RdEH~n;~j~7v{$pd?$MLQv2^t0axBe^awVci zTC&IEUJ+C)x(h~Q#2DV*l6=fnJP%IADE}ztr^d(hGJKOjBlO##a?oCn`($cN=wtY( zE_vP$-ZW2I8|7JGqa432@+`1LyW5d35#~)3Dkb0h8A{nYiryA+uf}G}^+P0W^O zv$JL1KHc{x>hd(|H<4>kJz`>L*d_RVAo!+)Mu2D^Y3tHK`0cSeJV6MlOYsyBG&e+R z%L7$~sKqH?b!ZY&&xNl#G|Qm^zAr#Eo$gyW&8)52TMJr>d>z38?8_CP?7+M5JwxU3 z9Tuv~fnM9-`@05jBXxdg2YfVo&keczQd?Cy_#c}{Z4h4r*RK=40GT_9aqEiS(ROi71txQ^K=h8XZfd*O_Ywx~41Tvr8TJ z)(B1SP|%&!a`EN!RU6f1hKvU@WUQMfG(#fFrGDkIwi!~Za;bB<)Oog~&XziBzubF} zlIKag6iH7sGkto4X|42^W~PY^m??zZd&9c|bTrbo?FzVk*W5eYc@ECvK6=_$`XsJ7 z=pCV3JMsJ{hkW`{i(~XRpt~>@Z~Vu4X=I?M&FP+$*_i(!qA!o9 zPvKfJT}IX^(udM{Y~O)=LC@ic=mB+v3P3apbcE;}Z#_j+0-ver6`&ydt_Sr21wD6w z%(ks@DClW(Xs-SeMDPF2l_wV+q2J)6J2oAm;I(FLd+nj1BT(MP&`1!CK4bKF5N+ic zJq1K}_eX@>_rn_WZ1{dfM1!t!Xtb&Y(KFJ~>IvsQ&0PHqe7z$$;^nEOx!zy#G+HRp zo&WVs?022%2Tjt$n&e2|t`!}P)$02j@Ow<~RjWURl5RAx~0y$rOqR?`{uwtZXqgp zpB#B5GH>dU_UqwN=xp!t(b&XK_T>G)kdNjOl$s)`S(2J1skxH6Pezq2eshoJr@20N ztjqGbbA~K=hcqPlQY2qU@`WT{kL+oWWM(Rp0JwrNhGS)B&QI!j#Zv?b4_4(N;Fd zETh4qBbmmlJo7drw!<71lbgxs&K~mk&2M_fyvt9|5xpTX*-D8mmeweiHYgEa ziTFyzSL$=GQx@sR{rDeU*jvjawOy`fmPv~*lTyt4=x@J*Ii;p2aTnoOn8JOR&I`l% zc%!%Er+a>{L@zHVv8?uj%PFhuv;4N>Y`54~@3!fQBY z65U#@OdOAr>1;YBG!aBKh0m$!%EU7Gs8(~iUB)1`L2BP1wQrExj|kD3=`_x_5V3S# zZQ$}~Hd6BUoLcUP)XEW1FGoPV^qfZN%^Z02LrK|Ul_)>(jm}rDc@w;c@EWbO7W^pWyoheMzYFU1FcAe#S zuX?lm?pZfQXoR%E2>k}$O`&6Tg!VdbpXB-7^I#sALid*Pqz3tZcczfJuu*6T_Avyvo@w?y0 zDe>nZwGPL5iT?%EAd^%7j-c-|9RfA+)g8ShV2E0>NxAvV@!Rn>=97}o5anz6M?P9d zC-RNabi{85wMm2_ifEIFF`6Rwa)di;ZkGr{6k)Ei_9NfuP%8d&`=6k8DMjFsRuMV}zecLt}i`zWznA7HQ$076X0@WoukXdccQEhV9xlQiE z&eimm=;!a_&Xb>J88q(B<~F7MG28FH*)>m&;=J z^;XKUUnwP5N-4FnZIv<#)XIIIO20d+S|n@R!q3@hv|S`6FOrfMNy&?(E{mk(EtWgx z9N<0u;U@P^U?-@S*Foc7y{xTP#)DcJ59(!Y^|Fq7S#K>9wP~aDmqr;knz-a>sn-cTcidpvfd_HZ;P~AlTeGaL6eY9q9gC#4{+>DUD~9)Tple# z=*4Y*cMjanHRU%dq^50B(>AG9o2<7@*4D1 zw}{WYKe>A|uHWQbv72j8`)#+h!EV`a`(!WdlTyq%{=_X5;hs}=OPzQ7-6tly{GIoj zV|BM|$1Zsjzeo0Ek8F95v|o>u=ivw%K|*||jgGt?Zd1Bvlp?8FlA0^;i{^1E_4a&8 z&6m4$1v0xX;F%HSE0BBz^8JqjiJ0P}_mFRxgnZn7bU&h6op_%aH?jlnlMwT?kJ{7_ z%}Rqw#}}CMWiY7{5j2LS`)K69ek-npxX#qGivl!zpcz0>z`ZkO^3i>eO6`tem71;$ z>Aj%7NpxLCBWB;E`|da6X>q_Ek<6W}mReHVZz7@!siXND!*svX zd{eaFr$qF9;&f1nv}uXduO#3;?cOUbik zZ_SfZ=KUkWog>YV8dNgT7R}(cqW6{-aVd0^E#p$?2v{bi%$A7lK6>W*4fau`)Syyo zP%Aa4mDqG{XWFajNu|q8JMZ$*mH!907MkvR2tIndZMyG?d(3-o*%FZ}CD%*I^-{9w zO;mD$JRQlB`#D+sT!ZeiXUYANMyYeL%<7w@V72FIY~t;Ks)Omsi{3(yu>+ZO3BTLNw$%9GSQseLE==!ohJ zj7ND#>>{G?1Rnz$mUJO}$Ae5P9s3>D#qinRVg#1*8h8dZ0KN{s>q2v>4$Hk8)nU1B zyXGtRsOXmZbxZxa1Ma!DTUva#tYe#$Y~F?K`yJjju-vC^+hlF~Bw}A6@gdY6`Su0+ zgH8qY$SANcFc?1Sf2KV8rkNqSuAQzAM=H(I%saDx=c5^!$#=?bmu8jWydc}LTei&; zbo-Sj=zmHn10@66@~+;5TO2HbVzO8bq_ z>mN4X8K~A-IBMH|pnGWx9>Mz?Ozu9a)=S`{@pP@+39Qx?h}eyMqkTcocdpu_|y$&DM zs#?DXs({aYmtrYs7LPPEkDV)H&U~ibNHyR3?Y#%2A6aSM63vsA?63~NS9%TgQ+i*N z=KLL&=TY3VJdCI}XfG>WdI|EC^4Xrw;-$fR?^bFik<6e<<#}GId^5IG zp7xc>6X;U;uEGr2-WhUK%#eORTiR;2w3WFoqrJb^cTuT1+wbx$#TM;E{Th`t-?>>o4~(e4CCj&+d&=jjl=b7A=-dOfpl&^`kk0V&P?NM|i|mD_pgS9Gm%Xq>N^X*8UY+9Wl(hx$ zUr?6f{y-4F-0}k3KI&z*DJsr3O})W3tlndr>*O2iS9}=er8*#lD*_#sB+jYQpd4fqRwQyOkK=&IeyQG^3|#v z*v8ZXw)JWu+f`~Q+eY;u+cjz}+a?ufyH0(@wgt}$shqg_gKe8i^3mrFDwA!yin86L zs@ZN)kFwpWo?+Xm68x0E3;mL8w>pyTPIWHZ-RerVd(;DL_u;yo^6ghIv+cq4FMY;O zMFq%ubQaryKAdex?_k?U?_`^ze`A}b|74q``vxg4tdC=xt0%D?s&8PMr)$^_*DY-G z^%rbM>78r~^dD>^+O%VlPEMfmPS-hXi*-KRarz{-CHf4u6ZB-ZrTS{NQGFL%Jk92I zoTlsf^9k-E5cW$Js8^@3392 z_pq&X^2MBd_1YVva#!hGwvGA(wrjNMFY9zEe{RubY~%Vewr%=0w(a^!wwv^8Y`5r- z*lyLou;=O>t?~c(z&A4Q#{KQntC)vuuZ2t!(qGPuLE(zG0hh{mOQf z^%vU$Yfv95FJc|Rw#dq7d%ATZ+hXf%w&SeHY)h<5*iNwSW?O1K%Qk9lW?OFk&UTtL zurHN6!zy4q)0)C|wskezIo1yDyyTl5zU54N6 zq|eLQ2Jk)YB>0n5%<2bgt9r+-veNl;qm{*WjWw8UlQo3xI_p2MN%;2QQ2rceo21&T z!};?Dwn_MX(jz(FChHjXZ(*B+-}XF?KXRb<754mrIfIS&R20tPwi@a& z`zz05_Rnzofk*7;Q66*tDe#!{PsC%+J4K$;kdE_$=KyR#E%8vl2;e-? zH;nBx-;r!*_>O^1Qfqw8Y@2+q!v@rDAGLcx?em#--S2$v@zH+3DaUWx(c?Gm7w`}L z5BdA}&HhO7Qyj)C|IzFp>iF~6A5g>nru=+A%_{&V46a0B>OZ|mxqy7uomiwo(o#wA#JHubccBcPF*nkQIJ{d|j6fpJZ z6ZnEZrvywr(gNN5IV)iLML4jFKj#L1U^_JMGuveWv%Sj$rk!e?@?rtAU8@{_qvP)k zn10n2IO{N4e>Z;)s+|F|y?dPU_BnAq{5hyRL311gf>b}h>JxnLaIz`E4%i^>0nqjY zRXDhfKj#KNXFD{w0~YNaH2pe1_&t9f75s^9Bxvegvw6KiH7D4I{qurme6I*n{|VyifsV_d zS{S6`5#xTaKj&M*^$V(HTwjd)!3_4-1_!f^1vwu(UBDVXT za(jYizpDi5x0p{SnEe_^n9BJ=374_$lW-N=lmv4er6tVf&shm`*@hEtW}BO^fbGzP zg>3T@?q)kY;a;}+2@kLxl~BuePcPFS_w_Q{yT6y|-#xvYdWB5?_JmCRLLrmCPsrp? z37PyQj(>vVFAdRt#rZDu-UzbYq3vvUhQ4LHKQ!cM^7n+y{7NO7&w<3_*dIzfi*298 zX>3yxZ)2O5*u*v~aUNt|)OV+u}qsUXM$>kUy6sUdnbt;?-=+6K`cZEz#6_M&cv3p`UlBTe2OiDeT z`pNDj6Tc_P#P3To`(b~Q*>62bX1}T4X1^8pHu=Z(Hu+0>oBXAYKkE3)9sji6R8Epw z*4xb6m-oK*MEYFYdpX-!?~QEhd;b87e%r^CALwJs5A`wIlhvmnLUG|froB#gKG*m8 zf&FV7+tkO*ch))i+MLfD`ive!>Ko_J3;T{Q_%$JU52u$qanq7Rr&9ckZOp`SUQxA&uY8}@rYn$P2Z*!HU*OLl9&2DY93o@U$C?>V;J z{noMF+0TrdyZf2>+n#=}uzz1aGmh@>_d0*>>Gu{}m14$KPf9y~4y1Ij4W)d|;ALT#j;{gE@ioAt_ZeW)QwEs*kT$^VhpYi+KZFOE z_RJk%+H>dt)1G+)OnVL=VA?Z(fN9SHXFU;TJw?uXPIt<$bkY|(>5H87B~JP>XFWYm zK9y?f>q#~B4Wyd-hEh#^`=pxsrlgwsrlp$tW~EYn6Y%WB_g`wS(^Jj%7dz$6c0SK> zKF@Q?uW-t(bmD7MPdS&$iKU*+wm$U&wyRR3Y#URjvt5&VHQT1t8`-W)tz_GhdNiulnQXgTvA$1ko_SCg(H>JMBc1vn2+pVeXY&%mwWZRYcIos~kZ`kfk-NSZw>H)TU zcsmo+zErD(>bpO+7u%lH6t*gDAX`t`A#4L_N3jj1jbhs;Z4BF#v@_VIrJc(*E3K4m zIBhE1+_Wp%4o$nBZC+Xh+u>G=JX8KuUnmPVr=_X%&I_1N8Fn!+zWY?u1HG#_8kZ#Irck*rGd^q0IO?mkl zCVf$T*p8WyWc27iJW*U6e7N?UIc1*)Get zi0$%>DBIeMscd5zm$9wSxQgwnjM;1(Gv=~glW{ZKri=w_*JUhZ+mdlN+jz#kY}+y( zV7nosmTh~+O17Ia9%s8HV>R2Y8Ee>fW<1ZfE8``$-5Ia3-I>wGc6Y``wtF((W4kY7 zGu!1u2>4zFk_T8Sk?)lP{w5aONp&b2Bf4O;AHK>3G3? zJSVOsvy0OwWSaYxrI~;5=crR&xl`V>Of#>W;gmNs)6Dl~XAUZ*^5$e7!**Wgscb7U zC$g=~oW{1%DYq^2H~zdKGkFrlwP(_OfPmVQY5KvwOw$kcXPW-hK8Kg+DQ*omvm%Db4>SDSS@+gR46Z0oabXS*uvF}7>6wzF+< zY}{E-Th@N|Z^#-rnabIebv)a^zz5m(aqOsppYZ2`fo6UX8Tc1I2UN*Gvwaf=n(Zqc zXtrP_;)(~-2=^WvuB_=zV;0? zLFRlB7-Y^Dp+R)Mz7=b3|UD~F_EZ%`{f2UO)CvwaH(neAIN$Q;K@2ATRS8)WLUe2}S6%*kKx}S`rhSHHoA$}eHv4^ew%PCb*|gt%Dw<9AUwx`P`*+0q)U@nB*v`mS zm(k~$**4qR**>;&vV&~rWrx^SWcOxUnVrmbVRnDEi?Y+$F3HY>#d*xBSFKZ@Shnf! z_1UH$t;#n2s4?60qcz#4A2ns0ezY#z-0x}0ruz#470)*JN!qf_eUc5?bl(E|f5;T9 z596t0i-#=d&*O%e{!lW+%(Ev9d5ry~LtbJV9kQA2OvgXl@y{7@_~o>|iXo<5D~C|K z;{K*n?vf$rAszd9$V#@gLtbDT8}cFBRgS-L$PfH^XwH+fD1Tng8*GQ?nDMqG$CN)I z$LzP#9NKS5D$4m2)wG<^SJUSiIpu6;=iJS9PEHIK_gQm(WV+ccq9n<9ACn({t)VhicSKf0)!(_4AL0-cfU$)N>{FBK3e%N}2lAq05!;pozFf zWjl1EiaK2Su3l}$d1$o1p@5!lpQ%7yAch5iLMDHZEQ`F0@R4$$Vrj@yueCtN=#wcKIo zVA30)GWZTA{pgTMt%I)@-=Aoe2%>{Y=?hWb->G;~Wg_UA*1@E*yYO2rc*?Yt@AY?q zYCLb_EdnCr!%x(xI!?_6nc7D|*hk2>0A$J|I+zq*gxumII+%0;d~F~T+XbpoQ|6)# z&})q^2C7j7Hy{?|Y==-`Ki5|TG7)9ss{onUDp0@Vv$3|A_!`95#l9x2qbS8Kg`Vrw zsH1PhduIKKs_((O7kHLp*3l*u$8}bXdVe13m#NgPWwZy0u-+AD-GQ!;$oR?z{gX_@ z*umuc3K4eL-RC(%twZp;8kbVZM5dIST(@K*$A@#k-(*TIgwMnhnbbOvQ&aKL{d|*3 zWKtJ^zAWJ_l2p2{@6_dAhunS8DPB9m_id}ezW9PZ{LGPSaCrgG{6GQJ$~5gA`0$Z0k4)k(hA zBiwvMro0{hB2$+_3_pL9$yWy7-{fqY`06A=4X1nyZ$(cULG;Y4I2xJGc?~`67^TiV zYzBrXJKv=`kU6%9YSaU7ps#^8CvE}lkW?a*YU93ajVgHyrGPdkz6HtwnenPnd}T~m zzO7W`IEpyA5)mUQV&Xf980D^)$dp_rJ|g3*V48UwY6UXu*dh6doLY@`x2O=bIr08Y zI2u7FqU?B=DnK>rN0e6wGOf|YzNNP#&j}RUZ?mBqRri4*rxc_*dja(2G&(*OaK!6~ z*a0%-#Oif!QmB`eWienfKAn8W!bfBxa{fgomV5`3CL>=V zQ;YB(Wm@O zzID7?3X!wkf05au@PB0;AhT^{=eiL@rY<=pu8+uRHIOqNNa_Od5t;SY{fnHI6kn@E z>;O4?^*py^8)Ql;1UYRbzOwUOACa>*kXc8a_;&n@Olsi;ZUm9DMdB+HUn|I|v!u38 za3hGE)&-fiwfp&df@MQ$lMLWM$QLJNfI zgj$7m2-&4>d4)n_L6{Z1hW;qN1wwT~twLR(8r8W7BZK(tNp8tOP>q@x#~3EQLZLFD z1wwT~twKA5?2Fx!bA$?o%7hjO)d{rqP@Pb#&<-KH+$|+Xs8Fa(Xn|1p658Hh@4;{PT|qQ+1D=y#Np#9a_?UhG z1+Q{b$1;&`*VW|nzN=LH8Y17lN>$7zq8W1JTB6tCbPr{8nwWKenBEpI-^q#B~sSUdTquR^Vuo&j|UDYOW#p5Qa|3nBw5nDvG4((o4jNiQA`&Sibk?-Z#QBxr` zfqdaM{0hm%ZoYCM&t%tEF_rSsw#AsJUsYU6K3ZGuWp2Lmzv*(=mQ9D=u?B;9x&87N-E_DmV{rL4@ zHS;UfKq%IWeAIsNL^m~z?@HIGz)q|UzfoaQ>HpFi3TF~6Mrs7#rL9qyev8<_M6^YQ zp7{=YKc9Sb2eNIP<+cmHSzMzA>_zHoA{sZ;(?oy%jMi8~MCHZS5>a`v^+aXAfi@CR zO(XB(dwe|Ciwebr;zH^@H(yvNA`}&h3B`rf`w}Y@5sC`MgyKSKlf()|grY(*p|}vf zzT|9MSSTVC6^aSPh13TUD-;om3dMxtLTajaC?*saQlCn!P(&yy6cdUIsZNO%iU>u8VnT5t^_j#9MTDY4 zF`>AS`dng#B0^E2m{43ueIcT8J= ziU>u8VnT5t^^L>|MTDY4F`>AS+9|O@5uvD1Oeij-c1f&IL?|j06N(F|ZzWbJA`}&h z3B`rfcM>ZU5sC`MgyKT@SCnpl7K#W(gL-a6iU>u8VnT5t^|QnZ zMTDY4F`>8+{voKle}y7KQK6VnTuA*Qu|g4{s8CEOE~I{ySfPkeR467C7gE1TtWZQK zDijln3#t7QD-;om3dMxtLh69T3PpsXLNTGZkosL>g(5;xp_ouyNF9_|p@>jaC?*sa z!oN&)_peYyC@K^aiVLYfBvvRQ6cvgI#f8+L5-SuDiVDSq;zH^#i4}?nMTKHQaUt9x zceht4A`}&h3B`q!mRO;PP*f-;6chzC?XUUiV4Mq6u$CruA{<25uvD1Oeij-{1Ph^5sC`MgyKRfAhAMmp)R3t z(9IVSst}3^#f7?r!U+;9R3Q`-iVJlKg?mY?P=!!TC@$0`6b?zOP=!!TC@$0`6i$>_ zp$egxP+X`>D4Zm*LKQ+Wp}0_&P`J0m3RMWjgyKS7Lg79VD^wvA6N(FU35EMgtWbqe zOeikYB@|AUSfL7`m{44(ODNn=VudP%VnT7DE}?LW#0pgi#f0KQT|(jh5-U_86cdUI zbqR$BNUTtWP)sN;)Fl*7l~|z)p_ouys7olECb2>lLNTGZP?u0RU1EhQgknN*p)R3t zhQtb02*rfrLR~`POoDEuFZ6{--53H4Tq*Wx!URc|c&slHhD z=Vdzk2Qq)i{4w*V%o8<5mGSZ#UY=-^XQoZ%tY&_Wm#w_)?;-z1ye#A86}-HLmuGl~ z+=E{w^d5rcIbJH~TwbpB-hG!+Px0~@UbcCMAd%op2*8f zeP`eq=5!yGb~!Jv@D;;z74s}!Uc;ViIp_7foXh?jd3h73-oiYemkZc)8|S=(J$rdw zzwz=QFSVcQ=I3Q1FSB_$jF(68@)%x@=H)58Jd2m-@p2L`FXiPmyqxQ&eRLx)Z{g*A z?62YFQ@nhQmn-_w+Q)}!tIrKn3!KNx3wU`EFDLPGa+q3U3g;~2);^p1ET+GXAE@3Gz?_8 z@p2fdy zW0}ulK8Kg%d3i1`&*S9b1<* z^KvdPa}K4W=5St);H6LfGBja5eZQn(n6dh3WADp1_N?Q`YCIlNs?Mw6 zz7bC_l}D*fus(d=4toe}n*BSTNh_?o9r_&F0rkI5si9CIbO@eKJqE3YUWDF-I-n1s zL3nn3D0DG254sy#0X+?U3{9Mi_#5yUIs#9nu7j3B4?#~t8=!6|fM?rj(0`yJXcBZO zbR%>>vc!5$=q06E9&~m5_>V&?8eua9VtV;ZfCe#ma3KT>CgT8{kgXZE%f8RUs^c%{C z@}Og&snASl0kjetw-D=xZia4y7D20_7oa$_0s0X78TwC^QpZB4LKi`^pasx!=wawF z=t<~xXgjnY`U?u&iQkZfPJl|FSg%PATlnK%A6)uMEgC2$+gH}UppqHU`=mY3usO)aEH8dZpfx4k@ zp}o*=&>xTwXZC*3QP4@yWzaRyJm@ZH(qgnLbThOFS_(Y~JprwOUVvVK-iF?XzJq>- z{)9qHurHziKzUFEIt{9V7DN53kp>+Ojet&qPKVBhCO~D-bm)3$0kj%=9_oblKnl-> z?|~kJ)c)+fvEJdB63aAQN4m}C2gbf@09)P!seL)B$}4{S0NUR4NBL5{f{j z&YxVb1!xC!0II1+J)tWfLmNTwK--|i$CdgoGy$3h-2lA=#i1_f56FH3?@K{xP&PCM zIt@Axx(1pHRY1=}FGK60FQM=%}T*F?4U!SJm^HI5E=_jgsy|Cp;{;oy$y9h z+o5lvJ&;<1F$_wE(x4-uk~7%G4!K-WMI zL#v@yXe;y;^d0mY^aqsmEb0v%4V?g;0$mR+fcid%^CWZuGzppx-2yFyYN5xVS0Jki z=Qrqjs0w-vdLDWM`V9ISItZmbkFgReg3f}bLNlS8pheJqP(Ab{RQ3Xn4`@GRy@)vq z6kdlqLgzv=A^M-Lw?QkQN1#>E3s4L6I@At*0BwanhrWaCW}JthOeh;V0y-W#89E)h z47vsC_Y#gp=qRWFx)_=T-2y!bt%Ei~9nkmCUr@r!XftRiG!i-yIt?m;qR^$#&=wr4 zuOKhfAIgOegN8$=L*t=ap+}$ws0C_;HbFa}Z=pSq{VL`!&{F7eX!UDo=Qzfg*Kzzp zWzdz-8fZ|fQpZ83K<7fG&|}a#Xalqj`U3h2`T^Pp`PwipKyN@FLZ3q0p&y|?p~N>Z zMnNY*r$FaH7eUuRRgmvZoI9ap=m_W(s2KV$G#R=Tx(9j$S_Qofy#Z~8dcTEZ6gmPr z9y%M!*@$g`Hbb97-$2j2jpGse4oY|j{R_&0R^_2j!{$Q^pvBOmP%E?z`W@=ijy%v9 zXc9CPYKHbge?nKki@5`I*n24Vee^x(4Cp-QT4*)&9@Gu>Kv|ox522Hw)1YzC#nA20 z5-1M63+;eXJJ7G7k0lEvSh8}?$ zpsmmqTXF0`w?b>6*PwTx&!L~89>}u|V-a)&GzK~wDu=FyZh#g;uRt52E@;&!7}uaT zp{>y8ko_snGf*~E2wei*2sJ_U-sd~eUg$SScVhklMW9om8PJW;V(4Y)s?V_BpxdFv zP!049^gPr8y$5ZFeuol1$6Ns#1f2|xhc1DxhHirvLk~iaLeD|X(A&@!=zHjA=ugP= z1@W;fItV3qW8MQ5L1oZY&~oTu=n3crXan>e6!;4Dg0i6Fp+aaZ zbPjYO^cUp)8lRy{pevvop#{)#=mqF~=u>DrvVUeT)b9}kjf5i5sZa@YB{Uye4Anr^4`>_c2I4)i`xIa?M7r>yYbub%C0z zE><_=7vpbHm#X<{ma0_OsN2;I`1OK$>P~eNewqIkwN%}zmf_QV>Mr%5T7=(wzgs<| z?op4ZCF)U3T&$v!l%^p>KXMCJT36NqFzvO^&)=7{Z;i2-bsHK|9|j(^@iGn zzYg`e`ape&UzPY;eW<=wAF1!u$7;9QrhZVLs2^3Q+N(ZOzaZD|>I?Ok+O919rSj?> zDxkl{tL!^flHR3~^=>s-e~;f?|3PKzAJq`ON9F0C)KU6pb+rCXjnw<`zlsj1i2fb_ z8S$Vh(LL${{RjRl#-D1E{!2x*(wAthr)iJAOndcA?bBClzrIE%=xcSNzC$PJD&1S( zsr%}Cbh2KoQ}i<3U*D$(=m&MGUa8acV>(?wp)+)Y&eW@QmVQPL)-UO>epzSh7Cl6- z*E#xiovT~*e{`EZL~qoG>bLb!{f-`{+x20(L+9y_^%440JzRI`5qgI{T6gPX^e&yR zzthL+AM|nhCp}XCrbp@D^=SR4#_RT0fwrv^wcq+bonW1$6Rn8uYmLz<*2y~6D%6?Q zsd}(=njU7Iu8*?D>U`@AeXMn+KF%uEBdxP^fpxZySm)?dta17@YrGz7{a2r9ovY8a zO7sNl0$pn1m*uSsb=0~@Pq9k%|Ex*+QtM(p-I}Z~x1#zAYl^k2J#+t2T*0p-2b-jMvnxj`)b9IAt zgI;aT(`&7p^mEqDy2+ZaU$hqJbylT*#kx(uYTd3|tvhtPwNQU#-K9Ua7U|Eed-QMC zV*Qs@t^3&b>NNX4oo+v%GwcU-mR+NB?OHv|en=l}KcbJbAJwDmI(>@$xGuI==}YVe zeU<&Bo^7wzbL~cbll_#gu%FiR?Pv6@_8PswUaKqZXZ3CNbGpiI(s$z<4ENaU^kVyE zeV^T;AFyB1%k5Y73i~x(W5;!^{kne0Zqs%48~R!MP5pxXwr;lH(XZO=`gQwV{kHv{ ze$ReiZ?QXcr@dK!W^d75_D6cV{jvVi-l})l+jO`6iT=j!)O+kM{gb_2|7!2h2kfu( zpZ3@K|CzfNu$k(9@&7Yxj%&{AFf;d^oRU*`BuSExBuSExBuSDaBuSDaNs=TF z8}a|{P5AeDGya3#tpAYr9RFc&IsXxFCI3-xW&a6pRsTtEZT~56J^yL%RerD5$ggSF z`Tbf`e^6`T4{5Fax^|mCqIL8~wY&T=?QVZu>*7ynUHwU|n?I%9=Qp%oep7qMZ)yGg zw)VI`tv%__XhZy2?HPZ8Ho{-1z2HAb8|^Qqz2rYv8|N>sz3MNiP4t)2UiX*Qruxs* zru)li@A}Wz-uIW)=J?BLbN%JD5B(LjdHxHu`Tk1U0)J&~p}&f@$X``k;=fQ^>aV7) z@L!~@^;g$6_%GJJ^)WB`|E1qKs_xIsIMgh zS87I}ftCq0)UtuAwPJxrT8Y3lTDd@Dtx}+gc445YRxNP7c2S_YRx@y;Rx8j#s}s0M zs~fmkyE1T#c3q&Y);w^l)+)dm9=Jp65V%vjGtf!9D{z-~PoT4QU!aTDGjNagK%lGE zCvczkP@uc^NT7$-KhRTqB5=PpEYM4PCeTM49_Xt*ALy@*2|TL392lUD4-C{M1s>Pl z3_PK|%@0_=6L?a4FYuJsBRo{=8-7~r7k*ZIBs@ZUJUmi+GW@*uRCts&Ec~MOYE;kUHy;py7X;ThV#@GR|*@NDg1_qfeWiB0 zzDm18U#;D#f2rN2uhH(-*J}6ZUu*a3>$Lmy^;!>ogLc3EjrM@PQF~DTR(nX_q&=)} z)*jKfXpidOX^-h!wa4}EwI}p#+LQVZ+EeqoT@^kdqG`f=?e{e*Y}04`BvyY z-zwej`%(}1zS2X!ul2BRy{`Md(IdWZ^{8*N9`k*t$9>=H3EvNT()XjD^8KV6zMpl| z_ls`%e${Q?Z+hDIyPomw*R#Gq^g`dC`Z>PCdNJQo{aoL1y}0i$y@ckQa&wG z+UJj)=L<&4_`;F%eUS)%!CuQ>j0HUSduCA)rxr-9mf9+{N9s70pEuRStuj=?SxOVB zj+Et$^^qDXm!59n&ar{9{PNzGsx7sL$}c5&om(ZOs#E!Svp4a)(OKJhRB@+rV;!B! z?Qa*Sa{JrOsoehNE4RP-%I$Bya{HUF-2Ue0&23e_a(kYy+@AMzmY3V}eC781L1!$t z=lRO*dH&Mep64sK=lP}N_B>y?{msvj+uwZU_BUU-{moBzXJei>JL@>n$~^{MZsG5S z!rZlbAC=$w2dVrVgQ#`RrRuo6Czlp=ZOy%v=d$PIme=(*cO4H(JtY-v?_Qda%1D)# z`s{XhKT3AsnRl_=k}FX8eN#1>vHi}amv!Qqd-2?KS5f&rYDRT(#?qbLvGb_>UcPv> zJJwI?38~6V_ntFvZR$g(>PfYr^6R)y#xi%iV`Ze;Q@=a&-a{RAYFZawiz$)Y(z(>5 zP8Gk0zcrjHFICjo^IV$W%e_>73rPl{zJ5_i(4HLS5%9xuJ~Z zZXf^oo}pq-{w8v!t3y5S)G%tkQ*(N`%Udq>N^ky>J}-9+rcj%lnkThX>Km!b5Ak|k zncN&b`|?-V`MG+8${)3g5A#>8Ggh0*-;Nqk&784|`@37vQ0neS-E%zmZfX8L=Lsr* z-;{gza#;D?I$nO#Jrm!MdY>v?A$RE_s=QNcrM{=~TlEK(zc0RWh&y&2Ro9v09V&m0 zPZ{dg&S%`(D|JZfxnb^}pJFV3408MXVa43GsQtZdIPV!cW2*WwmfxzP#$M&p{2tx^ zEPtO~kXzoxeQ`L&&vOVzP|iL)d>?~JS6nk-{yJKd%k?!38opM2GF$DpX? z+3)<<>5AGTwO)0E)HS0no&Triv3>C_QYbEr$z z9O_avcIN5SrDvX3U8?3#>rh*-j^Fs%?y*oa^3$ zbe9@R)mB5irhA< zEhy^VBKIz0{s?W6+C$~H;Dpq}n>i1h<*8>Q|KVKY(oEgl+SJ%DjMa0-?%(1rufNoD zRBPwbNmM(h)cuv(=A!0RbEu{Kw$)w7DXB8wyJOXD=*C_pE9uMb+7EUs30kI-Asz)xN1Et4r0rS)<~- zBU?YWrJLF2{8^%=Q}e1vA+=<6)YLNyHHVr`El-u2?#xS`$D>AmtJEz;Ek&(EEl=H! z&OBXFN3y8psil0$yVUt}?FXs9sQi7RnoeD+=1|kA{Z+?L&8zl9ZHu~8El;gOEm=)h z)Kbp&I#NqkYx}>mj<P1s~F4QV=k=czS42F*WjF=dA86XckZh5S>1yy;nIfA zrE97DIh1>^KVQ43{Jm7}egAxgckxWnnM2(t7IojGw!Wx)v!d=J)b*jReRcg7bsng7 z6jf)tyt6%$%YJo_%U4wX9RFVGXSwu%l-jEDd)ztHSQEycyDE3hOq5ICp+0oR8t>(m zr-r#pZ;|Rk+0Ix`Dt{e4Or7J5Jxk@cYLZ;~F_pjN?fc!Wqtw&R9Fcu)m7qpBW0k2_ zol?g|T?^`%s{K%P=IL^;X$7y&?NL$p_iD*!zV`e7;l6(L4E3KM)y{V8Y}cmt?cblH zsH1U+ZJxq&J3jSr(A|2A%3qi2Qng<7dXBpNs!PvytImACR@C)T`H;JPb*TI^{l3(& zYjRt!Uc2sc37_O}#?HJ|>XAtu7j>I1>TyObPtBqBx2QRanocc6?d88eZ&A1XH;%f0 zQSGMk*WdxE$O(6>v{X&0W>R-a-6wU+UwpcSza9BZHT9xXYCl3J-D}2_@|JR6gX(;m zPd;6no3}5YiOIhr`~;QXzT7W&RG4G;S)9aOVum0>h)Ol8m)TuQoSIQeKD)UXF{O$5mYO}NCMpS;u?WB5B6RYI5RK544-jA9f%RBSD{kTWTukFlRkbABE zS7%$)`+n-ZKy_{uwG_1lYLANAkKDT+=QYXgQ7N|mRj2v~yq-6ldYZ}~1NA!QOEUHb zmERBbx8IA`x%+mj{5|--OxKQeDtnZ#nBdPUWXd1ihYjov}YSr#^71 z7-Jth70vK@N~a2_RZivJt;+w!GNlB6sXJpAFvlM?a(g+AE%??MyPC25>+*H^6`TBi z+%DBe>IEvlEz@O8y$Ug3##YO8>iC`cxZDtR*LxS0Uq?|#R~^4IA2oGc)NxivZFyVw zHKQJ^?Lw|69gs=Rv${Oqw>#1f2M{x)2aKW+&y~!{XF#wz50tU z_x{2LXO5|+*Ykr@?^Ao6Qtt|?SNuy@?l!CUCc2Js-$7VJc(7nMJfMg2t(E%bU;IcqzI z%HNxnrSfyAV^Gv%yt>YFdv0^D#3Sbh_ub~)aX!ZxQ`>UEyYBT{p@aL#nR`94g)?2Q zZgEOYr{=xq9QVHNVJd$l)%K|^Q0vWA{*hSCyF=zZCRNmQ7Z>yX{SL31<7`VksulIB zZdaE4F|Tg($&+*4{WwqRBB^>(YQ1X7x&57VV{R!OO1MkuES3A6B>_1vCEk^e>Ppn*hS8CjTpPksRg`p zXSK}DJ4d$pqB7pU|9Yw?rMCIZXQJBkrp#O1S#nz{zXiE#I)7a5WUP#HX;H707PStw zdi(2oQ=jg_5<7a0n>S(BYVD-0#x?QR> zTWx`QHCgTDKlkH`R=Mk=s5y#y2LESS_c~WwrIxI=Z+JPcC-++rd=qAadoNnltIlU$ zirP1I{{3_73tH#ak-HX3I#rB+7rdTRYK}8kKjs+j%(1f!pEz=!Y5j8@Yn)5f>wjmv z%|%`3YF>4As_ko2!9BXK%6+GLT)3#Bd#T#Kn;6TV?L}Q%YHdYbM{2#NWXYim+=WuEMm@cDUb1uz&z9c`UK3~$Hio4`y zROpu6+SGd0r|Q%eT=6e=j%%rk&K&ABx1zRB?XTLtF;(5|Q}>SQ(}wE!scWIvhwi;f zn`+$7IX2uYQ(K(sL6t6@8+(GvUo+}eWHDN9R>{&#-?{xzG0TYJA-NG)p+ayM4}>+K)3I1GV0>-6M5xq2?`WkBS;o z$Kc<;EvU7rDr%e6J(Ajj+#_QC(<16KO6v23WiN5hgR0bjekOC~>qA`&MV(=1-qNDB zPtBn&RePx}Rp*8pQ)kIv?1y<WKgQ%TxCZMa`?O{r@|cs^zKuRZCW-ZYgTIqRxo3J>qIQb&FSPD{8CM97SEK<}Iq! zHB;23YOGvs_iy6d<8=O$kGW?k6>iVnX0GJY{HKbqky7*Ko)zTh_~*QrIP?B<>?&t$ zJ4?yms~n(icE$piyH!BtABDAYmis*QbfzIFag0-cb`scP3 zcgFtj9Q)5@z3Zg*P!*kZs4dMsBId8v+}~S&?`1uA&$mkLmO3KESN8s%*N`ep<zN-Jk6{~YV-jP+!WhyIW2P{(Bt z)8+T$h*a+R{Um4J+);bmDfKs)dSxfN)IFw^u5y>6maOh0>d2+J*WvECBX@4(UhBKp zsT;WTL8m%W`Ok%`rJVWRQQeFF`*RfaxbW{UrCUSyHuDgb|F(o0yXX==k=HS|zt=Q! zkI=yyd_%+;d!Dgpof=2I;FP+LP-DM_`BYSXI(hd&JzILCvDfp!ow;?qN9C_ewFQe9 z8{k~3mb^-)TPO9S)W3fW)Ew&iIP>*(wvRoz*FY=tp1^tV zrTM=()iVXPAL^Bf&zUa&%DY-hQO7`Cs&4UWkJR7J>Mzo=H@dIAUPk4&MZHF=>e&|V z{ol(}{##&g$=EC^e)c4xd*qP_;QICILp-b+l{mPkG z!Kvai-SeP|RAZ?wQjbc#AT?cTzSL@|@1;&j6~61Pt*X@3Qf;OBN5+AZao<1V>Cs=QP+sY|6=NZl_r zM(S;;#ZsH4_Dh96aMxQws;*S-2g~#KYdxgKOD&SxDD|7vNvYIacPZyfT_$zC)ICyz zq^3xHF117IgjD=PcOAu~s!ClW)mG|JsZmnXq!vhRl-eWZo9C|W9I2X84W-&iJtXy# z)I6#0qz+42AGzzOA$7e}XQ{`f#!1bQS}%1_s>FPE$+e|!mFg%pKx(|yLaD7%p^x3= zm6EC}b)!@dsb{4oNiCGxB6U#8THvnZUsBge-7EEy)I6zgq>f8PKXI2=PU;G&yQLnH znkx0N)Q?i9q|RIDF8NBSyQKO{jgfjwYKhcFsRL5UPu(S#mbzT3t<(UiiBb!tHc4rV z+~rl2YASWV)XP#!q<)r4ES9B6HI%wT>UpX6q`r_ETig8{?RFW{mbgnUB~@SQ6PcsE zj6EndRq9)*=x6Toe&ji3{(h~BjNL6YQR+LXqf!M+-KAVCb&J&FQZuBMO6``4eeN!$ zlGL?Q9i>J{&5>Fs^_x_DnY+BoQVpcKOHGjaOlr4O@C$b-7fH2}>M8Y{)GVoQrA|l{ zTkbCJQmIx_y``R!nkuzG>IW(R3U_(uO4X3MQL2m76H;$VEs^?B>abL3rMr$osTxw( zN%fX`QtDNyIZ~^newPZYa@SEp>Jq8zr8-F6FZGPnYf|q^eIa$_gYG$go74`u^q5p; zwYx1fq?${0lzLifhSYAUGGDq&X)pDN)Oe|nq_#;#*SPauB-K`Gh}7FsUrFtkN`2)n zrK(h8sRyOTOU;$qBy~*6SnDqD3aRc=qow9cZITLp?ao_Cs*zMzso_#{q&7(%mny!_ zU0!XeTcjSAdS2=ssiji8r4sAi<&~FeB-Kr7q||#-UrQa3D%jvIudY;EsYj(=k(w>F zUh1Hf`Hj20YEn(4?vZ*@>Q$)^q`sEgC&fQZ_V+!11*xm0?v{E?>J6!RQeR2^#^<8) zk0ig#nEkE0j&f3sq;8SwB{fWHywq%|RZ=^o4of9Bxoaygb(z%lQnyL>LRIYq}ob#m3l&IlGF!M%cahL%{{t5$(X*yU2k!zDpK{NI!Zku zHBstAsr6EOq+;K>>nJ5vORBlly;1|ECP^)k+9CC)RBWrejxti0O5H5gRqAo6Nm6s9 zK9~Ad>UXK+_wL%tN?j&(qtu;JeWYHNS|IhM)LyCMQi*Nu+KNlnk!mf~P3m!}DN-w> zev?Z4;4b-MsavE5NxdeuQ0fP%z;<^j=Sek{>MHfD)O4vYr1nagKf24SA$7CV0I4Zb zUrGHgmDu4ff37saK^wk=iJAOe(U|UGjNS z7fW3yb+c3#sfVPVm3l+!6RGu5yQTa;yX!43Ra>f!R6nWlQVXPhkkWR!%d0NcR;rKG zb5gUUR!HrV^8ey4?|i8%r8-LulA0p5SZbTpX{i#s-6hwSx?SoCsW+vTO6`*J{pv2I ztkhLf9i<+X8YeYRYO9oYkGs55QddiLks2g5Ug}e+ZBi$s&iTz<@`X}YO0|}HSn4&Y zPo%z)`b|pP>n=Gfb(z#nQuj+eEA@`l7gF1$PDz=+yX&YVb+uF%si&o0k(wp7RBD~n zcBwz5^nLEyibRa2_5)NN8drAA4;CACHB52@IGcWpJKZjbO+=pu3Lp zQkO`zlDc2&1*xf0Ur7BZ^_SFnf4b|aE!9@4pVSjluSbTVThutM#CUu+CBT_F&O_Tae>L;n_5qEi&r5Z`Kk?JP(sMIK_DN=K! zK9gD}^_!IMsJq^bRC%dOq?$-|lV4BT zf4T2K-yx;mx4%!uiu$+59+OMeCmW_SmVfV4jj4Ai)fT9C57qmF>itXguD*Jo_{{V6 zIO+B5b>2Nx>-~ta{I+~1r9O3a=1bKPQtMUkF{^is)w|8=`)ca_bM=YtEvMaW`H8B_ z_bB;9_ZIiP_XCXO|D{6pZ>Q$|rP2J@zyDoTwFUqFy#M|j6Fu7B--1=gN|m}U)itfo z2z4G5_1*A@rv3f?`FT{yuDPT3FRH9li^sX&ZaDM1=KqsR)qb3L>(ySW^RJ_9eeOHU z`R|;a?fLxwYP!*U_UdKl=$`Ess3YX@X@CFCq{hzns1*j>dDS;I)wlO9opLUFVTq3>Jdym_Naexr#hd&dB$1W4(6>^I=5c+ujZ(K7f1d3IlnPo{(w0US}p3)c^ON|9}P8! zIuq3yrp`%qu5~G`d475{cQn*@rfx5$;b+<(= zuc+x}T&Vs1uP>|VN?pkrJN%#PC~A2RHqtzUp8Mx?MU6e(O#Ayg&}toLJ65hO*Z#}@ zT*v=pOuJq4)SK|n<^6Ar6?Ob3-lKW0p7PIaX?m~bdH+9+6*X^BV?*xK{{BX(I?j8# zYo3`?|GAE{J@)?_(|yrL^E|+JA^+off41wb^RVU_IqSbSZ{Pl!r^)R9-n?hKeg7NN z-SU*?d2#VS_oK(t+TY(#R_8&HW6x;+<$IbviWn>ETr2g0=DC+|{{F}7t*CkbH;%#o zt92B04*gG#!3D2so{xX~=P~`?*tgrKXr3O2{<+?w#{T=;687YtZKgc8qvlC_e3w~ zSeF0N_?`B$Sf2lBo(lYyna2MsdA$6;3VnfNWq#$1f5pI4jge}O7kjGHHTa*#ub$P! z+^?Q#{O(z8ti^AhX`ahGb+NXmK3>i*pJ|LX#49|Fur9xU#$yb>ex@-+Q@oO2Khv15 zIbP*yfek$^@oIhnO=F%mc#WqmUeB+kY5aG4?Ct5mwmpa%zm?XJe#r4*PbWtDqL*Ju z>rD4U{#6xzVNK&V({c{wm)10XAFUgX^mNB*{JNUPucP(C`7E0=jiqY*PFi35gk@-+ zh0LvaKIJ#pG=3{>Ab#T+gquBs@jK5D+{&^we)@43dcDI@^NzrzcO<5~qtNh*gz2h+L9gi9B1myS2u)sSBOM55ddETjbzIPgy^G?Sq-WgcKI}_`9XJLKsY`n@l z2OE0lVpH!tywN)!TX+{>JMTig&ASNOdzawt-lce_cNuo_F2}pPE3vb8HQwW0gZFvY zVh`^+?CITry}TRo0q-X4?cIV8dbeU9?>2nMyB+)Tn{b-vVed}t=iP-*dUxXx?;ae^ zufy@|ir1a6?|E%imzzZaJ*KXDPKj+Gg+&FQ?;5n zL#u_ewAx%cTdPCQ<(J{So_T!9j5AGZfNQjdX!{yr+SeE}z9v}4*A&n9HDmg6zUFjU z$MU`wbOm2ayujBQEBV@BRbN}Y(AN$x_O-{GeI2l^uOr^(>%?;I@O7p;ICk`PVdPHa z+V^$EZoY2V!`B^q`g(Hd{m3=$>qS4{_@J*hBfTB_`1;Tf`TAmCUq2k{>yNMa2H<$# zK%C(lgzxwU<4oTWT<9B$-};8(7T<8(>KlPOeIxN_-zeP0@5gyPzo6#X&F{!@UHiu3 z9^W|J&o9Y&JqH~B^i5#opyOfRMEVH7EvI>o`X=Ks-&8!#FU)D46a2oM=J|_Xm(x5a z`E5DPbILahPxHHS+;aVM(CeRzntvXK{qr&DUw|q9LNxq~(DX0C0{>Dh^e@A6{L8VJ zeV-@g?b`nTcL{_WV*zXPxL@5E;Q zU3im!H@5We!B+mg*oNPo(>%BM4`5sWL2S=2&~eTBkKi5tW7yGu0`K&n#Jl(nI&Rne z3Z3S;+wa4!{s4C4cj&l{^GkGG+sr-<{(X4S#7I&Tr0Xo)P@w9QU;R-W>O|{Nfz9cYbe< z+dIEDr+HrB_vSRuXnt*uXKDP_oaPzhuc7g85%F7d+{zqZ_Sa%$oa1Uu~uLlUKSXSwF48dZD1na7MO(X1C#Ogz*OuI zn1*)*rsI8q8TepeCiV%;!iNI0v2S1wJ{*|KF@Gd5kM8F&XwY``xA8}XOG zCfps^g1-i~;-0`Z+#lGE2Le0r&%jPR9N2|N0=rpDD7c3XqSvDb_tIg3Lau4>1YIxFm5{9!DEbD==EfRC+IYKJq5v&bk?yjc$z*Z$b*xIf8meU zL(dKR=;FwuQZPW5bSxbVF;dF0Oi*Y1eB{0&7^TZ0&(MN#x&m@PA53DEpn(?$Exa_C z##+HFUKT9GtAfRtz9I4#T(CHOeXu0m6uq7sf~DzZj?IH*=o^D&8E=8y!vxFIEs^I5 z!HRfWuoAWpR>9kYRk1^`8r~bMj@^Sba73^sJ{PQoBZIZ^`CuI!6|9Rd1nc8V!3H=s z*brY1Ho|ei#yBz91YZv}#i_w&_*Sqv&J4D|_kt~PPOvq85Nv~UgKhD{U_1OY*d7-J zJK)k_NBlh436}>uh7?uwW$I77*SS2(PtAXxu zG#76T&BJz~`FLAs0k#h<#5+Tauv2IW-W6Jk_k@<=eWB&pBeW8GhF0VKp*7emw3c(A zPiP(ekmJLl4Rrs|Mtn512?vC>;A5e!I4racp9yWp;h`NkBD52q3+=)&q22gWXb+AJ z?Zt7SefUb~0FDnG#5Y2RaB}DfP6-{usi712X6PhN3!TR4A+Mij5g{MG6AIw$Pzc`- z={P48#ScPpoEu8wypVw(g)ICel*WajEPfg)#KoavxFl2@KMR$_rJ>UJd8iD25h{zz zL*;RGs3LwDs)TDoRd8*nDt;ZRhU-Graeb%;ZVc7L??Sb3Yp6DUAF6}9LUnOZs6PG{ zYJht~4gFrvz7W3z>-inMp8cW5^np+l{3Fy9{|q(5!=dJQJk$bDgj(WXq1Jdh)CN7_ zwy1^MVIK z_r>eO{jgcMKi&`?fGxrU@uu(~Y#APmt-?dFb$BS=5*~(a!^5#%cm&=S9*MVyM`4HX zXzUmsgLj6-co|L!FUP6jmH1|OHBJw&!FR%IadCJZE(veI&%+yWS$GpJ4{yPh z;jOqTybV`}x8s-L9r#svCw?8?h3mq*aea6XZV2ziP2qjGIeY-Ogb(7@@FDy@d<1_8 zAHyBt6Zlj3B<=~H#^1tT-j~}O_Tm0;01t#i_(xdBgW)J14#)9GIEhEY2A&FAXzOV# zp=YtAo_lZb0=*bk(~ILpdP%%kFO4Q^ zA-#FP>*=SrpdUuBr@!8kegwUqfqH9vTyKMe^tSkf-VO)r?eR&y15>`Dcf|2}CwyJ+ zj8pX7dz(}BuK1?j4QJ}zah~22Khk?K?|kH$r`{VE=zZ`Ly)Q1(`{6RZKYpPPz~%Zt zT%ixbmHJ@jU4>ll`Vd^F55;fwVYo>jj+^xnxJ4g{-|3@pt3DdP*T>+G`dHkdkHeqz z@wii;fIsUKahE;`_vn*xuRay`>CDiEPDUk!^TxWIG3@xMRu44n|5K|Ab{^Cw-pd`H@|8*~o6j%OMZKkv&);vX_x6 zk$rS!$A3i*FjCdATI3+(7dl=PIYd{F9Knkt$C#!D@>Du&y^7$T_3%kt0Doq0eU@GM?!Q%$3_vIk!u{UjYJu5?ARm{XZ$+kWRE22>m6^1 z7>qPSujj^yMK^bB5lPcGMY7m3QplyPkQ+oK_s>VSixj7CbG#!`lI|KQjol(;uzRE| z_KcLrUXhB}J5mYzM57@vaN2qLxVH<5?s zNFDkuq09cOngNW~3qGvm%Y?cOBo4G^Xc7n&1bKruapq87_}B$JLP* zOur`5lKv9Cp0$zI^jD5wN7^v54!LWLw8agPcKA)CJ>wf4H$^%y@~z|MNJsj+NGIGH z>5Sh;y5P1*SKJxthCfHTKoTD&c~4%u6if+dTqC2opbSFL(-GzgryYb2B9vl+gi%&)O;i%{Vd@Xtq zCq@t9>(L`PDS8a2M^E6}(UUkMdK%|My&>*yqdr_34dCi%2scD^+!T%C=4c$ZM3eYk z)WGdg3xABJaYrSLu?1FRfth&5x4@X}agtQBj5 zm&KZ5?N~FsJk}iR#9H7Lv6fgj);i?%)Q`2H>p5N-YfCqXwPXA$i^~NV+ zeQhNEJ`nfC?c z#i7^;d@(kXkuk_06R}bFN^CTakBz~Jv9b7iY#h@}LhiL<<8exC0?vv}#M!Y)_KHYxFj|gSI6ezrr3Pk z99w`}VheFcY!U8`Ey3SnOL1Rp8U7Jlj(^5h;-T1TJQZ7mr(!hRz5%20 zjTnn>!gzcOCgNL}Ch2Izw=t4(wBy_9bbJSvi0{Ob@m*Ldz8g!&_h7mBUaS<~hyRKn zz?$)ccxn6)Hi#d=tK!G7Vf+MM8$XFn!olj2qAnenRlZoC@KidV-E<27)8ye57guZ7Fw zwQ)tf4z7;Z#V_OaaZS7deid(sYvYYr%h$*gw0L7&A8*3Q2ISEv-V`^-o8gvtbNnve z0=LFn;t%oG_+z{c?ufU=pW^NCK)gL3jCa64;~nv2yc3>^cgEB4F6c>gMQ@@TYKiXX zOY}s4q8A1dy)l;PgQ-McG!p&LO!P-9F#ywvftXDU!h*zLEKCf+a}z_ccw!iqNDRmG z6Cv5dVj8we zOvl!V862ydkv{ zmMDflC5q$DL`mG0D2=})%HZxqS^PCo9``0H;_rz{xIa+^PbI3NCs_@(WOeib7*5v4Sh5brlXWqXtdDlG0iKg=h{ckPuz0dDmPj_ilF6o6I@t^>B%5Q!WDC3? z*%B)!TjRfyZLn&xEnb*xht-npv3jxtUYhKPwUV9ivSeqho9u#DC%fV`$!>UEvO6|U z_QaOSUf3$x8*fhb!8XahcuTS$woUfO_Q?TwdvYLlNDjg~l7sQiC8-j^JM-IHUnM{*qYOpeFw1n58_A3LpVQq1V2t5!v)C` z_(}34E=-=rPm^9g+^{I=!^Oz}ewGa3(xi@`C!@G5311|0E>9Y`B5C2uWExi`vk|Xn zHF77NETq>su1ywWQtG=7^bgPW3NadWafZcSFi?~|37ejD<{ zFj)nEN>*iLC-TQZvKqY$xp^h4)4Lt_Bx^A8tK+_8O?rQ_79L2}W}3svI`m)3x_B~K zA5SG4peNN3wNxYYry64*)dYj7rWj5&Lp{|Tqp21cOSQyAsx=y^HfW~WqLpfgb}ILY zk%CkQES2hrWm286Y^pPsOLf8WsjgTd)eS49x?|;3Pi&Ctg;%9|W5ZM*w)tx0lNPDI zcx|d5Hc9no{5s^pKQ#cGr3Nx`19B5g4Z;qo!FX3{2tJS+ioH|A@WIq@?2{USeN!Xx z;nXPXml}=zQ)6&IYAg;+jl;)Ny%IT%Fp0Yf>BWtJEf3o7#fwQ(IZW2IP)BwGB6> zw&Rbf9k?U46MstW!o8{8__USVYMN}~`P8pW`Y zQ5>%^N@8Q9G+t|z!DdETyvZn!EscuU%BX~`jVjpDsET(Q)v%LM9XlH}@NT0fb}?$< zJw|Q3&!~gljk?&wsE<9326(^G5c?R7u%FQw2O3TAaib{?GMeF2Mss}HXo16wmiUa( z8lN}X;LAo^e8p&ouNv)fg3$qAGdkiMMkkzXbdK_p2J(`I(FNZ$y5cmW8@^?9$LU5- zeB0=SGmPH&j?o8a8h!CyqaV&P`r~`X0Gw?M#P^LsIL8=_9~eV$t}zrpG=||kV>o_f zjKKNENc`9sg$s<)_=zzF7aC*nQ)3)1GREU#V*)NQCgNwtBwT7t#?OtZxXhS_Ul`MI zxiJG*7&CFDF$-52vvIXC2fsAt;u>Qfer3$ZwZ;Pc+E|F|j77NKSb`gjrTC4p3^y9f z@mpghZZcNmW@8O*G1lUD#yZ?;Y{2i0jkwL&gg+QtaJ#V;e>Aq?4r4q1WbDA5#!md% z*oC`{-S~^K2X`BL@mFIX?lBJFZ^l8~YaGJgjU%|vIEMR;6L`QliGLWU@u1=5djx+P zK0IUu@URiWBZiJgjVK;7;&|Lh;t9jRzYGgc8fiRbWbw37h#s>Tdd=dfnI+L@mPWr> z1_NeU44UOJWLCtmSqXKs3P#MT7&WV5%&d-avj!&2nwT_eValwHhFJ$qvo2a@eYDL6 zm^K??#%zRHvoRK!O|Z~xiszWku$b8#&ox_MakC|sFk53uvkjIq+hS?69iC^l$1-LI zJm2hyWz9}l&g_ik%`RBM?1~l5Zg_#&9V?kVv9j3V8_k8-!d!$mnM<&xxfENO%doY%9B(#PVjFWc-eRu7w&q&A)m(?|%nf*( zxe?o&oA7pX3wAKK;vMET>}YPsJIx)~$=r!|nY*yFxf|~`_h1)uFWzJB!>;B5yw^O4 z-ONLHpLqnko5!$+c>;TyC-HvsH1;yRaUO+DANDo__@EiWKBkTjnNjR(#_?e@iTz9i zA2BWLZ>I54Gm8VvLVV0Dh6Byw__$dT2brbu39}3iHp}9ZW_cW9R>Y^wN;uT4f=`=O zahO>RpE0ZBaI*$JYu3aOW-WZqtc@ehI{3U<7e|@(@ddL1jy4ZT@%qBS2 zY>F?N&2XIA9A7b8;CQnozG}9{31%C7&1{Pk&35>@*&ZjE9qW_H83%N!v8{aYe;7qeGzH9cwS!REH&m4fW&4Kv7ISA*NgYg4% z2+lQ!;)muioM#TlkIWG`-yDe_o1<`nIT}AP$KXP9EPiT^!$szJTx?FjCFVr@%$$Tv z&B^$=ITe?g)9?#(IxaV7;0kjlt~6)iDswijHs|1%=3HE3&cm=ax8jfH zHr!!u$Dhm{xYOK;KbyO7m$@5%G56qZb1(jC?!!Ii0sPH8h%6;9sVNC(SgTGP8KvEJTl0 z482xy)U1-|vr41iDuV&5EC#Le7_us2*s6rORRtqfRg7BIFlJT9xK#raR!vM=wJ>GX zM#HLurd1a$t3KLR158^DF=I8ttkoC`tR`4!HN|tRW?0N>j^|n}u(;I{OIWS3q}2vX zS#7bj)eg_I+G8231DUnDV0FccRyVxB>W-DHo>5Ut&w=SH45uk zqwxxB4A!;AVm)gd*0;vvmDU7oU`@oUtV!6=nv7RlQ?ZdX4X?4LV`FOuUTe+7Ce|#x z&YF!)tvPtTH5Z#%^Y8|1J~p=&;EmQoY+)_Jo2(_+(prkGtYz5RT8=kcE3u8W8gH@I zU|VY~-fFGGcGd>G&Dx0Vtxb5lwFNs^Tk#HS8+Np|}2i4yR2Q<+1ibFTYIpJ zwHNQP_F-4+0N!gI#BSChyw5s<-K}HT!#aUIt&@1absBqFUcQO=faSy9RsbKgLfFUB z@gXaUeXTe?Y$dUuW#A*0h5fBGK5AugfK`Z(S;cUmRU99;O5z}^G(KUK!NFEpe9|h9 zL#&GUlvN3bT2=6At11q&s^K$MbsTQhz-O(RIKrxh&snu`q*Vu>x9Z|3t3JM9HNeqU zLwwO{gk!A6_>$EG$68JCWvdyEvzp^8Rtp?&wZvDg);PgxgRfa_aiY}@U$@%hB&!3y zVRgjGRwtZdb;hYy7kty|iqoua_?Fcjr&~SoZL1f~uzKS=Rv(;c^~HCsemKkOkMCIn zaJDrN-?s+g9BVLsU=6{!)=>P=8iw<%;rNj?0_R&J@ndTgF0e-9C)OBTXpO~Bt#P=> z8jp*u3An_Xh@V-LaH%yJKewjhGHV)sVNJ*7)(l)>&BT?~EL>&H#?{sw{L-3>Ypi+r zl{FvNS_|-NYay<)7U6np32v~K;y2bZ+-NPwZ>^QM$y$w@tu?sCT8rOV>u{^J0l&94 z;x=m&{$Opv?bcTO(b|SPtnK)dwF7rrJMm|07w)ol<1f}8+->c}U#)$($2x$&SqE{i zbqIgAj^IA)81A=D-~sC-{$ZWQgO-=?!TxFa@Q@Y2!&V57SUMiHqIk@T<8dpACoBX1 zvMfAlrSX)N#nVmqedk8vS+|4A^BcXqU&3T@k}}CDiRI7_qBj)UJjx zyE?}08kn$aV$!aKDZ4frb{#bBx@g(;(Y704+HQy$yAfvX##mrC!9u$!o?|z|Vs>*p z*KUEu?Uq==ZjB}FHdxATi>2*$c%I!J%h(<8e7hr-wL4)syEB%zyI=*oD^|3-;RSYg ztYr7Z%62cTV)w>>*?q98-4`#k`(ZV^KVD=H!0Pruyx1OuHSEE7i9G~s+C%YDdl=TT zhvQ}T2&`?7#LMkbSjQfXSJ-2)u00m(+2gRjJsz*LCtw46B3@-r!iM%_yxN|MjqGW7 zjXfP3+cWT5dnPuqXW@1BY;0=J!Rzh0*vy`XH`w#BxxD~yv=?FvdlBAbFTs}fQfy@} z!`Ak4yxCrfZS2)}i@gTh+H3JvdmXm3H{fmdMr?0y!rSdF*umb4ci7volf4}~+dHtk zy%T%byRfId8}GOGU@v{i9jm8jV2$)lyd*sfYo=#o{q!7cke-VT)AR7^^n7fTUVzu87vlBlMc6F81e>Rq z;*IHL*do0gZ%VJkR_WDvdwLCaNUy~^((ABedIR2>-iV#joA9pm7VMnfiha`C@S*f} z?3>=f_4P1v-llirbLn09e0n#IO7FoJ(tB}qdLO=+K7cQ$58}A=A$%o$1jnb3;j8Hr zI3ax!r>0Nin`y7f8JqUuTj>B!PlxdBw2m{FQzMD31R@%b%(rKKX&f*8@ zLY$W_h99Mi$1<5-^!b_ISRvB~D`xuQg_(X>Ez=(_$_&7ZGXt?kW)NPI8O(BO zB99T7A$VD4DAvvl!^<RJ`)3y6W0@s5II|R=$}Gd-ndSIgW+jf!tj3ozYjAvKExwjnhm$iK@XgFd zoRQgt?`F2(oXl4IFtZI8WVYj{nH{(^vlG9_?84QV-S|~z4{pfp#cwnFaBJoO{*XC{ zJ2Qvym&_5|n>mL2Gbiv+<|H1?oW_$Guf>^=^{oAzqj*hBdOq@zQKbtdlK`^|EEKVYVz@lP!-;vla1%Y$a@&t%5ga zt75xsHM~7r9Xn-f;N97p*ezQNdt_^4?`$1>C|ei%XY1o**#KOW5vz?0d5=qVV4 zfr7ypE*OIGf}xly7>4PB;aE^G0*e=n#8L&Lux!C-tWYops}zjI3k$|!je_xbX~6`n zQ!o+h6->g$1(Wf*f~nZNU>e?3Fdf?z%)na-S>cTp9*wN_ zUQ+1utng|?q5S89J& zF78{Y9cIdv+EJ!lsU5Fel99ida;0{PDOYm(8lF{}ze-KtDvd9i(cvmlZIu?OQj3xQ zkFuBVb;e?gI1E>9c`+ zI=vjsPp8iS^V8|GF1j-Nbb8rEWqzLn=BLvu!2E3byo>&7$7jn!f>(WJPbzQn2%s zUZ1`K%+IIST=WU_C?^XY5Bydix(m^Y+v1oMXU zO<>-Tz8TCL(zk$lL;6-QZ%E$;<`>dG2mXchonU?;eK(k2NZ&!)FQo4Q^9$*F!Tdt{ zJ}_@g-+$4cJ?zHx17O~meh|zX)4#juFM#|5m^Y>$2J^=BBVc|p{V14UOg{$Z7t@b} z`Nj0#!Te(SNie^dUJK?I)6anUrSwa{zm(np=9khN!TeHsJ!!v`-UQ~C(wo8jQu78JHIsFcpUrz4=^QQEki?Z~l^jnru2b} zhWULE%$w4mfO!*J-_w)-NOz26>3^gT8_9UyIdU@3CyfmAd&=eZCA|>L zucRYjekI)n=2z3pfPXc;9L%q#&j9nQ>9a`t)%4k5el>j#m|sn=0P}0<^MHRXodol1 z>0U6umQIlNYv~l2UrT4e{8~B(=GW5~jErVqPxpiQ_4FW^Ur!fDo(trKV17M)5tv_3 zUkv6g>B`7=A9hQ+3g#{8Auw-AuO9gxkOr8yq)jkyNjJd!M%o=2-uaF62$VBVU(2FzR2*MfOl z`g-8ErEdiDw)9P4-j=?Zw6~>i0rR%>tzh1kz75RV(?1_M`-I!mcY=9)`ff09Pv0?e z7LfOVd3*X^FmF%a2j(}^zZBqsmBmMW0PXYNPn0KVtf_X>!88E+zY6A^=^eoDOm7AA&h&OL?@VtY?VahJVBVR22h2OuyTJT*dJph# zr}u*S?esn{znwln+Ha>1g8A+ACt!Y?E#K+MchVgfe`5GMDOYrP-g)uK>37nTF8&md zQ!YNA=SN(8D)7_5{BHU<;NMNp1oOM;W5N7xdIo8~o1O#achhsh{BC+4n0KWY0KY4J z3Yd4LPX+U?^cP5bS9&3sccmj>-j(hG^Ly!K7vI10d+Ft1elL9nnBPmEb@7jYJR8jK zrOyHLd+8Nm-km;=9PUmh!Mr=&3+CPF1f|@aPJwxMIs@k2=^U8fPZxoIKiv=J_tS%5 zem{KyX}_Po5X|qVF9P%X>5IXAS(aFa2{$xi5VWnD?dc1@pf2ePG_7{vGi9(+_}ofBHc%?@!-P+WXUg z0Q3Iz!(iT@egw=1(tii@f%IcwK9GJK%m>nsg84xDNiZKsuLbjg^fO@oD7_x|kJ1~! z{84%%m_JItMA{#vH-Y)1^ky)BlztV=2h&@?d@#Kg%m>rk!F({i1I!20JHdP~{SKH9 zrgwq)175Hgj{xp3Y@Smnk`g%B}!2%_ere>!dWB1T)R{f|+K|+qJbL&8EOivl%ecY!1vUdjaq)+Ye@z z9RxGW7D=0BF9b8oUIb>Ay%@|L*~+e8-nk=N1#?Gs2+SSX)w`YxqygrRtO@3hYy-^U ztPAFFb_C4f>=>BC*-OA2&Rz=UaQ1RAhqG6Jc|!KOU8C6v*=xW&A$u*DCuG07>$yN) z59SHk8^JswdlQ&Dv$yQ}`BQdgZv}H__BJqgW^dp1i$LB1=FaS$VD8M`4d#j2dnoN!iE2JURO$@RPG^!8|$p445Zp*OB(*?0PUy&Tatn>e;5p4|)P!?XLq zd_?vj@JD1n0rL?V_ovcFWa%ZJ0=Bn_Jf8;U zso5jJJT*H5%u};7!8|p4ESRTdPXc~gb}pEwW#@r;T6PX;Ps=U<^R((@$ZP`4 zM`n{?J~G=2=A*KC;E&2?zNL&&XZ`<{8uu?pZMsk3Ff1-4KN>_wJ-TOAYCvYogD%5(b+LD z&&*zV$#Zv}nY|p$GqYEKd1m&~OMV&1HDI2Z{Wh3qX0HPCG1>1@`eU-!fccp0wO~Fb zdmW`eCVM@YkICK$=3}xqfq7Q;7BJ7s-U{Yf+1tQ8D|i4&(8jd zJkQQP3g+3_$G|*0`#6~AWS<1{oa|aK&&fUm<~iAQV4jm*59T@94Pc&=-3aF6v#$Yv ze0DRKkI%je=Hs)QNc;Hg7BC;5-3sR8v)jQuH@g$~x!HHXJU6=w%yYB5NqcT~518j> z_kwwDb|08e$Q}gq3E5A;d_u;}zVr!My8BZ=cI-Z%=ZEb+75L8GrzhuSkKDcI5$9!( z*q!lw8kpy0r|d2PIRnh|vNORvFMBMQPt48%{>1EDFrS#62j&yACz1Av*#%%eF?$M_ zPt2YQ=997ucYk8|N!bXPPs(=|I5pN#=OKYI?C=Vw=d zd4Be6(w?79fO&p43Fi6PUNA4nrhs3N&4779HV5Vf**s}4$QHr8Alnb-1=&F`-_P#( zCb$or2{1xFdgxNRXk)QC4HzrAk@KVCN{~I3B@pAii z!pUzzVM#cjP$FDKSRynCZy~&ca1-Ghgq8n}2Xev@!mkrvMR+aY8E;LJQNo7_|4Nwp zlO)+s_XPnjf8(ATt|5M+o37K+Mg!LtMNelI>NPtFAzTdF6fHzMZz!r z8GZ2=^ef@Zgh#%I@gQ7CSpQ4t=Y2`?Lc-p^qHhSTzfO|J<7xHDgd>Dc52C?2`2_RrlaxWYxy(+RVL zgM=l*UlTt1^(6U!Zo&UQ;fsW?5q?UTgaJJHn@RHUJD5v^OTNXJ5U#nCxkGpZ;hzX! zCcOPF#+z^tA^TpE{J(_JyQv%DPY5>Q8tc;ZF!ZB>a@HbszKqvpJja zeZr3j6Auv38U7>ukW0Jh4S%Rl+$K+cWdgpG?7*|(#0%u|O5Zm$DDJr(e!K@1EGLyQk6Yl#Z1#p8dRgDrHx?r#;!#?x~!;(mh?7y;+~G z7&@9g7S4&5dT1;AIrsEy+0*nX8G2bZ>7M>LI{;TjTRZgi?9DI1Q6CNcM)nUp4fAwc z_8Ir|&Ft&?v}5Skb{zc;OYyQDzwe%YeaE}?>58G>+i~=jR_^cbc%wc|3_WVN@@nh9 zM-O*+dKk5O%G8wwa8FMde!o6V4E@dUFTwj{JpOig zk9+$2;e+n!L&GcX>3i8GeI%`q$xixTk*`{u}r7iQ!MW zCp2~L>C?lvxu?$#KfsgF!RLlgeyu%ye)t^s^o8MP>eCfNUmV`gleFW@!%O-!G4vn9 zFLSW33>#ftG4!9qZvb`zcwZlWn~VL%@cZ;>bm%q*8y)(ld)hPft$_FK;ZG=DGW6Zy zJN0RD=$WVAau@E4sMw<~6wA+)r^j44gdLkaops?^`gGp`X7q`7{S9;U#8x)ZeK_RgZIl8TS*EwB1^AEQ(sUZkF@?+vdiG5I%%`}A?*p7xg>v)E_S zhF9Tl%m3w1aBYB(etHgJ28KT=@2aUh?xYZdq`~vMp1*zEHTbaifBBP@_lsx65F79H zcMFXDIXr-UGT~u_$Kv_;Tznlrfp8w-iG(K+&L{i=zKwU`%lHz)rT8;`T5=g@G|$1S z@E*Jo?@69Vcp)B!e}(WO!Wt(vSK}%8Frh(MCo~By!Uo}GcozP3!Yc^BnY=Q&hTq>J z{5Ijg5MD+2o#fTYA11F$UQc)f;f;hpBD{(4-w1Ce{4wDzg#S)>E8$NFZzKEVmZs^$(&2P} zx-YG!FHV;TFG;u3Un9Jf@V4|%()Xl)k^Xi1SDX$_B>$FvoU@-9&U2p6NzDPyU=DD) za)5J_1IcHI`)v9;&O2VmNydjbqxfe|A3n{w!e=-!xSg|rJJ9lf3;q3_Xy(6-&iw(j z=?|bMe*g{m1L(FNNdA*NzLvuM3AYfwkq!^tn(iFBjc_}je!q#I-#hT#`>pi6p*!*0 z`|b3Cq3__c_q*v+htOCKeJ|ZLba#5m(D&2JhVDtnhJKLl8M-$u5B)H`a_GMFz|j5a zuM9mv_z~ej!jB0*A^bF58cMR2p&{{3i{IIdup@it&@ka)*$0PC$UZu>GrMi*L_SV= zQuc$PlL@ELc@NJ{Lc{QIbO)!R6?ioJ{l~MDzkogZli7Vgg?;rNcFcR&3s0wy%|6af z_aJ-N2D{VWVBh&hc9d^sulQzmfq%yS?!D~X-piisuh?yUh<((*=(KoF@}Vni<~%R? zSNC)*z+MubJ{g{_4Nt#0102l%zg34NnI%51SeO3A{}B>&$S5j3R#*o#11S z?(|Pv;puZ{df1a6>0)v7M6Y*iK1xY^S6;wo_6a+bOAz?UYoA%wPyIWAoPd0N-I>q(SJu79NDo}_7-`Fe`uxhF zJ=Y12{k{lE`MNXz@Q0Ozb$B|EDFNAL4vV2J_j|t(DD2?K#PGeYxH0v{t(#2Wm?r6Sa*-YiqsM?2fE7 z8p(LOw!(A0+F0ne+O@s4#zw8ZZIWcB+N~d{P1m}IS}UDoe7-bMS-fhlWKVOY`GxYr zqC?7aP9|!N)^fE`e@Sg+zSe1NwwG(u)n;{VKuL|-8b!34r1A9}Z#6sJYO~vkV53W| zD{EUvTWxBQW6o9E)%9Ap)*h5(;c$IpAY9r#S#Q+hoU}70TaA@kI|lcn?P;`@s*SmJ z>qs5Ug<7{;Z>~iZTG(8gsJCm&6j3kaKVMthUu|p(Y>b9<63KaCtJAHm52~XtVTR@v z>T`5us@^=@Nk-Qg#J#mDwMfRQo!aG>m72?~6>8%~bZ@n}(x^?>I~`!9W6QM->E*?( zjap}+)@JzYFVTJRtrzP3QC$bq6`=v=jXD6Syw ztarNYE#KHMsKp3ZN#84pe|YgF;c=ncmcI2d$aG z+Gr@C<0>o_p@ZhSZC4Ee6sPV~YpvDX*CBf)jHJBIyzjJ{RY*0NU2ug$cgysndz-JV zHf+=bV6Aq{*RQt0>?8H0QPAFM=MWQuuAXf}Q8fs)BX0}8+8C35)FElh>-hSLLKc?W z^^LBB?5{$U44v?c#t|Ka>dI`hu?4v`-0&P|S2u)P9cb6PH9;N_2WSrRpdny(w}e{b z_wiQ4H7P0QLo(i4U$1w|Oh&=)DK3s|FCT&(GS%8!I-i&tT}CJ=H;*u*R{A5D2ZO+i zw7gN9C@u7-7_~AEt~VxH%bUWt69@84!58YlzQ>I69kA4>Nm4gfqn%D|eW|hK=Zb$X zHILNWt)>;?aKcdkD%`4DBnTrZpE_i|)m&z_)~f6C#*l=}WYUbuq!~SCsgkixW>?u* z(0G-Jm5gt8x~=umE;D^;vs*KsVNs=ay9HNY0cm#H6~xmhJm`o{)zAs!i{pz2bt=Y@ zt;6+NG#BD19WfU-(dtZ8yS2sodM)t}t~Ay#w=_9`Ov8zKXQM^ylJa70eZv|puv$}q z0u!tQ_3k0pab;a>p+ie4M0-4}J?+-!Ms1~BYBKU|!Da?2&_QIj_9M-%I&QgVbllap z>_1RM$E=x|A9aBqwP`qq=2itoU@EPcPB4OIO1%EOxSf zY~RMVlEsLwxbbw8Y3jR6mZPLx_H2nsDGQNn8q!GB&2L#`LA%_=xXJF`l;ccpHr=`f zUbG05n{^o~$Cccht#q5PHCa(cSJvxIC%1Ukv(Sa6-BPIIKwnwqB=6~}@Tc9$UY5}V zt@dFSupFFB)tYPFL$DJVC)CnQA^x2)38gKL&M)qpE6+^MCUf(%HpGQ2WDLw~z?P0Ap8G_Kwa>@H##BXe2_}hzoV5PJw%V=gsb$pBbI9C}J$T z#Dh!p(pAa6g_(+nXsYSS#Y$;r-*l8?snUlvUz!`8UnnV3Wo+N%WNF^yVO>NRYMGfP z9J~H!UsD8cuGG8py-?=mCM37zQS(uff<4!&YM zHxb?=0&@uh+fw9-+L8KltvoxvIF*dE=P}W%PtbBv1tIPEQ#RvW3m2wm-P80Ixp*j| zoZmoBjKLX^pO87E%h=`UKSkFklIedYK+|MOD`DDX>}U^V?eXl1oMbsI9b+(+nfM6V z^~5rqu1>X%%9JwQa_O#g47s{fU#d5t4Zm8IWsiw0*p3i=)_#;C36W)>zKT55SGk@v zTC44+Bk#Ax|#yOAZ+5d=?@bJb2qlnik}Y^-W%E`GM=y0S!|Y;AVqY-BiUZFV-k z!8Uvz>YMYk#p>W{ZsWDylzCi{T$0lIMt95BB`V_!Du8wNgcz`TGxroi6rG(j0$!{? z6&~k6jDHP@wV1`$#F&rCiM0R~fkZcZ))HZ+SF+nwL8S*Ca>~a^x5%XJ9 zfgrj0z1~D^wcf0o*f$6o)K>*Q5c40EXIUUb)(=__1x9;LT@H-o!aj6j(`sS+p8*(b z0roZPY{ztiG#CLAMn~f$*RV{v@#(3Lht@mG%nnwgoc?W^$w)?(MnxQK-b;+l`(DN4fVjOe<>Y zz`S>hV_{Qp`z%ChXx+y?KSGO^0GPNORS#MytAF5{M!;yYsD9*8q8^851rD-hNz6!8qQi zGkc0K(*;NMRaInBD>#MrSLRZlvY<0`JC9--kL#I)+g2H2yB$|POFecmk9cEtT#VjG zr!MIQTj4niadn!nHE72OvQNEq z_gFomcB@KnGS`BKNbTEM$}^^@xQ|`QuB+!aIg?qhIR%}sqVJC5BKe|bYTe0WE`tFD z`N8bXyBF@WbM^DlLIZKGRwa@5C*=$Vq3N(ITPiKwCLSuMl@#g7R03u83Q2hnRSsJ{ zWmLz!k|(4vHs@aR%A1zdzlTb9Hs}Ud5ur_wfD&t?8DetiW;a5KUVMh*oTPQ;nC`NV zk6ToTkPV>D1XEAgL0savQHc$i=&3xn=m8fpa(%!lT~w^D4`ZCD9aeQiEvkl6p+=!{ zT3_947{)AGC}qH%L?ib#JDVFDt#-F2axyDqgfNbp+zvq4V(UhUX&3=RU&)z*w4uT2 zLu=V7PzNC9>~cV4=-1YI&sGZBFvz95Ly-Y?`DMq0^<|o8kw-yC&2HYp{YYw?9OW@` zK5Okv9Rb$72rlxGB#vP|-||`$u|+jDoU7?^pb~;hB0Ls-uIylA%)EOV!(|8VOZYO3BMIxqNi9d&nynLtD@px0;Y3r0AX;mAN;RKb%3W z)Q-8TI1U(}%#NqmMVp=^qU(*94(?`TP zO9rA0ueBWt>Tx-nZfg$37&^llD`;dsEWH`-YgUgiwz6u6!|e!1xn3S|+>(U4Lc8^R zM{><;Qiu=rL$>mJiD>6#N=rYkt|^kitR5G}<1t=E=hvvMlURr+g6sMj zDjO;@$qu41D5Ly%aZv082PrJS1FMiLq4VO)m>9^Rbk`kU4`O2laV`*C)P@2=w8P4a z@e5^7H=4u|>+66-O1Y>EAJHdV48SQaL;Zc*x8E_qpr%>Oz&6cPkJK@A;q)#%jc;=P z9ycc}%BthY`@?ED5E!+`utK#4qKDY+(+#YBPu@M8peMF>_d6&Wl}2y-#+fB3Wkpjf zdn?mKgbEMNRMIT`AEiKYD_>c)OC-S8{Bra8`uc(}Uye`kNqB(P*)@WSWY#nVba`3oKYZKynrfOjb22OP^ z1v+W2r(!*^fhwaa^q?HKkp5NCr|##&KE_Ge14?u;150#c(j&yV1zMm{ei3c~%G4M% zr1Le2@D_G)3bGws8I5pe0QulWl^fKt5xS@w;thyZXvD-v23F_1y)BsnebKFSPAH$^J_LLD4#{9DoF{t|r z2oKq;Xxt>BX{385gG5AQ*3*I>qEdSTjBeq!dErXsrknKyAAtmSMpSP(i3rGJ+Otv- zd|wWPi+FDJK$h)^kW;rFkY8yE@`y>O!TPb7d;io8Q^3Ugm0Wn&gefq}Rim1=$aUWBnKvF}kfMWYl)DJVik-UQ4APwk)dL|kh|AYTK>5zC@3)f#)EY;uewj=Be##SFq4nauaiK6xdAbxTg$7=uVi39!!e?Kmnz^U|EQz#^skSwl3XWh^}|?28AkN zl_;FfOnD=yS+1-ET~J4M%EyThQK+HBj&h(~p10(4-C2B%mcwF%jxXI2Z2o8^)oXTb zpW=}V&;gkl>>^qPR z_3De+KD9HTHQRZLwByopr@B!eU#lzA_b)=>w&sc5tRlJzI#FA0$VCJ;pxD5fLdc`^ z0sN%4M75RP1U_CwyI|9=$2Y}Q`iPnJBlrs@8vdM%`79$1xih$!uC>={m=>v4IIrR$ zsILc;QLU)txJ*v^Yl%R(K%|{x^M$#kmH;jWuHf%72!wK!OiajjIE5D#2jd9gD^;;j zcEBE4!$G44XpQ`P+)+KKzExt@BX-8yL<{&ZO>Bu}cg!Uvg8gze$Ppe8qJ*yl2!`98|GIT>xXnp^9w&5m4sh^su_z@iK@;&6B_`=S_u zQC&W4qQMjO}|+Lo5d7mNrl@ zcfw+;9NcOaU{2X$U6Pk9G7?5AE;epnNa^;ZqDb+*CfXtqY@JT|c&K{rA&TeYBDwWL zMo{NRzNE@4$24lp4OB4Pq$ERjmB9=++GH?h^R?xzWp2^QCd@s{NP14?Mpb4UCmO1* z^CvwzSw*}~4pi%1kp|>indU~S-ox}fMlgE}2lGf@a6XULUCZ_R;vy%@ii`?>&3xyaoxPA$lxpxi#IJ2oEsG-LQTEHl>ck?AZ z$PDLlO}B8yDsVB*Y#(7G6`j3Kzz~^-E=MefCBtT@5WJBQhDs+z(BHGLQYM_#Qh%)EkToF|+2MebPqnEQO5Ato2fzm@x&y&Yn8(UIOUCnY$Oc-c)=Tr$W2kHWm zWB05K3x|*jOs!+|VGG8-Hg@LK+}6*%hef(4-dEXysc^K}cR(A5WsyS)izUa}_0{-B zsAJ-Cz|ZX*ciL%c$G9&C#piR+PAyDw^tB7eyS+UfA}-(68xX#R4#j|50p}>BSZ|XXh zyX{7O2^tiNON@zdkA%fbnSZpFj`;c2VPUa(h`fu0f>@%dN1P$sh$kxLKS5^EH+Q?d zERAV(1Ls&rd64r<@aA8PX zcyqFsOv+@`U*2+#BaGmDI-gI0F^o7p65=A-1--VD&)>XxBYG7pDeFHwXcy|@_ABfa zf)ypX!)6{QWzqR)T+loS#J}VVcaUz9{HYu$T#5)gkR&Qwj{9Y-=rGr@Fh#p;EK@e5 z;SQ@|)wH{FN}=(uNxmkp=6zFY>%?ZVRh z++APfTDvj3B(7iGI5SKSY1X^_0F_;J~ zEwBzJMNqrOfMKA8c3V(6hwBTErQFs8FsauC_-;}F{9+_ zT}#9_$VGFqdpy3XQ3SgbI*oe?vfp+tP1KG}0Olw~_c~I;1@8E0ZY0wGqEBlaf&uH@ zU8cEQL0`e=1Sa$8qG%T{SH~w%bme7NP)i6{J+LOpJ}k6MZpSplyf3yJNoE zty%{?^vWyZ$;hwe{V_RpxRZ&*c3oPGQjLQv;J~GwBiN=;16RvV--}q*>ewcVtm3kg z_9iO(2+8Y%5mZ?s=GxpCI|gOA zVHG0rBMi;tFOwL5WA13vt#qs^26VIBCKS^<=7Ca)<;$^Cl#5AsAs?kY6Q&%~NQ$$) z_?p+IBg?*5O3L#TJW~r4Wz~v6iWw<>$HvZ0^eFjm?~Ozg2EB>AVHchpe8%O;!OJgW zom5kD<50>(mO03hljw%?4CR+{9a2YG@?1Ga^1?e=D*wW$8L?LQjb1X$U+G`UR{NaJ zV#^lD#13WD#lUP^NsC@MR$t#-U+}i@o=%}IT?suWLf9LK=i+sPWc$MoVzMmlwkw*d z9jVcq)3apY^B%9+-Nl-SkRHhDZQ8uRS$l4Q(+s3zoToI7R<}9}SnhjFxk+FGR~Z{x z+0Rec8;yFWw%kGm)gx%Dw+3D0@=cw&a8TfZ>4p8{5+jQahfU%YY#dr|w6H1S{}PNv zAFQ#G`4J>P7M@mgWUb_Fqs-Mbr6u{QGayO&mD#T2ksPvy~Q>@U}_v?`5U+* zNkJ(SVh73(NMNY`AxCj*u2x)+t~kt^ z#yvq&o~?LC1&gD5D$~eDiwh_hDrq-v)cLy4$l>H+nRp;j|$fIO%G@fd#xo z=+EC52}TOuIE8()2w!ab)H7RtA7ZZ7UKg0SSaXr&mHS_dIckV^${yglTUY4l*%G_j z*h}EMB7k}x>?QMonu`&0`T}itM$lV`Illc1@Hi`{j?$WlmSfS*A+Yqu!w0u0Y(tN*k2Cl>sQCN)y0GqJ!Ur9Q}SBZ7BRykxIJQ>7+ z9T8>XQkdGU#(l&p&Swhl8Y}Id_lV{S1Q)+3wG{!7S`VG|5?KYa{Q*K-Wq{OH=@ri^ z+sSd2?F6@hWL5wgjr9s>({dOR)$^5@nO8F0*rRBEHt&O>n^v z5&d3ajhi}AEPj!dj;z#OM+pF4@M<9ooV&z^y>p|w!=FVt250g z2+eo5g}_rY%VO|5hc>$_+~QDWHt!zadeN+klD$`!t}-`vrG?7;?Che0?3SQUZ&cZ~yK@WkG{KC<(Iy(%@`PmI@>X^@ z!%bXsk0Rr#cI>8?$zAG-Et+2WIuN;Tq3R?6=vWZR>slPk0QdPo4tNeT} zdT{2+%=Mhq1PJkuYN+mZv%QGI%R3xY#30+No#<(msQpl$8j^jt>cwU~+ zW$?Z%1uQS?5rbPOYEsT99?h)cGmAc+boq}awN#oC-;%~fsS#ljLR>>vx=Mk>SZNt5s|D_13x^4EHiqTlzLWwc62t|IkCc`NNtZcv^ z=}fe09RcpG9;pT8v0%z10s~VR`0gkKD;1foEFyMNqP^>gSf?>2Wvw+aLZMRv)~E?U z6vhH2y>*B!s!21Ij#reZjFjZ>=F>I;>=O^TaxXW6O|`I^F&JmVvK5wEl$*jj;32gp zf*OL@JjY=nmQ!cZO5w3FIvN!MXENJ<*qKnn`Eg>3yTofWY2qxki;Vy?DTbnf7b~bLV1xaZoG2=YcC$LCc+Enj8s6D`#^ip|0M83X>8XCzDwhD=6 z;7W2XJ*1cfjn}F!BBE{*j;&S>i8N1ES5(oO4Mz`RZMoSI;|5pnq(cA0M*Vs(3!13S z>3MIUSXq+Yk?RaM$X*3RZ)`xDZ7D@fOjv!7$?06Z+t`}GU8{51x*`g|Dn{Lr!Ny3h zb;bz2_Oqb%jHwLJG{^R$h##0fviT4y47f~A=~nfo-$`H*VmG@IK}04Gq6ior^ZF=z zfi+fy98=z`gM!2@a!izVvAspnDu>yIA)JP>*`rvWmoOD^>%ZOm>`{(QJBR8h90zo$ zPvtUcs})k5+y9qDd67PQq{F-?dK&75g`g*r;ZdQb(?vM+N<5D?IM(@3gF)gXlJtn2 z&P$$wq`wQhLIIGwIfm20$p^xpxjP&ccHFbw@u>suU33c`sUIK zrq4#hDzk+ z%a(k5is3bsVSGs@3xYIh?81;CxbF=~_Hrf?gyvPb!AmvbG4e@^U2C-w5|wjW9kax} zIVq0CCC?c-4OAgGlrM)v_gOA+6`cJlWT4*{@r#$=nU0LhS4UddcQBza8Phiw$Yy7i zJ)icM%Ym(-G|%P3TMo}*m70CVglHBCEs;km+o_6~9FnbUDJ^ptta{p!CDzX^F){Yf zQrf5(L_q@;q&9u<0M|o?!Lt+~hF8$~z7blSo zy`2y`pxDlWZr77mWq!QkPC~Uq<7e_+*9PfbaBLSQiUrLJ zh_69hex>U6{l42Ou#|xoLY4Jx&Os|R*DICv&WieND-=*Sv*x^2z7yS!*f&sXIjD*r zR_r(r?dvq3UvGzP-&vv(5p30shz5{dfY=M^gr(n`o>i?9L%S7Zm~m|mq_ z#du5g|FTZ%eTPa%m#y&Wtciwov$SPTtF_`ksRcYtfiW~z?n_%9Oh0>&qKz!8A+i|J zig-e_2p_H<9%_rVA1@gNMMiw>gBhwCP*VjzC8!)&F!wYt z&2hOc#UDwL2`^VX2SqZN!Un?E3&g>36<3mx-Dlu3{w#4@jP1*i7^|ZwWmtP7PyE7K zB1>|k%uD^>wX}7|^|WVFL<@ zGw;iEKxTAEkS}Z}hs@5A`(Zbed0Q4I9Bmf$7FP03C1bUhNHxS&lW=ubC+BXcv{uwq z&7Eqy=_li_&Ts95MXfFeX?%V|&soI648DhI?})HIn|Lyt$<)y1=f+J<7ddO?OBRR4 zZCz+V0=etG02TsV(Buk8)e5q3iEygxietB;igRBxU10o2JEni+-%SLXG*^ zaqxe<>(%V`a)6x{vr4`w=%d|vr9lZ45# z-8oq~YA${o8_u-$s9UyLZS{06UIL_Zk4~|##%8X;H6=413uXntM2eNGuu9mV%dDK8{OzziK6V2WSUA|gi`dSa3rcr zWdUN>iSpww`RME*n5HbEan9!4e2lhh2cSzenDU$C=r-Yqw{Vj4dg~k-rlr_w?lmu* z#w%Y&7+mB6t+YY9K+1NA(scrM#~l7uyElT%qj8s2o?P*4t83h$q|%6&wwZF$Ty(nN zaQh>qCotizb ztN?JICjGNeUt{wx(h@s$|IuAc4NPm|N!*T)i!iBw51M4?Se^=BGKu~9oD+D%`<_~N z?|k47=!CG)XdRWo_9!YL@h*p+ovthwxfttll2{4?H%LT$0#_Ta6Np=_d?8cGVb3Nu zH_TEwtWYZ}gNE-Az^L?;OEis~uJe^2+XsXKpTEiXdHkEo!plpA*Q#r=u@nC$*8Sz? zm1D_rQK;5NE-xQ~l_q>DRH`e);&V*)%Ll!=jW^C|`o8&6GPiGRiVq8lsfd0#(tm_< zc7Al8n|h0-aYdUi@tsNx&_}u7myAyFwYkxm*~xG$Z*T6Ce|&^v@U$YJ zaE^|#3@K*Yr7Cx| zs;qHw#S6)cNelINI@taLf$}Q)G#ovv8IM$=prx0wLnF)_r7!JJ$&A$O=A>Jfdiq%? zSyBmp;j5y+dr3tf$X)LVk1kB==w!Qat6ZyXaZ*BNHu8I z;^Qn5VnZepBu$dl-#TBYrU!0^ecMJzb4*Hb$AS?hk(mSPCOH4BAvKe#x-!{;h?j4@ z+g0IXFb(06I(T9ag{Wg+NEFKqJ$Q^t@F2~PFGGqEAxEDl z(a@~a+pe_=n#Y)}%{L&xEXKy^;#6jk=F;YwvHWsNjR9faz#n*ydxcICm+YR3rK6$t z__a7M1OZEOe@VtBga8dqPq%mzg>luJW}y}m`;NLZr$xwe)e(8CP#f*3@~Sc;(jd8V zxT3(Qp<%X2%iPSNcTGp_RMqZiP4?PBfKje(Si%~ntL?*ivNd?TKx%qGrsrvj-^&+g zFyA;*Q?XbE&(6@*=+V{XTgDqZ~1ILAz$-=kP)yTS0I>eLdBjy<8qWEl^e>^P&A zVT_TJlvrl;_xN_bEhCZly}Y@s%-^K%Q1`ahZf%+YLY}68?`6Xd8AZJiy6NaceF-M+ zd7o-PMvk0>1NE$q;!MpfQC)}%b2Oq>b`bE41G?@JJnxTHz>tcxH>qk^W; ztYj^6VN)C$al6;GY*alcVutVDJuOuZnN7Wa_Z{K8L65CeqL3T^D9|~b*u;gWdugsz z+pHJ(^tMh>3CT94lnStj$(y=)GU@!#ZkN#wmT|#cXDWoN$PYqK)LErEltgT zt41iqE4+N-j_!r@bW$l&7Y({s{RKmza>BGCCYDqrJZsB!^X#P}6N&trECsM@7HpNS zqen^Uv0|mXhl$aQaTN4I93jf36eq!p4=uApmKa#J{FA}qsM_G#)V5v1aP3o&Lz>_y zvFS2rfmo4OhqmDFE1KSfwHC@Z7Zg&uih3M(Np-|F!|uvxFUXfwxvPzU;-ARc%qGS? zgl=RYxcY>WL{xyREPUKk_mA2?#LIu#PYP3TXGD-8FH*D;A2;UMN7;6zJhOjvsytzC z5Jndl=gVXJ7GYfKB0>EpjE#<8xo@trP?{c{SuBs^t-&QRc2yz$KDd8=5+v?iY_?Se%T-&l{P3Q&&w|jC#AU1g}(s@-pK-wn9;TVirguIF-Eq_x3!9;qZ z3SD(N)ipAA?G5~>GXPXNc0kPtEi2pVMb&{!C1yYtzOe^{lm({%@Gm(Rl7kBI%tocQ zk91k7YTrG}qUt(xY|C-5=)_$5MqDV#V(fZT0Q94nQkPp%u>v2I8#S^^h(Z{2p}kCt zP5)f0j^0Ro@|jyiF|L=*CC3vCn^u$5{?gMlex&!#3xzB17LT*Ze3kR|@@&{kJ#;J? ziq9Nl|7F<$!ZoGWHkY)U)d`MiqJ_+9wM>jMGBr%RBe&&5d%Z1oXsu|AX{}BJO`@Kp z{MgIkdH)D_lJXX5Azmj#sUnV;1OIKFSbym%Gz#N_P!^ys3fk0(aQrdE~ zCC^U=MIhNkLQ;4x9VBP`%K5khlFW{Q4o z$<-yi=M@T|s8&X`+TId4B?MJpgkz20*J-*7$&Lj_06i9o-eskXUj1PgH|atiCd~R( z!nxT&I)-#C>Up#K=4bFhID;R=(ecId{@#d*(o_l2T)Z95&+eHQS3H(dS0zbi?h_3- zH@dht@~LP*^Wek5$V?gHHkhxHle3G!iTS)9Yyj{JXug4b(Nd~V{8cWqg}tNm<(WN| z{pHyyn~Rp8RLn#z7*>^y+sYIHRD{xZy^tn*3duGJZxkt69TF3F z#dF&ZzkS$6wfyrX$+A>JXUuZ2QVyU(ePmIIY9p_CU2M%Wxy^XCa)VGi$x>dVauz?k zD*S=##Kb6j&{l*uLCohv8CRVq*r1LZI6-g(yxZtH?=3>h!BS6Fv z@rv6GOyl-29F|EVdR8#G=q1|k0Wo~POU)Um3?7WECW+Zu=*s2SMmA}ZT*k^3>R)G9 zS3BH+q-CK|g9@S}BwqSi{=?0LL*mBIKMIp`S+o3iq$HQMe|52P4P8B(y6Euk;zQQr z0o4e>Oaz1Y<9rVrJ}Dy3CcWVH;1=Oy)(GC1enz7PQ~mMeLcqH&>ypc?GTC6&K? zfKbccM{aa>AS~q2zLJ3z`dg5qA1W8NzfBX`MO@{?4wtSV zO@mm&8YB=l-GZRwNSE{j$w@{2DKzSlWG*=f|4?ff^TX*ScC~Jid+Mfma8+UpB>wlf z^el&O>|GbdD+=0fztQ)#P-^PUHplaXv7Jw>{uT_X<|?Hb?@?vJXuDnAQgx6{A8DMY zvmmXRo2vm}!M2g?T?8sk5me=}FKadhGd1yo{ zuDq|aFv)-Rm(p-oM+Fh3HxpzcaA~Tzlo#tc+vRI^&QGc*Yn!IFEzstf0z$|<0!o`B z4@asI^!tPkasFBGEScr6d{hyZu7*Y3!m=HX( z2416@N7j1hEY+zI-C2Jh+-CEL)+Kr#5hg^NCgc;Ag`E6Nd#bd6m24N1j2ykX(w>Jx zM~;u2&k8o)tz#}Ka^K}3kpnLWDK&pp+EU(R0cMPe!N}jUBNp~z&xxvvyrENlubE?o85Jgvv3N_1o zihKreV?$RhA4R8!UnMjETtnywlOI!>wBoZ&*K=mTEoZ14pc zt{cgINv^~e2C^`=Qqdeivk~2d=+^w`V#I8{Ejp_;W_EBhQLICRHL-*!8h_SLit!>I zkDAcGSJt;WxU#TXw%QR`JY0BiJmTCi*&h~Jl9 zVp@YB1_C|55QLDi-l~w(5S3bFrise8NS;0+W%k7hEFx%cOD*}2$RJ=$i9$K28@kb$ zNtCI7gy%2mz$sB9tjZvYHIO}cfN@zEkNfO^Om->HwxG&rsFhc?_SLxDQ5_qsi4SzZ zs6$t9FvHzZ<>YhKdK*vYy&YjC$4F9k9~z}Qn>^9UX@(-%_U2|Q$0#=ua0}iWNgkti z&zq!_r~-CaS=5ly`f*?l${mu}^$npcUj=~jYDLMV1iNJLSbk+uN*axX(58PXy-rCSpU79Brk5OS0% zzCyG-kvBab(+)A7jdDnwpV*~*{mLW#BkQl_#5oKnb)6`4Q_WDke)CSn<{pq%K~EqV z8Fl()wf3cJ8qo*Yx~3*2%3eLXWT00~IC68G*GGwfwoO#U-O}$(B4!wc?70=~%C>_; z=_%)mCNwK_VWCT;7EyQfwA<}?T$`m4qCE;(dVrX@%4Y%HL@n5V3Xb!&qvI;?6zW)t zH!u;XXRWOC@;Wi5>LYm+t$G{#DC_h*wUN9VR%N!--&tKsI-8(Hm^4YavQvub`IPyC z+|$p`!VEJaw=IRc&a+Pr8O2t}mH{~(5UPx-okuve0)_};A+y}qe3)9H(+a&TFQJEF zSFt^8+_QPV_+E{A^dY*?^-A7VynZtt+N=XIYrw3m}^;bl=Fe(xS63uH%JXz|4lqan^e)We3K zS(;XTC%9T_1_~%9aAKhp6|*dz_kDmpP?TK%Tk!+pBnB2RvFgLy2a<%?Am$X2!=>AD zSHdJg6TmzeuZ>W7NKY1%ksw!#KM7?Cx_i?V(&FHQ_TXeAp-}^{l7z)>KtUr2;Dahq zC?1qhg}wshwz+809;y_-X>iv|q{hr6yAj7%;FO9nw9acT8HY1381Dq$j&b7SVW{pkFJ`W4_gdmiOc)Nu`A@m(_`wkJ zMvMIDmQ@xd-Nr$|dO4NO$=3%5vwdDzbaPD3|O@iJMNXQHY3B_!}WolF!A%M8oMeN@3Sl$S6QV zij`s;eU3T|3>(@i4~n*bzU@A$P=*KkBG^4eHviF9RtZdv7ZUMNI^g0G^f9Ep zGT(5Sl{>Sm%Av@g{hD9Y=UN+^a&OB6IBW2$5j*<8fc+Zj(cE}@{@fScasC)xUXi>a zV}shrNH#CZFIC$n=s`fel&c~JC+drj7L>jU_f-i%Z;|~ORyz8Hub|km*IZpBWYMEp zVoox{a}@2#pyTO_Wk?O?%h3J{-xWhFQh6(v)_SwwK5NT2Ry9$WoSmD)PUYKPQv)t~ z0JeFuxvd<Gm>k%2)^ddIM1T3t7JVOIsY^`jCrW0g zF3wGWYhs+nt{N*~?I&5pY)8=1>PaG{UI#>(t;}qdhs+s{0GLzxOQj|si?gRLRrias{~$5n#WOu z$by=J!u=eVrP6VT9_SpO*{F98?VFzx2{~MwbjPJ~jZ|w(T)!})YLkJ*f!!>e3oNd^C9iKPC+h0ywtzeIo73t5ZaG zy&{3)p!;(95%uytQ6QoAyM z9#~$jK&yRqk|d$TeA}W$``(Md<&OAv=j!_UhIz&H{V{;Hl-^~}32{bQ0A_uqU;F9; zOqm}No$#(utwO)&!zbQ$_>`=UvwVddTTmQc=Bb3_G4GK<^EA}KutRur4>+;U9e5>2 zD4Y(glCx2s)!V6JSqg+DY{^u1=W~uC!n@Qum*Y$*Rs{~tj5Chw7xRdG^dkN*-6p0I zeSMc(R7maZ#7{r>!Ge@Sl-G{7(PLoUrBc-jwyJ#aR88jXY*PBDDI3-p*@4XacO2o) zGs({czj%I?QO;9WrF*AdC`>u8O@SQf+|Y6HETg@QmD^F+%b3 zH12IBYzDNh$I}!gYker1eC&(BD3bUB9*as&ZnLYZ&sk%_Kv=2`B6(md0-s)3c>Yur z>6wVe$&r?iTWr~mXEHm-iTSANms(H^) z`kE7|C)@tU*tJ-fQILtel0gU~3vSki)jDZ6&K%QVVDRj3N6Fgh=GJ&i* zULNqz1z8}=>cn{=NbP_8*yk@+1K z7q}fBOg52)5xN4Dp0)btWNNI(w%d+vnq=cZ?kp?sx4b`Orq8x5gMl3;2-`-;_amBv zV|9)eKBTNIP#a&a70#hcuCD0?7!t&>&xv{r?uK0`I(ab z|0va$SdrsEVQLBP#g`9nx@X6-Eu!u=9z{mXe$gd0s#y_H(aE_oMuVwHVitXo@-mi} zDz8$a4uhDX2$^XW)-pHcB$1QW zkZANwSJ-r@foSyoIieFVkV44EB~oGxJRa|JK{hC&NVS={A}CIb#c3sCKz4d)E}bt5 zC^@0EmhvGXYD~kNk8Jc&?t-PnGv?X}Wa%FJ`iCgrUwWV~Yo1@peKR5)$qp2$$i$eo zK|kWHUwgNsH++0$c_|S-2Xf$kl{g{FGYjxVkNje&o7n$AK>&^*%MWB}x6k zr)Ug%y8uH*tBO}QXhvGo4$`y%ny%RFnTe? zNUpaGpRFg!LGfXHB@6OaU)7=Xl6{F_`|N#fJXvzNLx)RiR~R$j*1?vSd2BS%6xH{O z)hUYgt&_@4yDh6CX)@Pu(kPj?LT>$af*^ckxhW$u%Xc)QU8;+ZHY?06Fr0v(+aJ$D zn=%2`Ak5xgmTjtzHUhnITSaxtR3M)Go8)}g-P3lU;bOUkGPfBs!NCt6Y%d)D&;_87vd?RnKNrF-D~al84tncfO1 zvrf9Hu4Nh2&owdncd^o0`TCkOqi`HAM5;B@O?>{OJ6k4+RMVG*Dn#U#p4Z;K(Im=9 zbfW90>O`Tf6_xBv67SdbY3AETYDHRT&RGQg3{!@wRT>l_DS9gxQVfjHGRDMyOV#k! z+UVWled#Vbyh^Ngploez)+tIa%<7d38H(h|S1TwOW-n3+`)yf_fk-7 zCF3}4Wo0QRCbwzvvq$w5)>pkT*5t}+e|tIk3G>M)0lf*|ts5}YJZc~VDicVRBUwL; zfjV=p!94f1>>cpVQ*xOs$lboH0xt7mrxy#AIkxwE&6(SoN zXfEN+BEz83bcJ}~Px7{{g6tRMO|4e-sifal#%qp~n-nP5sE>O6ze2oazf*AAbi(8W z-$h1evLsa7wcH#;CySXT$YW%nlvwF~B^OKGu0&T)xPwZ%(Diy%4n90Ud!~%4b`7t` zZr>GMBycgZ#c~c>qewbVFWK2=7+@pVzF6PF5ugg4DCO0eT1{@yIG8V_7akQ6qU@?c zIGs?{AX1W9d+DW7JAV*wPQF3LBSc7s4KM>Kw#y>tPAUYGS~{e1$8XEU1F=`XDKQtL zoO54a22){FoeEWZf>; zJC}PkWt@_>6tm)%jruta`G}wrXVPCInfGy?y*25ng}a=G;H;mjVRMU`g$ol{pPF~N zc~lRy)@~G{u?flpZIf^sKR@J_5MR~}>GjJ+A+mc29W=M#q6B`j%LNs0-{A}$a$8m+ zRJUik`SOa~JI{?FWb(KoQ2aI6kQN|?7jeBn=L9pI{c`!=S$B)>(Y*O+v*eXY&oyE4 z*V(0DG(UWf8`kHS8)sLfPM!2{)!4!Syr_TynGZ-{1EZPF@oi&lQN;PMoI244#zDT6 zK?TJzpERN$X8_2Vp$Rc^lD;@KJ z#!?u!qk1TnD zlfT(mjIPlsqLj@e>=O|MTm!*88D@8vBX;PDH&7!tE7_m1SpBU2q}|*QVlJY{&TzA1 zGeKNfe8QF?>x&fqs}jK5V=E-<7vw|z-fozU2rKf{GMBFkf?}7X0!L6zufY+Dh|*=b zT#gB?zh>u8>RpE6+iELZ^X-X4e=a7v{ctJHq>!l6u30W$85W}i95m$%w`v`^c` zSR=(ju%2uTG0JAXCjO^fHw4!W{^K2v3LqiXBa1D#^@ntxEmZxNP-Tok3!8}O`vgJO zWc$|67Pd8t! zjS;8YWLA!?H^Py$h}(IT)Lj%qD(?B^RYuL^Di5(On0PH_LmWgyk^6OJ(KGKpK{7;3 ze(t2Roo|nAOn){fh#y> zA=>tE_9+kh+@Gf+G2}7%EwEG&prud?d~KTQG=pdnN^6#?Ws+G(@6DX z;85T}jb*)}qv9UU6P;Lys0T`J{w?{%J>-VZ+8OJZn8gWBV)Oz9L$3CxFxm2|8)2d+ z#g?sx?Uyf1DbBZ0Ho|$fBI2x|_i^O;u6(IC|`I2PB(Kd<+j``pS~k9U($z z7e$DyqnFMkKiGk*MyOA*E|I4iE71w_F@_&=MHrBSlw`yjadQFMZWCWB>nf)Ti0)7>B+uo} zrMtT=1Ut=Oz)X>aWzY-~{N9hM3AO7=G%!L^IOlnS=)4e#Nta*0%pqBSq_10W>JFUN} zePhtm|Gw`-zYpr$f!()l*GUeclG0VK`lv?Z7wtshFR&L+O@^XervMdPV>~hsi`awU zf^U`f>{N;_LIkI9MU7QwOG|fuvk+!puRe|`V;dt z{~CIzzv+XTS8PaJXG*X2p5Jg1i(8c|A#rLa-ei61+qD8?|G@~;aTlTb->gpO1XbR*;9D7?j%Z{yI`$ib)WdgeIC zDfS&zb|5`~-T7`@qwL~@TqrE0+Ji>t5I*5I!~-qIt4M#aLFHt9IjZx5D7Co%?;Jwm z$Y!BGZZK3*@OdBo)kAwl8^=#Oj;v=&2k^j+d+oUj4vNR;ubNw|$d_*xooj6=n+iu& zaPpSl6?hkaQN8d#^S^0(x8^pIByBT)%y&CwEmd`Ow^?nQNg}1t~ZC~>9O4r?lNWw<#~LccW033zr-ihE+8suudejYe(;Li6D?IvKxosk>Qx7nQc7fc5ZRJ$dzD0={Wcjdb!kYO z5F+%m=(dUuBrOGV%9QN}(fl7qx-*|y92atZ;tBCVFah$A5_-?jrW}7FbQ%;2=}8BHDe)%K zxJbV0CeqD@R;-GugjcQCD1y*td2-A`|54`1f`Qeiw8K>5?X$CYZ;#I%JM7XzUpYrE^Z(*{i9l}! z^V>e4MG|PdL6AsRnFO%qfMKud5&~Ilm9pLjp{> z@YEnm0l8tYn0+u)$^AYWGAbx%I)%6)89Pq3l%Nx2vox8ar&(dno0VHy|4YwdV2 zPB$FLCfl_y5BF81#a|Gr6a3x5eVuf))U)Gtiee>giTYKiX-jCSjGEdCH7Sz&;0tx6 zl&St&;Ei3JNT-x}-dr{nBhZwDthZEUt(33Kj$wtm-$Iay@q*@H)??Gom*{|IAxiBQ z*O4WrljZLLH6}-YV*r{VmXs5{djzg*<~$E!seOO#v#O!=)H0ei>KCW0Rs|>6Tn=1P z`*rAIKk}!0@#=)PpcFK=l0uk@EtFqtMn?K?ytqfex#gW*%m&vYTXvyqb4e_6Y^;Uh zd``4@X#C6bcWxjzw+i(=&XvH#VX~uhcS0!_4?A%4(LTxFK^A=V$bBFDw6l-wsxpk} z<@UkZvv()Oq8HzBmcwc~YZF;isHygKP z|LvZ*1HHf%m4#Ci*u+el!=0A;o=A{=O2BA5JrH(mk1CAzXs@^Jo2RXdAI|SRy z$xm!hRb(zXiXXeT7mvJd^GiZ~;5Xmf9@gC-^kTXPhgu)B%uMG?)$IsGQFMAJ7Dmb@ z>ZUFoWpEySr%JFWy0Ij@k(;c&7hw|-n;rqz6)a)U%ou|Pqe(1BM#*6neCxf+A8N8C z+J%RGCp$kEE#A$(3O%e^E-_*V1M5m?VM{>-#X$?bjH-j$IDvAxB0?8<&rL$cge;R+ zH6m9y*9k~uemtNs@M>SzRK}B{XKtotM(Iwx!A;(L!UCIu0A#~iUP&8nZc zg^N)&7qAF+G)N;A;Cr)($DG5H4g_l-E9^;)eeuLd_M2KuryIO&akj?SA+Ao~UW;Qb zejUIq*SxfN)!@_sc^+CG#Q}?j(7IH*4f&Qay~xUSI1VlMqd>mGRnfxx#8EeyrBd&C zrdrNbY?$e`9|VXI^gZtt^UCrY18rZ*6!*yjEy)~|7N*%cK28-Z%a4*Bp04S!tBl2? z+hvGy$5tt+8RN8mGpZwv(kLU5RIrNQde2g%#(0eC?9&OfWE}FRTEH?Ycx%q}V)=lPU0ngLj z*5KN&dN-@F;f}Wb(1-zcqA0oD*(If%9!eRWI?~NaV{8{Y`bm#l9H!>3t+JMMD5AJy5ir{aEcRWn>$|6(?(y-zAtU!aEf%O(~w>6yN|(u2~kl2Qs<|B0d-rY5%mN-3g@ z>C|VRX3Leh*KzhMB$Rs;?~49klon7V6bG`hwY;9E`?~OO>?dg#r~qvY;;O0t;%B)k zAdfTn>rhm{12F1cA+wYX;`SaTn^jP{T2cnfrw+H&+wO4Z$owoez9pNnW9^#BaU9BI zT?V{t0LLj-6u6zb*GC;DWz~pDO;&rjG+9s%%~X>%+itTd%K+&cV0SqxC7lw_3amqEyV=x#DrBi8<4Tt(^iJG#mBF3I$IzupC)cIw!RTINB>x=a}8?w7k z@qyJ#uZ3~X!Tp8bDB|u$=Mu}WJ5n$1cY9E!IH$*=*lmZ%8?9JbpMGshuQXv|##xiW zdi2xZPJKP?IpsOsS_T_iAtf+A(ev!-EIlW}#Btg0v^u4(0j{SX`mlbfbW$HHKfS`e zgllvE?Oav=9YHoqf-aBw4gQh@BN0&Wl;#&h^k3A&bSQ9`0?XhbKCkzh5J;CfB)b!j z1@s)%M@kk{U`*J6xFhm@uc#Qbvb#R45QN{ z8m3CvCbkRB=NlFt%A^PFbw>9!YhuAYsR4BfRxa3K#45tH&*&-MAMQx!yk#|7sciE2 zO(Hm(f5j!KFQop6ZS`Ak`f3OzJ0e*_x@WzAHcqm6bo>#uuRc|w6!S$h*89nzeMn@i z&bNzM?dNnsD7|J`QI@?}VW9-Eg}H&VyF6m1w|wQ21Iv+^4car{`I= znYAT}WL-s|c0mJ%)80>1e}+|iPMvD$XO zRQP~_V|iJ=tq1dYeETNl{;W1go#ynSPH~EnDHpT84*hN_Fzxl-qQKtUeUJQv@>f5b zf^Dm9iww#m<^@jC2!R3J3L`fh^JZa7i#;*MG^0y(`J1Z!z5Aw2s1mWw}oI6QtCHrubb#J&5v#6awd?%J0gL;*Z#t<7{7w}~AF#5@!e1qwZ?M?v z$k({eH@_{`t{e>ZDA&bqgWFp;pA{C%!>`!v6&Bp}0JrL3n>Gbz>Zh_ZbPw6MZu)l3 ztuR8Ol+ouack=#!j&l|9z8%>ZpWdWXy4J1#j6I`7r!a-cA`@mq%B`xl$#U!%cR`W8 zqN&`Ei?yD#x7MR5`paS0M_sDAGj5wz>$UZH?b!uRc`^9z|Nd$Jn`<;j&&|+V)FAO) z6eSZuACI2f0Y)e|bL60k3R*u)WjJwq9KxTMC?&aj!7VYa<{^eDT$3xh{C|2GF+XB{ zz(g$)nqtuq{=Eiirk;83e!(m~BkrYxj4D#p;^Xe^#;;G%yk50=+sB0V-j9mKJdDyY zb-X*FmbC3~xd0+6IP--v$V`jDi>;zeY{3~hqOj(mR&5sXPQ`1U;`OzjJuX7E-a_zND5s_%m1Q|uvOog1)C6z72caE$ttOcXBB90JnF8wj+oQp#@HYYl?l^{X{To? zelWw(D2gCfQt4C~JHG;Im*=xIoh}E4+S5NupVUFAX2Y0gSQ(zPeN;lNh~YwsN~jcW z0IWBdEh2=1tJM7=OpSzdx2pGIrUR^$$4hLwaNU>C40>fgcYadW<~JShV4e@FXmRp< zc73(S6j0Ty_Xf|;vRuPd)>GOL zn>4yB7z`(3PY_D$AzG1oHJe;NpQLsn;GrI4eStR$qOl1Z1IURq6NVKB80r zw3xd(!mQSuV`2kce^l{~jm{)C^>XjU1I6|pK1yo< zxyk@_rrK;j(XaFg&a9eLW}8XqXg?|#>HsO>gw&p^16>2hzz0d7(GDOhOjt~tEt3_c zBjvo7e;3LrXvHNSx=?Pp>)J^YVX{hib$2|1;a87LlV#MEhlgQnK3)8mAT622!* z7o@%e7#XOi@LsTC2chwsSMaztp%S0zu%5Cj>)xyRdy4k!&Ft>P`MtWRFvbU8(;}s+ z8+nL2)X-#TP-a~$L@8M|oe3VQag^l-H)zUqNkbvEEu`t9*L9D_y{&p41o%MHHi4bA zXl&+;`}B6hWT(1|2iQHzO{l+kxl0(Rk)omt`PnH3a? zVuU}vEh`ZXdC=b2<%fANbgyQYJl?Rl{m4PUZ#%^CjEg|1>=~TkkVczt4{zokdha|U zBfReA*UOdMA39MzB(PGp`KByR7wp|zw7q&bA>`BY>&HK6yUM0hc`@za*C74po8(n; z!v#KT_2Q>IMD^>Eo@xsSha(SpZmxypoj+(b;W=&zIEL;vbtVI=60U24Z!UL&p^&wJsWM8>`jIfCltoc z$;>FIjWcOAiU>D$)@Mb=%C#x(qi$(YV-FMwrDM*7R2_Ty?ChMoYG=nU&QDI?c5j}& z`1yqJ8pqGypPrsSd-v|=)3fv5;%D=7amD>!Vt}bUhIhI@W?#!|EVJ&3 zcfQyW2@F95Bq!XM)xhj>~bN6+w=T!Ia7P~jgH8CUv(&Eg%JKr$(PW#N_ zs*~)Ry&^+}7$8x={H+UK3y;1DK~t)r?b?JuiCz;)r9ism`oiCdkW1sF)76sbP@Z>& ziZKWiU!|ZmO^Tn3jLlt=)w>e)u@AhrwFA#=9DsFK2>y>u&vWSV2 zT^Wn>2zb=;Ko|I;*qg~V5SN>%e@fNWwFCrZt{_V$Nhm;ob4tD%m7%`0nPWp;fYuXE z0gWE@qBIl{_FC(_$N+tGqx^kFJ(Z$V1tQ%dfr#yh}T7 zT7kQ^;&xZadfF*@&5IyrZp9RXZ8ALUt}T(#CQx^=zfllBkq+V+=-o$Y%IRwolZ(r{ z)d}mPz)lt=?`~zBx~<>E)k-R6r~V;^HrIdXlbCg*Tj|4bgo0dtH14P)1>YxBQr0Wi z3hVJ7Q|uW-Wv1L@u@~88fYt@s#udDgHuQj`mE@gK8^J?Bd@;jiyI^;?6|o7 z0%Bi&q<2--Rkb~QQyu2ss;asg>tzUDXrv^W1oImUN0&+ zsV4z?w21BnM2K{#|1v?t!z{c|1 zyi`7bribry0u%cLeuZgN{N4QyQ_*ZcaukR>4kP-CcrLp7NhQ6aLzRrus|wU_sjbbv z=fp%I3704b!~l9WLI(%cLJH7GN!iCf`}$2TP?HU@C;uĊM{4Zk|^$@h=efO!u-1DfS@1u3Q|LnU= z*`~XLu8zA|cX7}?vE5~U(j=y1J~3VZQ|TJ26L-ZmV&1?D!4A_3Tp>6Gs-#TSKdi^T zO9|*jOYZVZ&Bbp!Y~r_5QKyVeQh~i+|E7nP9Us<(qYBMT|E&g2)F5F>W(Y z4Z1d-or(Up%~?n5POb^5!aLc%NYbWYTWS4O*u`bzxv=w!urRLe9l{nZgU$8D!kMg` zaLx|Y>&}STDXyn$A(z&vp;Ml*ap*BN+Qmdl3lp+#DUF520r>Ocse(fM#ZZ1u>)$y>aY_>OFR-&Uc{M z`xYl1(Z(uB7)cN>%=s_#+d9ViUS1t&OVlZC8#doDh_W?!aV_TfEU&~lxtvJXR`Qtx z!|b*J1|EET#MAjF=d6~=YR5V|u6n9DRh#qR``tqLh|<_9d(_4P;ejb+CN-|Ea~M^k zu|=}&YxO3`C$u5qy126CjxWHZN6as6F& zBC3(@Oy{4Vt$f@E%~Dn|wPf=rSB9z}wP>sHYEFdss%pR19F0;y{j^6g-!`TF#!-Dt zf@(9xyQ+Ytfw4D0FxmI@`Zp?0n-fyTZ@#4jP7NpP8(gumb7%l_^AW@Ho}L9pQLAoZ zAaiapcWMq3%0wmV93nY8$UMB|*I@IJ(K@TnUtH1F>dhWMt|hLlA;6lENV~mib1(^2 z9WmO$NGAuCqpLFu*%b@i(TuQ&d2Z8VpUAY|9idsmOU1a_4tHinrFFiFMz9Gp<-4*e8?(PX=Y!?ZP+V`FK<>jPy~2m zB%kd+Ed6P!VY*DUh8Z!pU*YzzK>`N8D-4>HAofAU6<^Pay5>m@R_S&M+wPSX=RRw? z5F%MM=>FEsZc&M*v;nwV`Sbi;&K(Ag(T^RA5XX)>=pc0AK(ZBalP@&ejdNnMC(4y1 zD-%u_^S|GR1zhJljGxiX{4G8M)$l&DGMRZOq4G3?hC|ld<<*r%jIdhd@Zn#|TiS&G z9h5g5>n{Etf9C~k+5Me4cBdfNfgLyNREN1}x)M3eB2JnS00g1{4g&MUEeu=v(q29* z7dq_BE32(MISR0*0bv^u1aSrR$=+EqKPlg#q<@aJSRUwoJrr&eRB6Om0#mqwum|tC z10T*Rd`Pp#z@ZeSCA4Yf<%YcS*SC>zir%64fs#6=xN5vfit%Wwds`VpFpo4C2Pp;h zX=cTLUo5uIRv?P6k8uhhnJH6F(}ySLrH}YMNCoemptPIap~5Ba8cat9~J3 zg8CApgi4Agn2z)hRZ6yVyq^0CWrKZ%XG|2)3;ZsMzk67^_h6n=w?T=Pm{hIw%T{W4 zGwMW!A-fCk2r72D`q>H$nd=Fc5N^F)TcBO%*RkxzmO{T>eB=((g0KaSSJ+?N{aLgp zei{SgvAmSJAmG?n4;5i&q{lTe3Dsi2UF^4uONjI+UR>PEHe^7CfF120w}htsmbjy; z&_^`AW-zeH#3^QLoDlMYKu32s1>3svE8fbqSD|u273u>w%QBa{Jtx6$7%qgURccpt z!Jn5+qT!xF+B>jLE|(RxNy6l|(@`@G$tk;Khn5u!DER;7-Zu@FNba#F^DD*2HI<$>arU2T!V9Z7ibB4l$Pe1;}NbN{_80tj-8z zQStIBR#LmX5}Fy≪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 UPkHJ7if?0w47=*gcR(loKRk_1d;kCd diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.PlatformInstaller.UI.dll b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/Microsoft.Web.PlatformInstaller.UI.dll deleted file mode 100644 index 9951693e9a0a132603bc92eb55f807189e071ec3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546620 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 =ZnK#i-d|J7N9Sv${Iu#E=#eBnXS7RRPSvY= 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 koPIyPpJnaOiNgin3mOR$9=iS{{=`0lVBY< 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%0D`5Jh0Hk;&w>BoRy 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ʮ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 z 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
nrH-0QcwC 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

|H;qiFd4Cnd9zSUELg|a7)99sJ=hL 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

P zfA#s-?i-HYdVJMp@4oq8oVwpIy5XzKUaUFO>xQbJZ&t3}{PZ7BJ#^gj;LeoK6Ye{E zdiIDTapsn3=l0(7gi*uByfR@y|5ZniMrbu8`N~6|rXLM^(`Z@x>0gfE`?Fk|HYP2NzwJogrbqYu z_Tn6~?V0;d-1o@?dqP*7Ui!*t~OmqZP&8j{!DnVZ;Rz7;~~Cag6(o3HyH$jGKXAL4>2cV@vwfVyKKsDV+Sv7fB1_b2Yz|PGWqu1Gs9&4L^E}tg1o^cyhknXo-Phb= zV7(r6_i-+ae6(-Ldn=YtKho>zL%)1IK6UaVPxamL&`YU@pX*dPar??~6?fdZ^UI#A zmJfKOV8@0Zf0%jmTW9aAI(^@3SAMd{BrW($nW3oyK8s;!FxX+ znh^1Q^QYN!$FAOeOKrbX`H_YTQc};Re|mFpyPk`KcK_1zrlJ+zoA%sx!()p#-97Bm z$Tt@UFD$z`_@pU#BL7`Y<_G&uW#l&SGn#n`@0Eao6@H&efX=$ z0S{hqGT~g(*B=hMGkeVI`FFp6X~W6qrfod?X7<0%{WScUF4ukEuVdxEUua%F=!@v@ zvg>aiX}ayNbrG?17w*~EBgGM&JJ3hWzgje3XCTw(X|aE_c0B9KG%1;BSU)d3f90 zsdxU`|MlgE%4#FFyUv|`_o0f@&!&y|xV~#@@oS-1PMH%msN4H9rzUr_hTgXKnLpY8 E0j-n8+W-In diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/license.rtf b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/license.rtf deleted file mode 100644 index b703f2258fc..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/PhpOnAzure.Web/resources/WebPICmdLine/license.rtf +++ /dev/null @@ -1,41 +0,0 @@ -{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\froman\fprq2\fcharset2 Symbol;}} -{\colortbl ;\red0\green0\blue0;\red0\green0\blue255;} -{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}} -{\*\generator Msftedit 5.41.21.2509;}\viewkind4\uc1\pard\nowidctlpar\sb120\sa120\b\f0\fs20 MICROSOFT SOFTWARE LICENSE TERMS\par -\pard\brdrb\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 MICROSOFT WEB PLATFORM INSTALLER 3.0\f1\par -\pard\nowidctlpar\sb120\sa120\b0\f0 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\par -\pard\nowidctlpar\fi-360\li360\sb120\sa120\tx360\f2\'b7\tab\f0 updates,\par -\pard\nowidctlpar\fi-360\li360\sb120\sa120\f2\'b7\tab\f0 supplements,\par -\f2\'b7\tab\f0 Internet-based services, and\par -\f2\'b7\tab\f0 support services\par -\pard\nowidctlpar\sb120\sa120 for this software, unless other terms accompany those items. If so, those terms apply.\par -\b By using the software, you accept these terms. If you do not accept them, do not use the software.\par -\pard\brdrt\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 If you comply with these license terms, you have the rights below.\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\tx360 1.\tab INSTALLATION AND USE RIGHTS. \b0 You may install and use any number of copies of the software on your devices.\f1\par -\pard\s1\fi-357\li357\sb120\sa120\tx360\b\caps\f0 2.\tab\fs19 Third Party Programs\caps0\f1 .\b0\f0\fs20 T\kerning36 his software enables you to obtain software applications from other sources. Those applications are offered and distributed by third parties under their own license terms. Microsoft is not developing, distributing or licensing those applications to you, but instead, as a convenience, enables you to use this software to obtain those applications directly from the application providers. By using the software, you acknowledge and agree that you are obtaining the applications directly from the third party providers and under separate license terms, and that it is your responsibility to locate, understand and comply with those license terms.\fs19 Microsoft grants you no license rights for third-party software or applications that is obtained using this software. \kerning0 \b\f1\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\tx360\f0\fs20 3.\tab INTERNET-BASED SERVICES. \b0 Microsoft provides Internet-based services with the software. It may change or cancel them at any time. \cf1 The software contains product information that is updated by means of a feed online from Microsoft.\cf0\f1\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\b\f0 4.\tab SCOPE OF LICENSE.\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\par -\pard\nowidctlpar\fi-363\li720\sb120\sa120\tx720\f2\'b7\tab\f0 work around any technical limitations in the software;\par -\pard\nowidctlpar\fi-363\li720\sb120\sa120\f2\'b7\tab\f0 reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par -\f2\'b7\tab\f0 make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\par -\f2\'b7\tab\f0 publish the software for others to copy;\par -\f2\'b7\tab\f0 rent, lease or lend the software; or\par -\f2\'b7\tab\f0 transfer the software or this agreement to any third party;\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\tx360\b 5.\tab BACKUP COPY.\b0 You may make one backup copy of the software. You may use it only to reinstall the software.\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\b 6.\tab DOCUMENTATION.\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\par -\b 7.\tab TRANSFER TO ANOTHER DEVICE.\b0 You may uninstall the software and install it on another device for your use. You may not do so to share this license between devices.\par -\b 8.\tab EXPORT RESTRICTIONS.\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\field{\*\fldinst{HYPERLINK "www.microsoft.com/exporting"}}{\fldrslt{\ul\cf2 www.microsoft.com/exporting}}}\f1\fs20 .\ul\par -\ulnone\b\f0 9.\tab SUPPORT SERVICES. \b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\par -\b 10.\tab ENTIRE AGREEMENT.\b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\par -\pard\nowidctlpar\s1\fi-360\li360\sb120\sa120\tx360\b 11.\tab APPLICABLE LAW.\par -\pard\nowidctlpar\s2\fi-363\li720\sb120\sa120\tx720 a.\tab United States.\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\par -\pard\nowidctlpar\s2\fi-363\li720\sb120\sa120\b b.\tab Outside the United States.\b0 If you acquired the software in any other country, the laws of that country apply.\par -\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\tx360\b 12.\tab LEGAL EFFECT.\b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\par -\pard\s1\fi-357\li357\sb120\sa120\tx360\b 13.\tab DISCLAIMER OF WARRANTY. The software is licensed \ldblquote as-is.\rdblquote You bear the risk of using it. Microsoft gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, Microsoft excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement.\par -\pard\s1\fi-357\li357\sb120\sa120 14.\tab LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. You can recover from Microsoft and its suppliers only direct damages up to U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\par -\pard\nowidctlpar\li357\sb120\sa120\b0 This limitation applies to\par -\pard\nowidctlpar\fi-363\li720\sb120\sa120\tx720\f2\'b7\tab\f0 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par -\pard\nowidctlpar\fi-363\li720\sb120\sa120\f2\'b7\tab\f0 claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par -\pard\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages\f1 .\fs19\par -} - \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceConfiguration.cscfg b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceConfiguration.cscfg deleted file mode 100644 index 34efdb28a5a..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceConfiguration.cscfg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceDefinition.csdef b/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceDefinition.csdef deleted file mode 100644 index e03ebfa19bb..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Scaffolders/DefaultScaffolder/resources/ServiceDefinition.csdef +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Service.php b/lib/Zend/Service/WindowsAzure/CommandLine/Service.php deleted file mode 100644 index 1654e69f0ee..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Service.php +++ /dev/null @@ -1,201 +0,0 @@ -" -cert:"mycert.pem" - */ - public function listCommand($subscriptionId, $certificate, $certificatePassphrase) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->listHostedServices(); - - if (count($result) == 0) { - echo 'No data to display.'; - } - foreach ($result as $object) { - $this->_displayObjectInformation($object, array('ServiceName', 'Url')); - } - } - - /** - * Get hosted service account properties. - * - * @command-name GetProperties - * @command-description Get hosted service account properties. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $serviceName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Name Required. The hosted service account name to operate on. - * @command-example Get hosted service account properties for service "phptest": - * @command-example GetProperties -sid:"" -cert:"mycert.pem" - * @command-example --Name:"phptest" - */ - public function getPropertiesCommand($subscriptionId, $certificate, $certificatePassphrase, $serviceName) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getHostedServiceProperties($serviceName); - - $this->_displayObjectInformation($result, array('ServiceName', 'Label', 'AffinityGroup', 'Location')); - } - - /** - * Get hosted service account property. - * - * @command-name GetProperty - * @command-description Get storage account property. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $serviceName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Name Required. The hosted service account name to operate on. - * @command-parameter-for $property Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Property|-prop Required. The property to retrieve for the hosted service account. - * @command-example Get hosted service account property "Url" for service "phptest": - * @command-example GetProperty -sid:"" -cert:"mycert.pem" - * @command-example --Name:"phptest" --Property:Url - */ - public function getPropertyCommand($subscriptionId, $certificate, $certificatePassphrase, $serviceName, $property) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getHostedServiceProperties($serviceName); - - printf("%s\r\n", $result->$property); - } - - /** - * Create hosted service account. - * - * @command-name Create - * @command-description Create hosted service account. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $serviceName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Name Required. The hosted service account name. - * @command-parameter-for $label Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Label Required. A label for the hosted service. - * @command-parameter-for $description Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Description Optional. A description for the hosted service. - * @command-parameter-for $location Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Location Required if AffinityGroup is not specified. The location where the hosted service will be created. - * @command-parameter-for $affinityGroup Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --AffinityGroup Required if Location is not specified. The name of an existing affinity group associated with this subscription. - * @command-parameter-for $waitForOperation Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --WaitFor|-w Optional. Wait for the operation to complete? - * @command-example Create hosted service account in West Europe - * @command-example Create -p:"phpazure" --Name:"phptestsdk2" --Label:"phptestsdk2" --Location:"West Europe" - */ - public function createCommand($subscriptionId, $certificate, $certificatePassphrase, $serviceName, $label, $description, $location, $affinityGroup, $waitForOperation = false) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $client->createHostedService($serviceName, $label, $description, $location, $affinityGroup); - if ($waitForOperation) { - $client->waitForOperation(); - } - echo $client->getLastRequestId(); - } - - /** - * Update hosted service account. - * - * @command-name Update - * @command-description Update hosted service account. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $serviceName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Name Required. The hosted service account name. - * @command-parameter-for $label Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Label Required. A label for the hosted service. - * @command-parameter-for $description Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Description Optional. A description for the hosted service. - * @command-parameter-for $waitForOperation Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --WaitFor|-w Optional. Wait for the operation to complete? - * @command-example Update hosted service - * @command-example Update -p:"phpazure" --Name:"phptestsdk2" --Label:"New label" --Description:"Some description" - */ - public function updateCommand($subscriptionId, $certificate, $certificatePassphrase, $serviceName, $label, $description, $waitForOperation = false) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $client->updateHostedService($serviceName, $label, $description); - if ($waitForOperation) { - $client->waitForOperation(); - } - echo $client->getLastRequestId(); - } - - /** - * Delete hosted service account. - * - * @command-name Delete - * @command-description Delete hosted service account. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $serviceName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Name Required. The hosted service account name. - * @command-parameter-for $waitForOperation Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --WaitFor|-w Optional. Wait for the operation to complete? - * @command-example Delete hosted service - * @command-example Delete -p:"phpazure" --Name:"phptestsdk2" - */ - public function deleteCommand($subscriptionId, $certificate, $certificatePassphrase, $serviceName, $waitForOperation = false) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $client->deleteHostedService($serviceName); - if ($waitForOperation) { - $client->waitForOperation(); - } - echo $client->getLastRequestId(); - } -} - -Zend_Service_Console_Command::bootstrap($_SERVER['argv']); diff --git a/lib/Zend/Service/WindowsAzure/CommandLine/Storage.php b/lib/Zend/Service/WindowsAzure/CommandLine/Storage.php deleted file mode 100644 index 05fb5c68d78..00000000000 --- a/lib/Zend/Service/WindowsAzure/CommandLine/Storage.php +++ /dev/null @@ -1,198 +0,0 @@ -" -cert:"mycert.pem" - */ - public function listAccountsCommand($subscriptionId, $certificate, $certificatePassphrase) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->listStorageAccounts(); - - if (count($result) == 0) { - echo 'No data to display.'; - } - foreach ($result as $object) { - $this->_displayObjectInformation($object, array('ServiceName', 'Url')); - } - } - - /** - * Get storage account properties. - * - * @command-name GetProperties - * @command-description Get storage account properties. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $accountName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --AccountName Required. The storage account name to operate on. - * @command-example Get storage account properties for account "phptest": - * @command-example GetProperties -sid:"" -cert:"mycert.pem" - * @command-example --AccountName:"phptest" - */ - public function getPropertiesCommand($subscriptionId, $certificate, $certificatePassphrase, $accountName) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getStorageAccountProperties($accountName); - - $this->_displayObjectInformation($result, array('ServiceName', 'Label', 'AffinityGroup', 'Location')); - } - - /** - * Get storage account property. - * - * @command-name GetProperty - * @command-description Get storage account property. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $accountName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --AccountName Required. The storage account name to operate on. - * @command-parameter-for $property Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Property|-prop Required. The property to retrieve for the storage account. - * @command-example Get storage account property "Url" for account "phptest": - * @command-example GetProperty -sid:"" -cert:"mycert.pem" - * @command-example --AccountName:"phptest" --Property:Url - */ - public function getPropertyCommand($subscriptionId, $certificate, $certificatePassphrase, $accountName, $property) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getStorageAccountProperties($accountName); - - printf("%s\r\n", $result->$property); - } - - /** - * Get storage account keys. - * - * @command-name GetKeys - * @command-description Get storage account keys. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $accountName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --AccountName Required. The storage account name to operate on. - * @command-example Get storage account keys for account "phptest": - * @command-example GetKeys -sid:"" -cert:"mycert.pem" - * @command-example --AccountName:"phptest" - */ - public function getKeysCommand($subscriptionId, $certificate, $certificatePassphrase, $accountName) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getStorageAccountKeys($accountName); - - $this->_displayObjectInformation((object)array('Key' => 'primary', 'Value' => $result[0]), array('Key', 'Value')); - $this->_displayObjectInformation((object)array('Key' => 'secondary', 'Value' => $result[1]), array('Key', 'Value')); - } - - /** - * Get storage account key. - * - * @command-name GetKey - * @command-description Get storage account key. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $accountName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --AccountName Required. The storage account name to operate on. - * @command-parameter-for $key Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Key|-k Optional. Specifies the key to regenerate (primary|secondary). If omitted, primary key is used as the default. - * @command-example Get primary storage account key for account "phptest": - * @command-example GetKey -sid:"" -cert:"mycert.pem" - * @command-example --AccountName:"phptest" -Key:primary - */ - public function getKeyCommand($subscriptionId, $certificate, $certificatePassphrase, $accountName, $key = 'primary') - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $result = $client->getStorageAccountKeys($accountName); - - if (strtolower($key) == 'secondary') { - printf("%s\r\n", $result[1]); - } - printf("%s\r\n", $result[0]); - } - - /** - * Regenerate storage account keys. - * - * @command-name RegenerateKeys - * @command-description Regenerate storage account keys. - * @command-parameter-for $subscriptionId Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --SubscriptionId|-sid Required. This is the Windows Azure Subscription Id to operate on. - * @command-parameter-for $certificate Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --Certificate|-cert Required. This is the .pem certificate that user has uploaded to Windows Azure subscription as Management Certificate. - * @command-parameter-for $certificatePassphrase Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Prompt --Passphrase|-p Required. The certificate passphrase. If not specified, a prompt will be displayed. - * @command-parameter-for $accountName Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile|Zend_Service_Console_Command_ParameterSource_Env --AccountName Required. The storage account name to operate on. - * @command-parameter-for $key Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --Key|-k Optional. Specifies the key to regenerate (primary|secondary). If omitted, primary key is used as the default. - * @command-parameter-for $waitForOperation Zend_Service_Console_Command_ParameterSource_Argv|Zend_Service_Console_Command_ParameterSource_ConfigFile --WaitFor|-w Optional. Wait for the operation to complete? - * @command-example Regenerate secondary key for account "phptest": - * @command-example RegenerateKeys -sid:"" -cert:"mycert.pem" - * @command-example --AccountName:"phptest" -Key:secondary - */ - public function regenerateKeysCommand($subscriptionId, $certificate, $certificatePassphrase, $accountName, $key = 'primary', $waitForOperation = false) - { - $client = new Zend_Service_WindowsAzure_Management_Client($subscriptionId, $certificate, $certificatePassphrase); - $client->regenerateStorageAccountKey($accountName, $key); - if ($waitForOperation) { - $client->waitForOperation(); - } - echo $client->getLastRequestId(); - } -} - -Zend_Service_Console_Command::bootstrap($_SERVER['argv']); diff --git a/lib/Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php b/lib/Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php deleted file mode 100644 index 3edecd6d722..00000000000 --- a/lib/Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php +++ /dev/null @@ -1,235 +0,0 @@ -_accountName = $accountName; - $this->_accountKey = base64_decode($accountKey); - $this->_usePathStyleUri = $usePathStyleUri; - } - - /** - * Set account name for Windows Azure - * - * @param string $value - * @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract - */ - public function setAccountName($value = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT) - { - $this->_accountName = $value; - return $this; - } - - /** - * Set account key for Windows Azure - * - * @param string $value - * @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract - */ - public function setAccountkey($value = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY) - { - $this->_accountKey = base64_decode($value); - return $this; - } - - /** - * Set use path-style URI's - * - * @param boolean $value - * @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract - */ - public function setUsePathStyleUri($value = false) - { - $this->_usePathStyleUri = $value; - return $this; - } - - /** - * Sign request URL with credentials - * - * @param string $requestUrl Request URL - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return string Signed request URL - */ - abstract public function signRequestUrl( - $requestUrl = '', - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ - ); - - /** - * Sign request headers with credentials - * - * @param string $httpVerb HTTP verb the request will use - * @param string $path Path for the request - * @param string $queryString Query string for the request - * @param array $headers x-ms headers to add - * @param boolean $forTableStorage Is the request for table storage? - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @param mixed $rawData Raw post data - * @return array Array of headers - */ - abstract public function signRequestHeaders( - $httpVerb = Zend_Http_Client::GET, - $path = '/', - $queryString = '', - $headers = null, - $forTableStorage = false, - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ, - $rawData = null - ); - - - /** - * Prepare query string for signing - * - * @param string $value Original query string - * @return string Query string for signing - */ - protected function _prepareQueryStringForSigning($value) - { - // Return value - $returnValue = array(); - - // Prepare query string - $queryParts = $this->_makeArrayOfQueryString($value); - foreach ($queryParts as $key => $value) { - $returnValue[] = $key . '=' . $value; - } - - // Return - if (count($returnValue) > 0) { - return '?' . implode('&', $returnValue); - } else { - return ''; - } - } - - /** - * Make array of query string - * - * @param string $value Query string - * @return array Array of key/value pairs - */ - protected function _makeArrayOfQueryString($value) - { - // Returnvalue - $returnValue = array(); - - // Remove front ? - if (strlen($value) > 0 && strpos($value, '?') === 0) { - $value = substr($value, 1); - } - - // Split parts - $queryParts = explode('&', $value); - foreach ($queryParts as $queryPart) { - $queryPart = explode('=', $queryPart, 2); - - if ($queryPart[0] != '') { - $returnValue[ $queryPart[0] ] = isset($queryPart[1]) ? $queryPart[1] : ''; - } - } - - // Sort - ksort($returnValue); - - // Return - return $returnValue; - } - - /** - * Returns an array value if the key is set, otherwide returns $valueIfNotSet - * - * @param array $array - * @param mixed $key - * @param mixed $valueIfNotSet - * @return mixed - */ - protected function _issetOr($array, $key, $valueIfNotSet) - { - return isset($array[$key]) ? $array[$key] : $valueIfNotSet; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Credentials/Exception.php b/lib/Zend/Service/WindowsAzure/Credentials/Exception.php deleted file mode 100644 index a6c0c286435..00000000000 --- a/lib/Zend/Service/WindowsAzure/Credentials/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_permissionSet = $permissionSet; - } - - /** - * Get permission set - * - * @return array - */ - public function getPermissionSet() - { - return $this->_permissionSet; - } - - /** - * Set permisison set - * - * Warning: fine-grained permissions should be added prior to coarse-grained permissions. - * For example: first add blob permissions, end with container-wide permissions. - * - * Warning: the signed access signature URL must match the account name of the - * Zend_Service_WindowsAzure_Credentials_Zend_Service_WindowsAzure_Credentials_SharedAccessSignature instance - * - * @param array $value Permission set - * @return void - */ - public function setPermissionSet($value = array()) - { - foreach ($value as $url) { - if (strpos($url, $this->_accountName) === false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('The permission set can only contain URLs for the account name specified in the Zend_Service_WindowsAzure_Credentials_SharedAccessSignature instance.'); - } - } - $this->_permissionSet = $value; - } - - /** - * Create signature - * - * @param string $path Path for the request - * @param string $resource Signed resource - container (c) - blob (b) - * @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l) - * @param string $start The time at which the Shared Access Signature becomes valid. - * @param string $expiry The time at which the Shared Access Signature becomes invalid. - * @param string $identifier Signed identifier - * @return string - */ - public function createSignature( - $path = '/', - $resource = 'b', - $permissions = 'r', - $start = '', - $expiry = '', - $identifier = '' - ) { - // Determine path - if ($this->_usePathStyleUri) { - $path = substr($path, strpos($path, '/')); - } - - // Add trailing slash to $path - if (substr($path, 0, 1) !== '/') { - $path = '/' . $path; - } - - // Build canonicalized resource string - $canonicalizedResource = '/' . $this->_accountName; - /*if ($this->_usePathStyleUri) { - $canonicalizedResource .= '/' . $this->_accountName; - }*/ - $canonicalizedResource .= $path; - - // Create string to sign - $stringToSign = array(); - $stringToSign[] = $permissions; - $stringToSign[] = $start; - $stringToSign[] = $expiry; - $stringToSign[] = $canonicalizedResource; - $stringToSign[] = $identifier; - - $stringToSign = implode("\n", $stringToSign); - $signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true)); - - return $signature; - } - - /** - * Create signed query string - * - * @param string $path Path for the request - * @param string $queryString Query string for the request - * @param string $resource Signed resource - container (c) - blob (b) - * @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l) - * @param string $start The time at which the Shared Access Signature becomes valid. - * @param string $expiry The time at which the Shared Access Signature becomes invalid. - * @param string $identifier Signed identifier - * @return string - */ - public function createSignedQueryString( - $path = '/', - $queryString = '', - $resource = 'b', - $permissions = 'r', - $start = '', - $expiry = '', - $identifier = '' - ) { - // Parts - $parts = array(); - if ($start !== '') { - $parts[] = 'st=' . urlencode($start); - } - $parts[] = 'se=' . urlencode($expiry); - $parts[] = 'sr=' . $resource; - $parts[] = 'sp=' . $permissions; - if ($identifier !== '') { - $parts[] = 'si=' . urlencode($identifier); - } - $parts[] = 'sig=' . urlencode($this->createSignature($path, $resource, $permissions, $start, $expiry, $identifier)); - - // Assemble parts and query string - if ($queryString != '') { - $queryString .= '&'; - } - $queryString .= implode('&', $parts); - - return $queryString; - } - - /** - * Permission matches request? - * - * @param string $permissionUrl Permission URL - * @param string $requestUrl Request URL - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return string Signed request URL - */ - public function permissionMatchesRequest( - $permissionUrl = '', - $requestUrl = '', - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ - ) { - // Build requirements - $requiredResourceType = $resourceType; - if ($requiredResourceType == Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB) { - $requiredResourceType .= Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER; - } - - // Parse permission url - $parsedPermissionUrl = parse_url($permissionUrl); - - // Parse permission properties - $permissionParts = explode('&', $parsedPermissionUrl['query']); - - // Parse request url - $parsedRequestUrl = parse_url($requestUrl); - - // Check if permission matches request - $matches = true; - foreach ($permissionParts as $part) { - list($property, $value) = explode('=', $part, 2); - - if ($property == 'sr') { - $matches = $matches && (strpbrk($value, $requiredResourceType) !== false); - } - - if ($property == 'sp') { - $matches = $matches && (strpbrk($value, $requiredPermission) !== false); - } - } - - // Ok, but... does the resource match? - $matches = $matches && (strpos($parsedRequestUrl['path'], $parsedPermissionUrl['path']) !== false); - - // Return - return $matches; - } - - /** - * Sign request URL with credentials - * - * @param string $requestUrl Request URL - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return string Signed request URL - */ - public function signRequestUrl( - $requestUrl = '', - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ - ) { - // Look for a matching permission - foreach ($this->getPermissionSet() as $permittedUrl) { - if ($this->permissionMatchesRequest($permittedUrl, $requestUrl, $resourceType, $requiredPermission)) { - // This matches, append signature data - $parsedPermittedUrl = parse_url($permittedUrl); - - if (strpos($requestUrl, '?') === false) { - $requestUrl .= '?'; - } else { - $requestUrl .= '&'; - } - - $requestUrl .= $parsedPermittedUrl['query']; - - // Return url - return $requestUrl; - } - } - - // Return url, will be unsigned... - return $requestUrl; - } - - /** - * Sign request with credentials - * - * @param string $httpVerb HTTP verb the request will use - * @param string $path Path for the request - * @param string $queryString Query string for the request - * @param array $headers x-ms headers to add - * @param boolean $forTableStorage Is the request for table storage? - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @param mixed $rawData Raw post data - * @return array Array of headers - */ - public function signRequestHeaders( - $httpVerb = Zend_Http_Client::GET, - $path = '/', - $queryString = '', - $headers = null, - $forTableStorage = false, - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ, - $rawData = null - ) { - return $headers; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Credentials/SharedKey.php b/lib/Zend/Service/WindowsAzure/Credentials/SharedKey.php deleted file mode 100644 index 3ec2875a248..00000000000 --- a/lib/Zend/Service/WindowsAzure/Credentials/SharedKey.php +++ /dev/null @@ -1,173 +0,0 @@ -_usePathStyleUri) { - $path = substr($path, strpos($path, '/')); - } - - // Determine query - $queryString = $this->_prepareQueryStringForSigning($queryString); - - // Canonicalized headers - $canonicalizedHeaders = array(); - - // Request date - $requestDate = ''; - if (isset($headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) { - $requestDate = $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date']; - } else { - $requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123 - $canonicalizedHeaders[] = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date:' . $requestDate; - } - - // Build canonicalized headers - if (!is_null($headers)) { - foreach ($headers as $header => $value) { - if (is_bool($value)) { - $value = $value === true ? 'True' : 'False'; - } - - $headers[$header] = $value; - if (substr($header, 0, strlen(Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER)) == Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER) { - $canonicalizedHeaders[] = strtolower($header) . ':' . $value; - } - } - } - sort($canonicalizedHeaders); - - // Build canonicalized resource string - $canonicalizedResource = '/' . $this->_accountName; - if ($this->_usePathStyleUri) { - $canonicalizedResource .= '/' . $this->_accountName; - } - $canonicalizedResource .= $path; - if ($queryString !== '') { - $queryStringItems = $this->_makeArrayOfQueryString($queryString); - foreach ($queryStringItems as $key => $value) { - $canonicalizedResource .= "\n" . strtolower($key) . ':' . urldecode($value); - } - } - - // Content-Length header - $contentLength = ''; - if (strtoupper($httpVerb) != Zend_Http_Client::GET - && strtoupper($httpVerb) != Zend_Http_Client::DELETE - && strtoupper($httpVerb) != Zend_Http_Client::HEAD) { - $contentLength = 0; - - if (!is_null($rawData)) { - $contentLength = strlen($rawData); - } - } - - // Create string to sign - $stringToSign = array(); - $stringToSign[] = strtoupper($httpVerb); // VERB - $stringToSign[] = $this->_issetOr($headers, 'Content-Encoding', ''); // Content-Encoding - $stringToSign[] = $this->_issetOr($headers, 'Content-Language', ''); // Content-Language - $stringToSign[] = $contentLength; // Content-Length - $stringToSign[] = $this->_issetOr($headers, 'Content-MD5', ''); // Content-MD5 - $stringToSign[] = $this->_issetOr($headers, 'Content-Type', ''); // Content-Type - $stringToSign[] = ""; // Date - $stringToSign[] = $this->_issetOr($headers, 'If-Modified-Since', ''); // If-Modified-Since - $stringToSign[] = $this->_issetOr($headers, 'If-Match', ''); // If-Match - $stringToSign[] = $this->_issetOr($headers, 'If-None-Match', ''); // If-None-Match - $stringToSign[] = $this->_issetOr($headers, 'If-Unmodified-Since', ''); // If-Unmodified-Since - $stringToSign[] = $this->_issetOr($headers, 'Range', ''); // Range - - if (!$forTableStorage && count($canonicalizedHeaders) > 0) { - $stringToSign[] = implode("\n", $canonicalizedHeaders); // Canonicalized headers - } - - $stringToSign[] = $canonicalizedResource; // Canonicalized resource - $stringToSign = implode("\n", $stringToSign); - $signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true)); - - // Sign request - $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate; - $headers['Authorization'] = 'SharedKey ' . $this->_accountName . ':' . $signString; - - // Return headers - return $headers; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Credentials/SharedKeyLite.php b/lib/Zend/Service/WindowsAzure/Credentials/SharedKeyLite.php deleted file mode 100644 index a7d638cc168..00000000000 --- a/lib/Zend/Service/WindowsAzure/Credentials/SharedKeyLite.php +++ /dev/null @@ -1,152 +0,0 @@ -_usePathStyleUri) { - $path = substr($path, strpos($path, '/')); - } - - // Determine query - $queryString = $this->_prepareQueryStringForSigning($queryString); - - // Build canonicalized resource string - $canonicalizedResource = '/' . $this->_accountName; - if ($this->_usePathStyleUri) { - $canonicalizedResource .= '/' . $this->_accountName; - } - $canonicalizedResource .= $path; - if ($queryString !== '') { - $canonicalizedResource .= $queryString; - } - - // Request date - $requestDate = ''; - if (isset($headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) { - $requestDate = $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date']; - } else { - $requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123 - } - - // Create string to sign - $stringToSign = array(); - $stringToSign[] = $requestDate; // Date - $stringToSign[] = $canonicalizedResource; // Canonicalized resource - $stringToSign = implode("\n", $stringToSign); - $signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true)); - - // Sign request - $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate; - $headers['Authorization'] = 'SharedKeyLite ' . $this->_accountName . ':' . $signString; - - // Return headers - return $headers; - } - - /** - * Prepare query string for signing - * - * @param string $value Original query string - * @return string Query string for signing - */ - protected function _prepareQueryStringForSigning($value) - { - // Check for 'comp=' - if (strpos($value, 'comp=') === false) { - // If not found, no query string needed - return ''; - } else { - // If found, make sure it is the only parameter being used - if (strlen($value) > 0 && strpos($value, '?') === 0) { - $value = substr($value, 1); - } - - // Split parts - $queryParts = explode('&', $value); - foreach ($queryParts as $queryPart) { - if (strpos($queryPart, 'comp=') !== false) { - return '?' . $queryPart; - } - } - - // Should never happen... - return ''; - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDataSources.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDataSources.php deleted file mode 100644 index d97633a5b66..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDataSources.php +++ /dev/null @@ -1,81 +0,0 @@ -_data = array( - 'overallquotainmb' => $overallQuotaInMB, - 'logs' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationLogs(), - 'diagnosticinfrastructurelogs' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationDiagnosticInfrastructureLogs(), - 'performancecounters' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationPerformanceCounters(), - 'windowseventlog' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationWindowsEventLog(), - 'directories' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationDirectories() - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php deleted file mode 100644 index 7d6b2de8326..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php +++ /dev/null @@ -1,53 +0,0 @@ -_data = array( - 'bufferquotainmb' => $bufferQuotaInMB, - 'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes, - 'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDirectories.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDirectories.php deleted file mode 100644 index 39534fadc93..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationDirectories.php +++ /dev/null @@ -1,85 +0,0 @@ -_data = array( - 'bufferquotainmb' => $bufferQuotaInMB, - 'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes, - 'subscriptions' => array() - ); - } - - /** - * Add subscription - * - * @param string $path Path - * @param string $container Container - * @param int $directoryQuotaInMB Directory quota in MB - */ - public function addSubscription($path, $container, $directoryQuotaInMB = 1024) - { - $this->_data['subscriptions'][$path] = new Zend_Service_WindowsAzure_Diagnostics_DirectoryConfigurationSubscription($path, $container, $directoryQuotaInMB); - } - - /** - * Remove subscription - * - * @param string $path Path - */ - public function removeSubscription($path) - { - if (isset($this->_data['subscriptions'][$path])) { - unset($this->_data['subscriptions'][$path]); - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationInstance.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationInstance.php deleted file mode 100644 index b9c163c38d4..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationInstance.php +++ /dev/null @@ -1,220 +0,0 @@ -_data = array( - 'datasources' => new Zend_Service_WindowsAzure_Diagnostics_ConfigurationDataSources() - ); - } - - /** - * Load configuration XML - * - * @param string $configurationXml Configuration XML - */ - public function loadXml($configurationXml) - { - // Convert to SimpleXMLElement - $configurationXml = Zend_Xml_Security::scan($configurationXml); - - // Assign general settings - $this->DataSources->OverallQuotaInMB = (int)$configurationXml->DataSources->OverallQuotaInMB; - - // Assign Logs settings - $this->DataSources->Logs->BufferQuotaInMB = (int)$configurationXml->DataSources->Logs->BufferQuotaInMB; - $this->DataSources->Logs->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->Logs->ScheduledTransferPeriodInMinutes; - $this->DataSources->Logs->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->Logs->ScheduledTransferLogLevelFilter; - - // Assign DiagnosticInfrastructureLogs settings - $this->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB = (int)$configurationXml->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB; - $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes; - $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter; - - // Assign PerformanceCounters settings - $this->DataSources->PerformanceCounters->BufferQuotaInMB = (int)$configurationXml->DataSources->PerformanceCounters->BufferQuotaInMB; - $this->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes; - if ($configurationXml->DataSources->PerformanceCounters->Subscriptions - && $configurationXml->DataSources->PerformanceCounters->Subscriptions->PerformanceCounterConfiguration) { - $subscriptions = $configurationXml->DataSources->PerformanceCounters->Subscriptions; - if (count($subscriptions->PerformanceCounterConfiguration) > 1) { - $subscriptions = $subscriptions->PerformanceCounterConfiguration; - } else { - $subscriptions = array($subscriptions->PerformanceCounterConfiguration); - } - foreach ($subscriptions as $subscription) { - $this->DataSources->PerformanceCounters->addSubscription((string)$subscription->CounterSpecifier, (int)$subscription->SampleRateInSeconds); - } - } - - // Assign WindowsEventLog settings - $this->DataSources->WindowsEventLog->BufferQuotaInMB = (int)$configurationXml->DataSources->WindowsEventLog->BufferQuotaInMB; - $this->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes; - $this->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter; - if ($configurationXml->DataSources->WindowsEventLog->Subscriptions - && $configurationXml->DataSources->WindowsEventLog->Subscriptions->string) { - $subscriptions = $configurationXml->DataSources->WindowsEventLog->Subscriptions; - if (count($subscriptions->string) > 1) { - $subscriptions = $subscriptions->string; - } else { - $subscriptions = array($subscriptions->string); - } - foreach ($subscriptions as $subscription) { - $this->DataSources->WindowsEventLog->addSubscription((string)$subscription); - } - } - - // Assign Directories settings - $this->DataSources->Directories->BufferQuotaInMB = (int)$configurationXml->DataSources->Directories->BufferQuotaInMB; - $this->DataSources->Directories->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->Directories->ScheduledTransferPeriodInMinutes; - - if ($configurationXml->DataSources->Directories->Subscriptions - && $configurationXml->DataSources->Directories->Subscriptions->DirectoryConfiguration) { - $subscriptions = $configurationXml->DataSources->Directories->Subscriptions; - if (count($subscriptions->DirectoryConfiguration) > 1) { - $subscriptions = $subscriptions->DirectoryConfiguration; - } else { - $subscriptions = array($subscriptions->DirectoryConfiguration); - } - foreach ($subscriptions as $subscription) { - $this->DataSources->Directories->addSubscription((string)$subscription->Path, (string)$subscription->Container, (int)$subscription->DirectoryQuotaInMB); - } - } - } - - /** - * Create configuration XML - * - * @return string - */ - public function toXml() - { - // Return value - $returnValue = array(); - - // Build XML - $returnValue[] = ''; - $returnValue[] = ''; - - // Add data sources - $returnValue[] = ' '; - - $returnValue[] = ' ' . $this->DataSources->OverallQuotaInMB . ''; - - $returnValue[] = ' '; - $returnValue[] = ' ' . $this->DataSources->Logs->BufferQuotaInMB . ''; - $returnValue[] = ' ' . $this->DataSources->Logs->ScheduledTransferPeriodInMinutes . ''; - $returnValue[] = ' ' . $this->DataSources->Logs->ScheduledTransferLogLevelFilter . ''; - $returnValue[] = ' '; - - $returnValue[] = ' '; - $returnValue[] = ' ' . $this->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB . ''; - $returnValue[] = ' ' . $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes . ''; - $returnValue[] = ' ' . $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter . ''; - $returnValue[] = ' '; - - $returnValue[] = ' '; - $returnValue[] = ' ' . $this->DataSources->PerformanceCounters->BufferQuotaInMB . ''; - $returnValue[] = ' ' . $this->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes . ''; - if (count($this->DataSources->PerformanceCounters->Subscriptions) == 0) { - $returnValue[] = ' '; - } else { - $returnValue[] = ' '; - foreach ($this->DataSources->PerformanceCounters->Subscriptions as $subscription) { - $returnValue[] = ' '; - $returnValue[] = ' ' . $subscription->CounterSpecifier . ''; - $returnValue[] = ' ' . $subscription->SampleRateInSeconds . ''; - $returnValue[] = ' '; - } - $returnValue[] = ' '; - } - $returnValue[] = ' '; - - $returnValue[] = ' '; - $returnValue[] = ' ' . $this->DataSources->WindowsEventLog->BufferQuotaInMB . ''; - $returnValue[] = ' ' . $this->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes . ''; - if (count($this->DataSources->WindowsEventLog->Subscriptions) == 0) { - $returnValue[] = ' '; - } else { - $returnValue[] = ' '; - foreach ($this->DataSources->WindowsEventLog->Subscriptions as $subscription) { - $returnValue[] = ' ' . $subscription . ''; - } - $returnValue[] = ' '; - } - $returnValue[] = ' ' . $this->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter . ''; - $returnValue[] = ' '; - - $returnValue[] = ' '; - $returnValue[] = ' ' . $this->DataSources->Directories->BufferQuotaInMB . ''; - $returnValue[] = ' ' . $this->DataSources->Directories->ScheduledTransferPeriodInMinutes . ''; - if (count($this->DataSources->Directories->Subscriptions) == 0) { - $returnValue[] = ' '; - } else { - $returnValue[] = ' '; - foreach ($this->DataSources->Directories->Subscriptions as $subscription) { - $returnValue[] = ' '; - $returnValue[] = ' ' . $subscription->Path . ''; - $returnValue[] = ' ' . $subscription->Container . ''; - $returnValue[] = ' ' . $subscription->DirectoryQuotaInMB . ''; - $returnValue[] = ' '; - } - $returnValue[] = ' '; - } - $returnValue[] = ' '; - - $returnValue[] = ' '; - $returnValue[] = ' false'; - $returnValue[] = ''; - - // Return - return implode("\r\n", $returnValue); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationLogs.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationLogs.php deleted file mode 100644 index f6ffd6b8633..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationLogs.php +++ /dev/null @@ -1,62 +0,0 @@ -_data = array( - 'bufferquotainmb' => $bufferQuotaInMB, - 'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes, - 'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php deleted file mode 100644 index 47ef47f4082..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php +++ /dev/null @@ -1,66 +0,0 @@ -_data)) { - $this->_data[strtolower($name)] = $value; - return; - } - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception("Unknown property: " . $name); - } - - /** - * Magic overload for getting properties - * - * @param string $name Name of the property - */ - public function __get($name) { - if (array_key_exists(strtolower($name), $this->_data)) { - return $this->_data[strtolower($name)]; - } - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception("Unknown property: " . $name); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php deleted file mode 100644 index 28bb951fe65..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php +++ /dev/null @@ -1,85 +0,0 @@ -_data = array( - 'bufferquotainmb' => $bufferQuotaInMB, - 'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes, - 'subscriptions' => array() - ); - } - - /** - * Add subscription - * - * @param string $counterSpecifier Counter specifier - * @param int $sampleRateInSeconds Sample rate in seconds - */ - public function addSubscription($counterSpecifier, $sampleRateInSeconds = 1) - { - - $this->_data['subscriptions'][$counterSpecifier] = new Zend_Service_WindowsAzure_Diagnostics_PerformanceCounterSubscription($counterSpecifier, $sampleRateInSeconds); - } - - /** - * Remove subscription - * - * @param string $counterSpecifier Counter specifier - */ - public function removeSubscription($counterSpecifier) - { - if (isset($this->_data['subscriptions'][$counterSpecifier])) { - unset($this->_data['subscriptions'][$counterSpecifier]); - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php b/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php deleted file mode 100644 index 3b991430a51..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php +++ /dev/null @@ -1,76 +0,0 @@ -_data = array( - 'bufferquotainmb' => $bufferQuotaInMB, - 'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes, - 'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter, - 'subscriptions' => array() - ); - } - - /** - * Add subscription - * - * @param string $filter Event log filter - */ - public function addSubscription($filter) - { - $this->_data['subscriptions'][$filter] = $filter; - } - - /** - * Remove subscription - * - * @param string $filter Event log filter - */ - public function removeSubscription($filter) - { - if (isset($this->_data['subscriptions'][$filter])) { - unset($this->_data['subscriptions'][$filter]); - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php b/lib/Zend/Service/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php deleted file mode 100644 index eb1e23e1d08..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php +++ /dev/null @@ -1,53 +0,0 @@ -_data = array( - 'path' => $path, - 'container' => $container, - 'directoryquotainmb' => $directoryQuotaInMB - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/Exception.php b/lib/Zend/Service/WindowsAzure/Diagnostics/Exception.php deleted file mode 100644 index 0ebf6072c19..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -_blobStorageClient = $blobStorageClient; - $this->_controlContainer = $controlContainer; - - $this->_ensureStorageInitialized(); - } - - /** - * Ensure storage has been initialized - */ - protected function _ensureStorageInitialized() - { - if (!$this->_blobStorageClient->containerExists($this->_controlContainer)) { - $this->_blobStorageClient->createContainer($this->_controlContainer); - } - } - - /** - * Get default configuration values - * - * @return Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance - */ - public function getDefaultConfiguration() - { - return new Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance(); - } - - /** - * Checks if a configuration for a specific role instance exists. - * - * @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure. - * @return boolean - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function configurationForRoleInstanceExists($roleInstance = null) - { - if (is_null($roleInstance)) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.'); - } - - return $this->_blobStorageClient->blobExists($this->_controlContainer, $roleInstance); - } - - /** - * Checks if a configuration for current role instance exists. Only works on Development Fabric or Windows Azure Fabric. - * - * @return boolean - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function configurationForCurrentRoleInstanceExists() - { - if (!isset($_SERVER['RdRoleId'])) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.'); - } - - return $this->_blobStorageClient->blobExists($this->_controlContainer, $this->_getCurrentRoleInstanceId()); - } - - /** - * Get configuration for current role instance. Only works on Development Fabric or Windows Azure Fabric. - * - * @return Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function getConfigurationForCurrentRoleInstance() - { - if (!isset($_SERVER['RdRoleId'])) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.'); - } - return $this->getConfigurationForRoleInstance($this->_getCurrentRoleInstanceId()); - } - - /** - * Get the current role instance ID. Only works on Development Fabric or Windows Azure Fabric. - * - * @return string - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - protected function _getCurrentRoleInstanceId() - { - if (!isset($_SERVER['RdRoleId'])) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.'); - } - - if (strpos($_SERVER['RdRoleId'], 'deployment(') === false) { - return $_SERVER['RdRoleId']; - } else { - $roleIdParts = explode('.', $_SERVER['RdRoleId']); - return $roleIdParts[0] . '/' . $roleIdParts[2] . '/' . $_SERVER['RdRoleId']; - } - - if (!isset($_SERVER['RoleDeploymentID']) && !isset($_SERVER['RoleInstanceID']) && !isset($_SERVER['RoleName'])) { - throw new Exception('Server variables \'RoleDeploymentID\', \'RoleInstanceID\' and \'RoleName\' are unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.'); - } - - if (strpos($_SERVER['RdRoleId'], 'deployment(') === false) { - return $_SERVER['RdRoleId']; - } else { - return $_SERVER['RoleDeploymentID'] . '/' . $_SERVER['RoleInstanceID'] . '/' . $_SERVER['RoleName']; - } - } - - /** - * Set configuration for current role instance. Only works on Development Fabric or Windows Azure Fabric. - * - * @param Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance $configuration Configuration to apply - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function setConfigurationForCurrentRoleInstance(Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance $configuration) - { - if (!isset($_SERVER['RdRoleId'])) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.'); - } - - $this->setConfigurationForRoleInstance($this->_getCurrentRoleInstanceId(), $configuration); - } - - /** - * Get configuration for a specific role instance - * - * @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure. - * @return Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function getConfigurationForRoleInstance($roleInstance = null) - { - if (is_null($roleInstance)) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.'); - } - - - - if ($this->_blobStorageClient->blobExists($this->_controlContainer, $roleInstance)) { - $configurationInstance = new Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance(); - $configurationInstance->loadXml( $this->_blobStorageClient->getBlobData($this->_controlContainer, $roleInstance) ); - return $configurationInstance; - } - - return new Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance(); - } - - /** - * Set configuration for a specific role instance - * - * @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure. - * @param Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance $configuration Configuration to apply - * @throws Zend_Service_WindowsAzure_Diagnostics_Exception - */ - public function setConfigurationForRoleInstance($roleInstance, Zend_Service_WindowsAzure_Diagnostics_ConfigurationInstance $configuration) - { - if (is_null($roleInstance)) { - #require_once 'Zend/Service/WindowsAzure/Diagnostics/Exception.php'; - throw new Zend_Service_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.'); - } - - $this->_blobStorageClient->putBlobData($this->_controlContainer, $roleInstance, $configuration->toXml(), array(), null, array('Content-Type' => 'text/xml')); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php b/lib/Zend/Service/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php deleted file mode 100644 index 2905d077339..00000000000 --- a/lib/Zend/Service/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php +++ /dev/null @@ -1,54 +0,0 @@ -_data = array( - 'counterspecifier' => $counterSpecifier, - 'samplerateinseconds' => $sampleRateInSeconds - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Exception.php b/lib/Zend/Service/WindowsAzure/Exception.php deleted file mode 100644 index e1739311a0d..00000000000 --- a/lib/Zend/Service/WindowsAzure/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ - $value) { - if ((is_object($value) && !method_exists($value, '__toString')) - || is_array($value) - ) { - $value = gettype($value); - } - $logEntity->{$key} = $value; - } - - return $logEntity; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Log/Writer/WindowsAzure.php b/lib/Zend/Service/WindowsAzure/Log/Writer/WindowsAzure.php deleted file mode 100644 index 66be08fe282..00000000000 --- a/lib/Zend/Service/WindowsAzure/Log/Writer/WindowsAzure.php +++ /dev/null @@ -1,196 +0,0 @@ -_tableStorageConnection = $tableStorageConnection; - $this->_tableName = $tableName; - - // create the logging table if it does not exist. It will add some overhead, so it's optional - if ($createTable) { - $this->_tableStorageConnection->createTableIfNotExists( - $this->_tableName - ); - } - - // keep messages to be logged in an internal buffer and only send them over the wire when - // the script execution ends - if ($bufferMessages) { - $this->_bufferMessages = $bufferMessages; - } - - $this->_formatter = - new Zend_Service_WindowsAzure_Log_Formatter_WindowsAzure(); - } - - /** - * If the log messages have been stored in the internal buffer, just send them - * to table storage. - */ - public function shutdown() - { - parent::shutdown(); - if ($this->_bufferMessages) { - $this->_tableStorageConnection->startBatch(); - foreach ($this->_messageBuffer as $logEntity) { - $this->_tableStorageConnection->insertEntity( - $this->_tableName, $logEntity - ); - } - $this->_tableStorageConnection->commit(); - } - } - - /** - * Create a new instance of Zend_Service_Log_Writer_WindowsAzure - * - * @param array $config - * @return Zend_Service_Log_Writer_WindowsAzure - * @throws Zend_Service_Log_Exception - */ - static public function factory($config) - { - $config = self::_parseConfig($config); - $config = array_merge( - array( - 'connection' => null, - 'tableName' => null, - 'createTable' => true, - ), $config - ); - - return new self( - $config['connection'], - $config['tableName'], - $config['createTable'] - ); - } - - /** - * The only formatter accepted is already loaded in the constructor - * - * @todo enable custom formatters using the WindowsAzure_Storage_DynamicTableEntity class - */ - public function setFormatter( - Zend_Service_Log_Formatter_Interface $formatter - ) - { - #require_once 'Zend/Service/Log/Exception.php'; - throw new Zend_Service_Log_Exception( - get_class($this) . ' does not support formatting'); - } - - /** - * Write a message to the table storage. If buffering is activated, then messages will just be - * added to an internal buffer. - * - * @param array $event - * @return void - * @todo format the event using a formatted, not in this method - */ - protected function _write($event) - { - $logEntity = $this->_formatter->format($event); - - if ($this->_bufferMessages) { - $this->_messageBuffer[] = $logEntity; - } else { - $this->_tableStorageConnection->insertEntity( - $this->_tableName, $logEntity - ); - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php b/lib/Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php deleted file mode 100644 index c41175442b8..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php +++ /dev/null @@ -1,66 +0,0 @@ -_data = array( - 'name' => $name, - 'label' => base64_decode($label), - 'description' => $description, - 'location' => $location, - 'hostedservices' => $hostedServices, - 'storageservices' => $storageServices - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/CertificateInstance.php b/lib/Zend/Service/WindowsAzure/Management/CertificateInstance.php deleted file mode 100644 index 359601ada73..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/CertificateInstance.php +++ /dev/null @@ -1,60 +0,0 @@ -_data = array( - 'certificateurl' => $certificateUrl, - 'thumbprint' => $thumbprint, - 'thumbprintalgorithm' => $thumbprintAlgorithm, - 'data' => base64_decode($data) - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/Client.php b/lib/Zend/Service/WindowsAzure/Management/Client.php deleted file mode 100644 index e714cfb5cb5..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/Client.php +++ /dev/null @@ -1,2426 +0,0 @@ -_subscriptionId = $subscriptionId; - $this->_certificatePath = $certificatePath; - $this->_certificatePassphrase = $certificatePassphrase; - - $this->_retryPolicy = $retryPolicy; - if (is_null($this->_retryPolicy)) { - $this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry(); - } - - // Setup default Zend_Http_Client channel - $options = array( - 'adapter' => 'Zend_Http_Client_Adapter_Socket', - 'ssltransport' => 'ssl', - 'sslcert' => $this->_certificatePath, - 'sslpassphrase' => $this->_certificatePassphrase, - 'sslusecontext' => true, - ); - if (function_exists('curl_init')) { - // Set cURL options if cURL is used afterwards - $options['curloptions'] = array( - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_TIMEOUT => 120, - ); - } - $this->_httpClientChannel = new Zend_Http_Client(null, $options); - } - - /** - * Set the HTTP client channel to use - * - * @param Zend_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name. - */ - public function setHttpClientChannel($adapterInstance = 'Zend_Http_Client_Adapter_Socket') - { - $this->_httpClientChannel->setAdapter($adapterInstance); - } - - /** - * Retrieve HTTP client channel - * - * @return Zend_Http_Client_Adapter_Interface - */ - public function getHttpClientChannel() - { - return $this->_httpClientChannel; - } - - /** - * Returns the Windows Azure subscription ID - * - * @return string - */ - public function getSubscriptionId() - { - return $this->_subscriptionId; - } - - /** - * Returns the last request ID. - * - * @return string - */ - public function getLastRequestId() - { - return $this->_lastRequestId; - } - - /** - * Get base URL for creating requests - * - * @return string - */ - public function getBaseUrl() - { - return self::URL_MANAGEMENT . '/' . $this->_subscriptionId; - } - - /** - * Perform request using Zend_Http_Client channel - * - * @param string $path Path - * @param string $queryString Query string - * @param string $httpVerb HTTP verb the request will use - * @param array $headers x-ms headers to add - * @param mixed $rawData Optional RAW HTTP data to be sent over the wire - * @return Zend_Http_Response - */ - protected function _performRequest( - $path = '/', - $queryString = '', - $httpVerb = Zend_Http_Client::GET, - $headers = array(), - $rawData = null - ) { - // Clean path - if (strpos($path, '/') !== 0) { - $path = '/' . $path; - } - - // Clean headers - if (is_null($headers)) { - $headers = array(); - } - - // Ensure cUrl will also work correctly: - // - disable Content-Type if required - // - disable Expect: 100 Continue - if (!isset($headers["Content-Type"])) { - $headers["Content-Type"] = ''; - } - //$headers["Expect"] = ''; - - // Add version header - $headers['x-ms-version'] = $this->_apiVersion; - - // URL encoding - $path = self::urlencode($path); - $queryString = self::urlencode($queryString); - - // Generate URL and sign request - $requestUrl = $this->getBaseUrl() . $path . $queryString; - $requestHeaders = $headers; - - // Prepare request - $this->_httpClientChannel->resetParameters(true); - $this->_httpClientChannel->setUri($requestUrl); - $this->_httpClientChannel->setHeaders($requestHeaders); - $this->_httpClientChannel->setRawData($rawData); - - // Execute request - $response = $this->_retryPolicy->execute( - array($this->_httpClientChannel, 'request'), - array($httpVerb) - ); - - // Store request id - $this->_lastRequestId = $response->getHeader('x-ms-request-id'); - - return $response; - } - - /** - * Parse result from Zend_Http_Response - * - * @param Zend_Http_Response $response Response from HTTP call - * @return object - * @throws Zend_Service_WindowsAzure_Exception - */ - protected function _parseResponse(Zend_Http_Response $response = null) - { - if (is_null($response)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Response should not be null.'); - } - - $xml = Zend_Xml_Security::scan($response->getBody()); - - if ($xml !== false) { - // Fetch all namespaces - $namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true)); - - // Register all namespace prefixes - foreach ($namespaces as $prefix => $ns) { - if ($prefix != '') { - $xml->registerXPathNamespace($prefix, $ns); - } - } - } - - return $xml; - } - - /** - * URL encode function - * - * @param string $value Value to encode - * @return string Encoded value - */ - public static function urlencode($value) - { - return str_replace(' ', '%20', $value); - } - - /** - * Builds a query string from an array of elements - * - * @param array Array of elements - * @return string Assembled query string - */ - public static function createQueryStringFromArray($queryString) - { - return count($queryString) > 0 ? '?' . implode('&', $queryString) : ''; - } - - /** - * Get error message from Zend_Http_Response - * - * @param Zend_Http_Response $response Repsonse - * @param string $alternativeError Alternative error message - * @return string - */ - protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') - { - $response = $this->_parseResponse($response); - if ($response && $response->Message) { - return (string)$response->Message; - } else { - return $alternativeError; - } - } - - /** - * The Get Operation Status operation returns the status of the specified operation. - * After calling an asynchronous operation, you can call Get Operation Status to - * determine whether the operation has succeed, failed, or is still in progress. - * - * @param string $requestId The request ID. If omitted, the last request ID will be used. - * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getOperationStatus($requestId = '') - { - if ($requestId == '') { - $requestId = $this->getLastRequestId(); - } - - $response = $this->_performRequest(self::OP_OPERATIONS . '/' . $requestId); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!is_null($result)) { - return new Zend_Service_WindowsAzure_Management_OperationStatusInstance( - (string)$result->ID, - (string)$result->Status, - ($result->Error ? (string)$result->Error->Code : ''), - ($result->Error ? (string)$result->Error->Message : '') - ); - } - return null; - } else { - #require_once 'Zend/Service/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - - - /** - * The List Subscription Operations operation returns a list of create, update, - * and delete operations that were performed on a subscription during the specified timeframe. - * Documentation on the parameters can be found at http://msdn.microsoft.com/en-us/library/gg715318.aspx. - * - * @param string $startTime The start of the timeframe to begin listing subscription operations in UTC format. This parameter and the $endTime parameter indicate the timeframe to retrieve subscription operations. This parameter cannot indicate a start date of more than 90 days in the past. - * @param string $endTime The end of the timeframe to begin listing subscription operations in UTC format. This parameter and the $startTime parameter indicate the timeframe to retrieve subscription operations. - * @param string $objectIdFilter Returns subscription operations only for the specified object type and object ID. - * @param string $operationResultFilter Returns subscription operations only for the specified result status, either Succeeded, Failed, or InProgress. - * @param string $continuationToken Internal usage. - * @return array Array of Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listSubscriptionOperations($startTime, $endTime, $objectIdFilter = null, $operationResultFilter = null, $continuationToken = null) - { - if ($startTime == '' || is_null($startTime)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Start time should be specified.'); - } - if ($endTime == '' || is_null($endTime)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('End time should be specified.'); - } - if ($operationResultFilter != '' && !is_null($operationResultFilter)) { - $operationResultFilter = strtolower($operationResultFilter); - if ($operationResultFilter != 'succeeded' && $operationResultFilter != 'failed' && $operationResultFilter != 'inprogress') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('OperationResultFilter should be succeeded|failed|inprogress.'); - } - } - - $parameters = array(); - $parameters[] = 'StartTime=' . $startTime; - $parameters[] = 'EndTime=' . $endTime; - if ($objectIdFilter != '' && !is_null($objectIdFilter)) { - $parameters[] = 'ObjectIdFilter=' . $objectIdFilter; - } - if ($operationResultFilter != '' && !is_null($operationResultFilter)) { - $parameters[] = 'OperationResultFilter=' . ucfirst($operationResultFilter); - } - if ($continuationToken != '' && !is_null($continuationToken)) { - $parameters[] = 'ContinuationToken=' . $continuationToken; - } - - $response = $this->_performRequest(self::OP_OPERATIONS, '?' . implode('&', $parameters)); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - $namespaces = $result->getDocNamespaces(); - $result->registerXPathNamespace('__empty_ns', $namespaces['']); - - $xmlOperations = $result->xpath('//__empty_ns:SubscriptionOperation'); - - // Create return value - $returnValue = array(); - foreach ($xmlOperations as $xmlOperation) { - // Create operation instance - $operation = new Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance( - $xmlOperation->OperationId, - $xmlOperation->OperationObjectId, - $xmlOperation->OperationName, - array(), - (array)$xmlOperation->OperationCaller, - (array)$xmlOperation->OperationStatus - ); - - // Parse parameters - $xmlOperation->registerXPathNamespace('__empty_ns', $namespaces['']); - $xmlParameters = $xmlOperation->xpath('.//__empty_ns:OperationParameter'); - foreach ($xmlParameters as $xmlParameter) { - $xmlParameterDetails = $xmlParameter->children('http://schemas.datacontract.org/2004/07/Microsoft.Samples.WindowsAzure.ServiceManagement'); - $operation->addOperationParameter((string)$xmlParameterDetails->Name, (string)$xmlParameterDetails->Value); - } - - // Add to result - $returnValue[] = $operation; - } - - // More data? - if (!is_null($result->ContinuationToken) && $result->ContinuationToken != '') { - $returnValue = array_merge($returnValue, $this->listSubscriptionOperations($startTime, $endTime, $objectIdFilter, $operationResultFilter, (string)$result->ContinuationToken)); - } - - // Return - return $returnValue; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Wait for an operation to complete - * - * @param string $requestId The request ID. If omitted, the last request ID will be used. - * @param int $sleepInterval Sleep interval in milliseconds. - * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function waitForOperation($requestId = '', $sleepInterval = 250) - { - if ($requestId == '') { - $requestId = $this->getLastRequestId(); - } - if ($requestId == '' || is_null($requestId)) { - return null; - } - - $status = $this->getOperationStatus($requestId); - while ($status->Status == 'InProgress') { - $status = $this->getOperationStatus($requestId); - usleep($sleepInterval); - } - - return $status; - } - - /** - * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance for the current account - * - * @param string $serviceName the service name to create a storage client for. - * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests - * @return Zend_Service_WindowsAzure_Storage_Blob - */ - public function createBlobClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) - { - if ($serviceName == '' || is_null($serviceName)) { - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $storageKeys = $this->getStorageAccountKeys($serviceName); - - - - return new Zend_Service_WindowsAzure_Storage_Blob( - Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB, - $serviceName, - $storageKeys[0], - false, - $retryPolicy - ); - } - - /** - * Creates a new Zend_Service_WindowsAzure_Storage_Table instance for the current account - * - * @param string $serviceName the service name to create a storage client for. - * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests - * @return Zend_Service_WindowsAzure_Storage_Table - */ - public function createTableClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $storageKeys = $this->getStorageAccountKeys($serviceName); - - return new Zend_Service_WindowsAzure_Storage_Table( - Zend_Service_WindowsAzure_Storage::URL_CLOUD_TABLE, - $serviceName, - $storageKeys[0], - false, - $retryPolicy - ); - } - - /** - * Creates a new Zend_Service_WindowsAzure_Storage_Queue instance for the current account - * - * @param string $serviceName the service name to create a storage client for. - * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests - * @return Zend_Service_WindowsAzure_Storage_Queue - */ - public function createQueueClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $storageKeys = $this->getStorageAccountKeys($serviceName); - - #require_once 'Zend/Service/WindowsAzure/Storage/Queue.php'; - - return new Zend_Service_WindowsAzure_Storage_Queue( - Zend_Service_WindowsAzure_Storage::URL_CLOUD_QUEUE, - $serviceName, - $storageKeys[0], - false, - $retryPolicy - ); - } - - /** - * The List Storage Accounts operation lists the storage accounts available under - * the current subscription. - * - * @return array An array of Zend_Service_WindowsAzure_Management_StorageServiceInstance - */ - public function listStorageAccounts() - { - $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->StorageService) { - return array(); - } - if (count($result->StorageService) > 1) { - $xmlServices = $result->StorageService; - } else { - $xmlServices = array($result->StorageService); - } - - $services = array(); - if (!is_null($xmlServices)) { - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_StorageServiceInstance( - (string)$xmlServices[$i]->Url, - (string)$xmlServices[$i]->ServiceName - ); - } - } - return $services; - } else { - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Storage Account Properties operation returns the system properties for the - * specified storage account. These properties include: the address, description, and - * label of the storage account; and the name of the affinity group to which the service - * belongs, or its geo-location if it is not part of an affinity group. - * - * @param string $serviceName The name of your service. - * @return Zend_Service_WindowsAzure_Management_StorageServiceInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getStorageAccountProperties($serviceName) - { - if ($serviceName == '' || is_null($serviceName)) { - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName); - - if ($response->isSuccessful()) { - $xmlService = $this->_parseResponse($response); - - if (!is_null($xmlService)) { - #require_once 'Zend/Service/WindowsAzure/Management/StorageServiceInstance.php'; - - return new Zend_Service_WindowsAzure_Management_StorageServiceInstance( - (string)$xmlService->Url, - (string)$xmlService->ServiceName, - (string)$xmlService->StorageServiceProperties->Description, - (string)$xmlService->StorageServiceProperties->AffinityGroup, - (string)$xmlService->StorageServiceProperties->Location, - (string)$xmlService->StorageServiceProperties->Label - ); - } - return null; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Storage Keys operation returns the primary - * and secondary access keys for the specified storage account. - * - * @param string $serviceName The name of your service. - * @return array An array of strings - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getStorageAccountKeys($serviceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys'); - - if ($response->isSuccessful()) { - $xmlService = $this->_parseResponse($response); - - if (!is_null($xmlService)) { - return array( - (string)$xmlService->StorageServiceKeys->Primary, - (string)$xmlService->StorageServiceKeys->Secondary - ); - } - return array(); - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Regenerate Keys operation regenerates the primary - * or secondary access key for the specified storage account. - * - * @param string $serviceName The name of your service. - * @param string $key The key to regenerate (primary or secondary) - * @return array An array of strings - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function regenerateStorageAccountKey($serviceName, $key = 'primary') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $key = strtolower($key); - if ($key != 'primary' && $key != 'secondary') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Key identifier should be primary|secondary.'); - } - - $response = $this->_performRequest( - self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys', '?action=regenerate', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml'), - ' - - ' . ucfirst($key) . ' - '); - - if ($response->isSuccessful()) { - $xmlService = $this->_parseResponse($response); - - if (!is_null($xmlService)) { - return array( - (string)$xmlService->StorageServiceKeys->Primary, - (string)$xmlService->StorageServiceKeys->Secondary - ); - } - return array(); - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List Hosted Services operation lists the hosted services available - * under the current subscription. - * - * @return array An array of Zend_Service_WindowsAzure_Management_HostedServiceInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listHostedServices() - { - $response = $this->_performRequest(self::OP_HOSTED_SERVICES); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->HostedService) { - return array(); - } - if (count($result->HostedService) > 1) { - $xmlServices = $result->HostedService; - } else { - $xmlServices = array($result->HostedService); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_HostedServiceInstance( - (string)$xmlServices[$i]->Url, - (string)$xmlServices[$i]->ServiceName - ); - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Create Hosted Service operation creates a new hosted service in Windows Azure. - * - * @param string $serviceName A name for the hosted service that is unique to the subscription. - * @param string $label A label for the hosted service. The label may be up to 100 characters in length. - * @param string $description A description for the hosted service. The description may be up to 1024 characters in length. - * @param string $location Required if AffinityGroup is not specified. The location where the hosted service will be created. - * @param string $affinityGroup Required if Location is not specified. The name of an existing affinity group associated with this subscription. - */ - public function createHostedService($serviceName, $label, $description = '', $location = null, $affinityGroup = null) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if (strlen($description) > 1024) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.'); - } - if ( (is_null($location) && is_null($affinityGroup)) || (!is_null($location) && !is_null($affinityGroup)) ) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Please specify a location -or- an affinity group for the service.'); - } - - $locationOrAffinityGroup = is_null($location) - ? '' . $affinityGroup . '' - : '' . $location . ''; - - $response = $this->_performRequest(self::OP_HOSTED_SERVICES, '', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $serviceName . '' . $description . '' . $locationOrAffinityGroup . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Update Hosted Service operation updates the label and/or the description for a hosted service in Windows Azure. - * - * @param string $serviceName A name for the hosted service that is unique to the subscription. - * @param string $label A label for the hosted service. The label may be up to 100 characters in length. - * @param string $description A description for the hosted service. The description may be up to 1024 characters in length. - */ - public function updateHostedService($serviceName, $label, $description = '') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - - $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '', - Zend_Http_Client::PUT, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $description . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Delete Hosted Service operation deletes the specified hosted service in Windows Azure. - * - * @param string $serviceName A name for the hosted service that is unique to the subscription. - */ - public function deleteHostedService($serviceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '', Zend_Http_Client::DELETE); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Hosted Service Properties operation retrieves system properties - * for the specified hosted service. These properties include the service - * name and service type; the name of the affinity group to which the service - * belongs, or its location if it is not part of an affinity group; and - * optionally, information on the service's deployments. - * - * @param string $serviceName The name of your service. - * @return Zend_Service_WindowsAzure_Management_HostedServiceInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getHostedServiceProperties($serviceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '?embed-detail=true'); - - if ($response->isSuccessful()) { - $xmlService = $this->_parseResponse($response); - - if (!is_null($xmlService)) { - - $returnValue = new Zend_Service_WindowsAzure_Management_HostedServiceInstance( - (string)$xmlService->Url, - (string)$xmlService->ServiceName, - (string)$xmlService->HostedServiceProperties->Description, - (string)$xmlService->HostedServiceProperties->AffinityGroup, - (string)$xmlService->HostedServiceProperties->Location, - (string)$xmlService->HostedServiceProperties->Label - ); - - // Deployments - if (count($xmlService->Deployments->Deployment) > 1) { - $xmlServices = $xmlService->Deployments->Deployment; - } else { - $xmlServices = array($xmlService->Deployments->Deployment); - } - - $deployments = array(); - foreach ($xmlServices as $xmlDeployment) { - $deployments[] = $this->_convertXmlElementToDeploymentInstance($xmlDeployment); - } - $returnValue->Deployments = $deployments; - - return $returnValue; - } - return null; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Create Deployment operation uploads a new service package - * and creates a new deployment on staging or production. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $name The name for the deployment. The deployment ID as listed on the Windows Azure management portal must be unique among other deployments for the hosted service. - * @param string $label A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription. - * @param string $packageUrl The service configuration file for the deployment. - * @param string $configuration A label for this deployment, up to 100 characters in length. - * @param boolean $startDeployment Indicates whether to start the deployment immediately after it is created. - * @param boolean $treatWarningsAsErrors Indicates whether to treat package validation warnings as errors. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function createDeployment($serviceName, $deploymentSlot, $name, $label, $packageUrl, $configuration, $startDeployment = false, $treatWarningsAsErrors = false) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($name == '' || is_null($name)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Name should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if ($packageUrl == '' || is_null($packageUrl)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.'); - } - if ($configuration == '' || is_null($configuration)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.'); - } - - if (@file_exists($configuration)) { - $configuration = utf8_decode(file_get_contents($configuration)); - } - - // Clean up the configuration - $conformingConfiguration = $this->_cleanConfiguration($configuration); - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - $response = $this->_performRequest($operationUrl, '', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $name . '' . $packageUrl . '' . base64_encode($conformingConfiguration) . '' . ($startDeployment ? 'true' : 'false') . '' . ($treatWarningsAsErrors ? 'true' : 'false') . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Deployment operation returns configuration information, status, - * and system properties for the specified deployment. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @return Zend_Service_WindowsAzure_Management_DeploymentInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getDeploymentBySlot($serviceName, $deploymentSlot) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_getDeployment($operationUrl); - } - - /** - * The Get Deployment operation returns configuration information, status, - * and system properties for the specified deployment. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @return Zend_Service_WindowsAzure_Management_DeploymentInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getDeploymentByDeploymentId($serviceName, $deploymentId) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_getDeployment($operationUrl); - } - - /** - * The Get Deployment operation returns configuration information, status, - * and system properties for the specified deployment. - * - * @param string $operationUrl The operation url - * @return Zend_Service_WindowsAzure_Management_DeploymentInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _getDeployment($operationUrl) - { - $response = $this->_performRequest($operationUrl); - - if ($response->isSuccessful()) { - $xmlService = $this->_parseResponse($response); - - return $this->_convertXmlElementToDeploymentInstance($xmlService); - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Swap Deployment operation initiates a virtual IP swap between - * the staging and production deployment environments for a service. - * If the service is currently running in the staging environment, - * it will be swapped to the production environment. If it is running - * in the production environment, it will be swapped to staging. - * - * @param string $serviceName The service name. - * @param string $productionDeploymentName The name of the production deployment. - * @param string $sourceDeploymentName The name of the source deployment. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function swapDeployment($serviceName, $productionDeploymentName, $sourceDeploymentName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($productionDeploymentName == '' || is_null($productionDeploymentName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Production Deployment ID should be specified.'); - } - if ($sourceDeploymentName == '' || is_null($sourceDeploymentName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Source Deployment ID should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName; - $response = $this->_performRequest($operationUrl, '', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $productionDeploymentName . '' . $sourceDeploymentName . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Delete Deployment operation deletes the specified deployment. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function deleteDeploymentBySlot($serviceName, $deploymentSlot) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_deleteDeployment($operationUrl); - } - - /** - * The Delete Deployment operation deletes the specified deployment. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function deleteDeploymentByDeploymentId($serviceName, $deploymentId) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_deleteDeployment($operationUrl); - } - - /** - * The Delete Deployment operation deletes the specified deployment. - * - * @param string $operationUrl The operation url - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _deleteDeployment($operationUrl) - { - $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Update Deployment Status operation initiates a change in deployment status. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $status The deployment status (running|suspended) - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function updateDeploymentStatusBySlot($serviceName, $deploymentSlot, $status = 'running') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - $status = strtolower($status); - if ($status != 'running' && $status != 'suspended') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_updateDeploymentStatus($operationUrl, $status); - } - - /** - * The Update Deployment Status operation initiates a change in deployment status. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param string $status The deployment status (running|suspended) - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function updateDeploymentStatusByDeploymentId($serviceName, $deploymentId, $status = 'running') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - $status = strtolower($status); - if ($status != 'running' && $status != 'suspended') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_updateDeploymentStatus($operationUrl, $status); - } - - /** - * The Update Deployment Status operation initiates a change in deployment status. - * - * @param string $operationUrl The operation url - * @param string $status The deployment status (running|suspended) - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _updateDeploymentStatus($operationUrl, $status = 'running') - { - $response = $this->_performRequest($operationUrl . '/', '?comp=status', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . ucfirst($status) . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Converts an XmlElement into a Zend_Service_WindowsAzure_Management_DeploymentInstance - * - * @param object $xmlService The XML Element - * @return Zend_Service_WindowsAzure_Management_DeploymentInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _convertXmlElementToDeploymentInstance($xmlService) - { - if (!is_null($xmlService)) { - - $returnValue = new Zend_Service_WindowsAzure_Management_DeploymentInstance( - (string)$xmlService->Name, - (string)$xmlService->DeploymentSlot, - (string)$xmlService->PrivateID, - (string)$xmlService->Label, - (string)$xmlService->Url, - (string)$xmlService->Configuration, - (string)$xmlService->Status, - (string)$xmlService->UpgradeStatus, - (string)$xmlService->UpgradeType, - (string)$xmlService->CurrentUpgradeDomainState, - (string)$xmlService->CurrentUpgradeDomain, - (string)$xmlService->UpgradeDomainCount - ); - - // Append role instances - if ($xmlService->RoleInstanceList && $xmlService->RoleInstanceList->RoleInstance) { - $xmlRoleInstances = $xmlService->RoleInstanceList->RoleInstance; - if (count($xmlService->RoleInstanceList->RoleInstance) == 1) { - $xmlRoleInstances = array($xmlService->RoleInstanceList->RoleInstance); - } - - $roleInstances = array(); - if (!is_null($xmlRoleInstances)) { - for ($i = 0; $i < count($xmlRoleInstances); $i++) { - $roleInstances[] = array( - 'rolename' => (string)$xmlRoleInstances[$i]->RoleName, - 'instancename' => (string)$xmlRoleInstances[$i]->InstanceName, - 'instancestatus' => (string)$xmlRoleInstances[$i]->InstanceStatus - ); - } - } - - $returnValue->RoleInstanceList = $roleInstances; - } - - // Append roles - if ($xmlService->RoleList && $xmlService->RoleList->Role) { - $xmlRoles = $xmlService->RoleList->Role; - if (count($xmlService->RoleList->Role) == 1) { - $xmlRoles = array($xmlService->RoleList->Role); - } - - $roles = array(); - if (!is_null($xmlRoles)) { - for ($i = 0; $i < count($xmlRoles); $i++) { - $roles[] = array( - 'rolename' => (string)$xmlRoles[$i]->RoleName, - 'osversion' => (!is_null($xmlRoles[$i]->OsVersion) ? (string)$xmlRoles[$i]->OsVersion : (string)$xmlRoles[$i]->OperatingSystemVersion) - ); - } - } - $returnValue->RoleList = $roles; - } - - return $returnValue; - } - return null; - } - - /** - * Updates a deployment's role instance count. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string|array $roleName The role name - * @param string|array $instanceCount The instance count - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function setInstanceCountBySlot($serviceName, $deploymentSlot, $roleName, $instanceCount) { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($roleName == '' || is_null($roleName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.'); - } - - // Get configuration - $deployment = $this->getDeploymentBySlot($serviceName, $deploymentSlot); - $configuration = $deployment->Configuration; - $configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration); - - // Update configuration - $this->configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration); - } - - /** - * Updates a deployment's role instance count. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string|array $roleName The role name - * @param string|array $instanceCount The instance count - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function setInstanceCountByDeploymentId($serviceName, $deploymentId, $roleName, $instanceCount) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - if ($roleName == '' || is_null($roleName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.'); - } - - // Get configuration - $deployment = $this->getDeploymentByDeploymentId($serviceName, $deploymentId); - $configuration = $deployment->Configuration; - $configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration); - - // Update configuration - $this->configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration); - } - - /** - * Updates instance count in configuration XML. - * - * @param string|array $roleName The role name - * @param string|array $instanceCount The instance count - * @param string $configuration XML configuration represented as a string - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration) { - // Change variables - if (!is_array($roleName)) { - $roleName = array($roleName); - } - if (!is_array($instanceCount)) { - $instanceCount = array($instanceCount); - } - - $configuration = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $configuration); - //$configuration = '' . substr($configuration, strpos($configuration, '>') + 2); - - $xml = Zend_Xml_Security::scan($configuration); - - // http://www.php.net/manual/en/simplexmlelement.xpath.php#97818 - $namespaces = $xml->getDocNamespaces(); - $xml->registerXPathNamespace('__empty_ns', $namespaces['']); - - for ($i = 0; $i < count($roleName); $i++) { - $elements = $xml->xpath('//__empty_ns:Role[@name="' . $roleName[$i] . '"]/__empty_ns:Instances'); - - if (count($elements) == 1) { - $element = $elements[0]; - $element['count'] = $instanceCount[$i]; - } - } - - $configuration = $xml->asXML(); - //$configuration = preg_replace('/(<\?xml[^?]+?)utf-8/i', '$1utf-16', $configuration); - - return $configuration; - } - - /** - * The Change Deployment Configuration request may be specified as follows. - * Note that you can change a deployment's configuration either by specifying the deployment - * environment (staging or production), or by specifying the deployment's unique name. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $configuration XML configuration represented as a string - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($configuration == '' || is_null($configuration)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.'); - } - - if (@file_exists($configuration)) { - $configuration = utf8_decode(file_get_contents($configuration)); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_configureDeployment($operationUrl, $configuration); - } - - /** - * The Change Deployment Configuration request may be specified as follows. - * Note that you can change a deployment's configuration either by specifying the deployment - * environment (staging or production), or by specifying the deployment's unique name. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param string $configuration XML configuration represented as a string - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - if ($configuration == '' || is_null($configuration)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.'); - } - - if (@file_exists($configuration)) { - $configuration = utf8_decode(file_get_contents($configuration)); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_configureDeployment($operationUrl, $configuration); - } - - /** - * The Change Deployment Configuration request may be specified as follows. - * Note that you can change a deployment's configuration either by specifying the deployment - * environment (staging or production), or by specifying the deployment's unique name. - * - * @param string $operationUrl The operation url - * @param string $configuration XML configuration represented as a string - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _configureDeployment($operationUrl, $configuration) - { - // Clean up the configuration - $conformingConfiguration = $this->_cleanConfiguration($configuration); - - $response = $this->_performRequest($operationUrl . '/', '?comp=config', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . base64_encode($conformingConfiguration) . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Upgrade Deployment operation initiates an upgrade. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $label A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription. - * @param string $packageUrl The service configuration file for the deployment. - * @param string $configuration A label for this deployment, up to 100 characters in length. - * @param string $mode The type of upgrade to initiate. Possible values are Auto or Manual. - * @param string $roleToUpgrade The name of the specific role to upgrade. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function upgradeDeploymentBySlot($serviceName, $deploymentSlot, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if ($packageUrl == '' || is_null($packageUrl)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.'); - } - if ($configuration == '' || is_null($configuration)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.'); - } - $mode = strtolower($mode); - if ($mode != 'auto' && $mode != 'manual') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.'); - } - - if (@file_exists($configuration)) { - $configuration = utf8_decode(file_get_contents($configuration)); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade); - } - - /** - * The Upgrade Deployment operation initiates an upgrade. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param string $label A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription. - * @param string $packageUrl The service configuration file for the deployment. - * @param string $configuration A label for this deployment, up to 100 characters in length. - * @param string $mode The type of upgrade to initiate. Possible values are Auto or Manual. - * @param string $roleToUpgrade The name of the specific role to upgrade. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function upgradeDeploymentByDeploymentId($serviceName, $deploymentId, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if ($packageUrl == '' || is_null($packageUrl)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.'); - } - if ($configuration == '' || is_null($configuration)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.'); - } - $mode = strtolower($mode); - if ($mode != 'auto' && $mode != 'manual') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.'); - } - - if (@file_exists($configuration)) { - $configuration = utf8_decode(file_get_contents($configuration)); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade); - } - - - /** - * The Upgrade Deployment operation initiates an upgrade. - * - * @param string $operationUrl The operation url - * @param string $label A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription. - * @param string $packageUrl The service configuration file for the deployment. - * @param string $configuration A label for this deployment, up to 100 characters in length. - * @param string $mode The type of upgrade to initiate. Possible values are Auto or Manual. - * @param string $roleToUpgrade The name of the specific role to upgrade. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade) - { - // Clean up the configuration - $conformingConfiguration = $this->_cleanConfiguration($configuration); - - $response = $this->_performRequest($operationUrl . '/', '?comp=upgrade', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . ucfirst($mode) . '' . $packageUrl . '' . base64_encode($conformingConfiguration) . '' . (!is_null($roleToUpgrade) ? '' . $roleToUpgrade . '' : '') . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param int $upgradeDomain An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function walkUpgradeDomainBySlot($serviceName, $deploymentSlot, $upgradeDomain = 0) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot; - return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain); - } - - /** - * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param int $upgradeDomain An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function walkUpgradeDomainByDeploymentId($serviceName, $deploymentId, $upgradeDomain = 0) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId; - return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain); - } - - - /** - * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade. - * - * @param string $operationUrl The operation url - * @param int $upgradeDomain An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _walkUpgradeDomain($operationUrl, $upgradeDomain = 0) - { - $response = $this->_performRequest($operationUrl . '/', '?comp=walkupgradedomain', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $upgradeDomain . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Reboot Role Instance operation requests a reboot of a role instance - * that is running in a deployment. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $roleInstanceName The role instance name - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function rebootRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($roleInstanceName == '' || is_null($roleInstanceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName; - return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot'); - } - - /** - * The Reboot Role Instance operation requests a reboot of a role instance - * that is running in a deployment. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param string $roleInstanceName The role instance name - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function rebootRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - if ($roleInstanceName == '' || is_null($roleInstanceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName; - return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot'); - } - - /** - * The Reimage Role Instance operation requests a reimage of a role instance - * that is running in a deployment. - * - * @param string $serviceName The service name - * @param string $deploymentSlot The deployment slot (production or staging) - * @param string $roleInstanceName The role instance name - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function reimageRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - $deploymentSlot = strtolower($deploymentSlot); - if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.'); - } - if ($roleInstanceName == '' || is_null($roleInstanceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName; - return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage'); - } - - /** - * The Reimage Role Instance operation requests a reimage of a role instance - * that is running in a deployment. - * - * @param string $serviceName The service name - * @param string $deploymentId The deployment ID as listed on the Windows Azure management portal - * @param string $roleInstanceName The role instance name - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function reimageRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($deploymentId == '' || is_null($deploymentId)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.'); - } - if ($roleInstanceName == '' || is_null($roleInstanceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName; - return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage'); - } - - /** - * Reboots or reimages a role instance. - * - * @param string $operationUrl The operation url - * @param string $operation The operation (reboot|reimage) - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - protected function _rebootOrReimageRoleInstance($operationUrl, $operation = 'reboot') - { - $response = $this->_performRequest($operationUrl, '?comp=' . $operation, Zend_Http_Client::POST); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List Certificates operation lists all certificates associated with - * the specified hosted service. - * - * @param string $serviceName The service name - * @return array Array of Zend_Service_WindowsAzure_Management_CertificateInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listCertificates($serviceName) - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates'; - $response = $this->_performRequest($operationUrl); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->Certificate) { - return array(); - } - if (count($result->Certificate) > 1) { - $xmlServices = $result->Certificate; - } else { - $xmlServices = array($result->Certificate); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_CertificateInstance( - (string)$xmlServices[$i]->CertificateUrl, - (string)$xmlServices[$i]->Thumbprint, - (string)$xmlServices[$i]->ThumbprintAlgorithm, - (string)$xmlServices[$i]->Data - ); - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Certificate operation returns the public data for the specified certificate. - * - * @param string $serviceName|$certificateUrl The service name -or- the certificate URL - * @param string $algorithm Algorithm - * @param string $thumbprint Thumbprint - * @return Zend_Service_WindowsAzure_Management_CertificateInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getCertificate($serviceName, $algorithm = '', $thumbprint = '') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.'); - } - if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.'); - } - - $operationUrl = str_replace($this->getBaseUrl(), '', $serviceName); - if (strpos($serviceName, 'https') === false) { - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint); - } - - $response = $this->_performRequest($operationUrl); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - return new Zend_Service_WindowsAzure_Management_CertificateInstance( - $this->getBaseUrl() . $operationUrl, - $algorithm, - $thumbprint, - (string)$result->Data - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Add Certificate operation adds a certificate to the subscription. - * - * @param string $serviceName The service name - * @param string $certificateData Certificate data - * @param string $certificatePassword The certificate password - * @param string $certificateFormat The certificate format. Currently, only 'pfx' is supported. - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function addCertificate($serviceName, $certificateData, $certificatePassword, $certificateFormat = 'pfx') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.'); - } - if ($certificateData == '' || is_null($certificateData)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Certificate data should be specified.'); - } - if ($certificatePassword == '' || is_null($certificatePassword)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Certificate password should be specified.'); - } - if ($certificateFormat != 'pfx') { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Certificate format should be "pfx".'); - } - - if (@file_exists($certificateData)) { - $certificateData = file_get_contents($certificateData); - } - - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates'; - $response = $this->_performRequest($operationUrl, '', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . base64_encode($certificateData) . '' . $certificateFormat . '' . $certificatePassword . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Delete Certificate operation deletes a certificate from the subscription's certificate store. - * - * @param string $serviceName|$certificateUrl The service name -or- the certificate URL - * @param string $algorithm Algorithm - * @param string $thumbprint Thumbprint - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function deleteCertificate($serviceName, $algorithm = '', $thumbprint = '') - { - if ($serviceName == '' || is_null($serviceName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.'); - } - if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.'); - } - - $operationUrl = str_replace($this->getBaseUrl(), '', $serviceName); - if (strpos($serviceName, 'https') === false) { - $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint); - } - - $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List Affinity Groups operation lists the affinity groups associated with - * the specified subscription. - * - * @return array Array of Zend_Service_WindowsAzure_Management_AffinityGroupInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listAffinityGroups() - { - $response = $this->_performRequest(self::OP_AFFINITYGROUPS); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->AffinityGroup) { - return array(); - } - if (count($result->AffinityGroup) > 1) { - $xmlServices = $result->AffinityGroup; - } else { - $xmlServices = array($result->AffinityGroup); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance( - (string)$xmlServices[$i]->Name, - (string)$xmlServices[$i]->Label, - (string)$xmlServices[$i]->Description, - (string)$xmlServices[$i]->Location - ); - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Create Affinity Group operation creates a new affinity group for the specified subscription. - * - * @param string $name A name for the affinity group that is unique to the subscription. - * @param string $label A label for the affinity group. The label may be up to 100 characters in length. - * @param string $description A description for the affinity group. The description may be up to 1024 characters in length. - * @param string $location The location where the affinity group will be created. To list available locations, use the List Locations operation. - */ - public function createAffinityGroup($name, $label, $description = '', $location = '') - { - if ($name == '' || is_null($name)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if (strlen($description) > 1024) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.'); - } - if ($location == '' || is_null($location)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Location should be specified.'); - } - - $response = $this->_performRequest(self::OP_AFFINITYGROUPS, '', - Zend_Http_Client::POST, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $name . '' . $description . '' . $location . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Update Affinity Group operation updates the label and/or the description for an affinity group for the specified subscription. - * - * @param string $name The name for the affinity group that should be updated. - * @param string $label A label for the affinity group. The label may be up to 100 characters in length. - * @param string $description A description for the affinity group. The description may be up to 1024 characters in length. - */ - public function updateAffinityGroup($name, $label, $description = '') - { - if ($name == '' || is_null($name)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.'); - } - if ($label == '' || is_null($label)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.'); - } - if (strlen($label) > 100) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.'); - } - if (strlen($description) > 1024) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.'); - } - - $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '', - Zend_Http_Client::PUT, - array('Content-Type' => 'application/xml; charset=utf-8'), - '' . $description . ''); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Delete Affinity Group operation deletes an affinity group in the specified subscription. - * - * @param string $name The name for the affinity group that should be deleted. - */ - public function deleteAffinityGroup($name) - { - if ($name == '' || is_null($name)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.'); - } - - $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '', - Zend_Http_Client::DELETE); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The Get Affinity Group Properties operation returns the - * system properties associated with the specified affinity group. - * - * @param string $affinityGroupName The affinity group name. - * @return Zend_Service_WindowsAzure_Management_AffinityGroupInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function getAffinityGroupProperties($affinityGroupName) - { - if ($affinityGroupName == '' || is_null($affinityGroupName)) { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.'); - } - - $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $affinityGroupName); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - $affinityGroup = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance( - $affinityGroupName, - (string)$result->Label, - (string)$result->Description, - (string)$result->Location - ); - - // Hosted services - if (count($result->HostedServices->HostedService) > 1) { - $xmlService = $result->HostedServices->HostedService; - } else { - $xmlService = array($result->HostedServices->HostedService); - } - - $services = array(); - if (!is_null($xmlService)) { - for ($i = 0; $i < count($xmlService); $i++) { - $services[] = array( - 'url' => (string)$xmlService[$i]->Url, - 'name' => (string)$xmlService[$i]->ServiceName - ); - } - } - $affinityGroup->HostedServices = $services; - - // Storage services - if (count($result->StorageServices->StorageService) > 1) { - $xmlService = $result->StorageServices->StorageService; - } else { - $xmlService = array($result->StorageServices->StorageService); - } - - $services = array(); - if (!is_null($xmlService)) { - for ($i = 0; $i < count($xmlService); $i++) { - $services[] = array( - 'url' => (string)$xmlService[$i]->Url, - 'name' => (string)$xmlService[$i]->ServiceName - ); - } - } - $affinityGroup->StorageServices = $services; - - return $affinityGroup; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List Locations operation lists all of the data center locations - * that are valid for your subscription. - * - * @return array Array of Zend_Service_WindowsAzure_Management_LocationInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listLocations() - { - $response = $this->_performRequest(self::OP_LOCATIONS); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->Location) { - return array(); - } - if (count($result->Location) > 1) { - $xmlServices = $result->Location; - } else { - $xmlServices = array($result->Location); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_LocationInstance( - (string)$xmlServices[$i]->Name - ); - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List Operating Systems operation lists the versions of the guest operating system - * that are currently available in Windows Azure. The 2010-10-28 version of List Operating - * Systems also indicates what family an operating system version belongs to. - * Currently Windows Azure supports two operating system families: the Windows Azure guest - * operating system that is substantially compatible with Windows Server 2008 SP2, - * and the Windows Azure guest operating system that is substantially compatible with - * Windows Server 2008 R2. - * - * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listOperatingSystems() - { - $response = $this->_performRequest(self::OP_OPERATINGSYSTEMS); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->OperatingSystem) { - return array(); - } - if (count($result->OperatingSystem) > 1) { - $xmlServices = $result->OperatingSystem; - } else { - $xmlServices = array($result->OperatingSystem); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance( - (string)$xmlServices[$i]->Version, - (string)$xmlServices[$i]->Label, - ((string)$xmlServices[$i]->IsDefault == 'true'), - ((string)$xmlServices[$i]->IsActive == 'true'), - (string)$xmlServices[$i]->Family, - (string)$xmlServices[$i]->FamilyLabel - ); - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * The List OS Families operation lists the guest operating system families - * available in Windows Azure, and also lists the operating system versions - * available for each family. Currently Windows Azure supports two operating - * system families: the Windows Azure guest operating system that is - * substantially compatible with Windows Server 2008 SP2, and the Windows - * Azure guest operating system that is substantially compatible with - * Windows Server 2008 R2. - * - * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance - * @throws Zend_Service_WindowsAzure_Management_Exception - */ - public function listOperatingSystemFamilies() - { - $response = $this->_performRequest(self::OP_OPERATINGSYSTEMFAMILIES); - - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - - if (!$result->OperatingSystemFamily) { - return array(); - } - if (count($result->OperatingSystemFamily) > 1) { - $xmlServices = $result->OperatingSystemFamily; - } else { - $xmlServices = array($result->OperatingSystemFamily); - } - - $services = array(); - if (!is_null($xmlServices)) { - - for ($i = 0; $i < count($xmlServices); $i++) { - $services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance( - (string)$xmlServices[$i]->Name, - (string)$xmlServices[$i]->Label - ); - - if (count($xmlServices[$i]->OperatingSystems->OperatingSystem) > 1) { - $xmlOperatingSystems = $xmlServices[$i]->OperatingSystems->OperatingSystem; - } else { - $xmlOperatingSystems = array($xmlServices[$i]->OperatingSystems->OperatingSystem); - } - - $operatingSystems = array(); - if (!is_null($xmlOperatingSystems)) { - #require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php'; - for ($i = 0; $i < count($xmlOperatingSystems); $i++) { - $operatingSystems[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance( - (string)$xmlOperatingSystems[$i]->Version, - (string)$xmlOperatingSystems[$i]->Label, - ((string)$xmlOperatingSystems[$i]->IsDefault == 'true'), - ((string)$xmlOperatingSystems[$i]->IsActive == 'true'), - (string)$xmlServices[$i]->Name, - (string)$xmlServices[$i]->Label - ); - } - } - $services[ count($services) - 1 ]->OperatingSystems = $operatingSystems; - } - } - return $services; - } else { - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Clean configuration - * - * @param string $configuration Configuration to clean. - * @return string - */ - public function _cleanConfiguration($configuration) { - $configuration = str_replace('?_data = array( - 'name' => $name, - 'deploymentslot' => $deploymentSlot, - 'privateid' => $privateID, - 'label' => base64_decode($label), - 'url' => $url, - 'configuration' => base64_decode($configuration), - 'status' => $status, - 'upgradestatus' => $upgradeStatus, - 'upgradetype' => $upgradeType, - 'currentupgradedomainstate' => $currentUpgradeDomainState, - 'currentupgradedomain' => $currentUpgradeDomain, - 'upgradedomaincount' => $upgradeDomainCount, - 'roleinstancelist' => $roleInstanceList, - 'rolelist' => $roleList - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/Exception.php b/lib/Zend/Service/WindowsAzure/Management/Exception.php deleted file mode 100644 index fc389b84249..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -_data = array( - 'url' => $url, - 'servicename' => $serviceName, - 'description' => $description, - 'affinitygroup' => $affinityGroup, - 'location' => $location, - 'label' => base64_decode($label), - 'deployments' => $deployments - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/LocationInstance.php b/lib/Zend/Service/WindowsAzure/Management/LocationInstance.php deleted file mode 100644 index e2554fd8bed..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/LocationInstance.php +++ /dev/null @@ -1,51 +0,0 @@ -_data = array( - 'name' => $name - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php b/lib/Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php deleted file mode 100644 index 4f91e3c3c4d..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php +++ /dev/null @@ -1,57 +0,0 @@ -_data = array( - 'name' => $name, - 'label' => base64_decode($label), - 'operatingsystems' => $operatingSystems - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php b/lib/Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php deleted file mode 100644 index 41be13ceb18..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php +++ /dev/null @@ -1,66 +0,0 @@ -_data = array( - 'version' => $version, - 'label' => base64_decode($label), - 'isdefault' => $isDefault, - 'isactive' => $isActive, - 'family' => $family, - 'familylabel' => base64_decode($familyLabel) - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/OperationStatusInstance.php b/lib/Zend/Service/WindowsAzure/Management/OperationStatusInstance.php deleted file mode 100644 index 76bf45c91db..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/OperationStatusInstance.php +++ /dev/null @@ -1,60 +0,0 @@ -_data = array( - 'id' => $id, - 'status' => $status, - 'errorcode' => $errorCode, - 'errormessage' => $errorMessage - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/ServiceEntityAbstract.php b/lib/Zend/Service/WindowsAzure/Management/ServiceEntityAbstract.php deleted file mode 100644 index 985ea069c16..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/ServiceEntityAbstract.php +++ /dev/null @@ -1,67 +0,0 @@ -_data)) { - $this->_data[strtolower($name)] = $value; - return; - } - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception("Unknown property: " . $name); - } - - /** - * Magic overload for getting properties - * - * @param string $name Name of the property - */ - public function __get($name) { - if (array_key_exists(strtolower($name), $this->_data)) { - return $this->_data[strtolower($name)]; - } - #require_once 'Zend/Service/WindowsAzure/Management/Exception.php'; - throw new Zend_Service_WindowsAzure_Management_Exception("Unknown property: " . $name); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/StorageServiceInstance.php b/lib/Zend/Service/WindowsAzure/Management/StorageServiceInstance.php deleted file mode 100644 index e0f8106f6d6..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/StorageServiceInstance.php +++ /dev/null @@ -1,66 +0,0 @@ -_data = array( - 'url' => $url, - 'servicename' => $serviceName, - 'description' => $description, - 'affinitygroup' => $affinityGroup, - 'location' => $location, - 'label' => base64_decode($label) - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php b/lib/Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php deleted file mode 100644 index eda0b72b080..00000000000 --- a/lib/Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php +++ /dev/null @@ -1,77 +0,0 @@ -_data = array( - 'operationid' => $operationId, - 'operationobjectid' => $operationObjectId, - 'operationname' => $operationName, - 'operationparameters' => $operationParameters, - 'operationcaller' => $operationCaller, - 'operationstatus' => $operationStatus - ); - } - - /** - * Add operation parameter - * - * @param string $name Name - * @param string $value Value - */ - public function addOperationParameter($name, $value) - { - $this->_data['operationparameters'][$name] = $value; - } -} diff --git a/lib/Zend/Service/WindowsAzure/RetryPolicy/Exception.php b/lib/Zend/Service/WindowsAzure/RetryPolicy/Exception.php deleted file mode 100644 index 01d53ada628..00000000000 --- a/lib/Zend/Service/WindowsAzure/RetryPolicy/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -_retryCount = $count; - $this->_retryInterval = $intervalBetweenRetries; - } - - /** - * Execute function under retry policy - * - * @param string|array $function Function to execute - * @param array $parameters Parameters for function call - * @return mixed - */ - public function execute($function, $parameters = array()) - { - $returnValue = null; - - for ($retriesLeft = $this->_retryCount; $retriesLeft >= 0; --$retriesLeft) { - try { - $returnValue = call_user_func_array($function, $parameters); - return $returnValue; - } catch (Exception $ex) { - if ($retriesLeft == 1) { - #require_once 'Zend/Service/WindowsAzure/RetryPolicy/Exception.php'; - throw new Zend_Service_WindowsAzure_RetryPolicy_Exception("Exceeded retry count of " . $this->_retryCount . ". " . $ex->getMessage()); - } - - usleep($this->_retryInterval * 1000); - } - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php b/lib/Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php deleted file mode 100644 index 8018946c901..00000000000 --- a/lib/Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php +++ /dev/null @@ -1,72 +0,0 @@ -_storage = $storage; - $this->_storageType = $storageType; - $this->_sessionContainer = $sessionContainer; - $this->_sessionContainerPartition = $sessionContainerPartition; - } - - /** - * Registers the current session handler as PHP's session handler - * - * @return boolean - */ - public function register() - { - return session_set_save_handler(array($this, 'open'), - array($this, 'close'), - array($this, 'read'), - array($this, 'write'), - array($this, 'destroy'), - array($this, 'gc') - ); - } - - /** - * Open the session store - * - * @return bool - */ - public function open() - { - // Make sure storage container exists - if ($this->_storageType == self::STORAGE_TYPE_TABLE) { - $this->_storage->createTableIfNotExists($this->_sessionContainer); - } else if ($this->_storageType == self::STORAGE_TYPE_BLOB) { - $this->_storage->createContainerIfNotExists($this->_sessionContainer); - } - - // Ok! - return true; - } - - /** - * Close the session store - * - * @return bool - */ - public function close() - { - return true; - } - - /** - * Read a specific session - * - * @param int $id Session Id - * @return string - */ - public function read($id) - { - // Read data - if ($this->_storageType == self::STORAGE_TYPE_TABLE) { - // In table storage - try - { - $sessionRecord = $this->_storage->retrieveEntityById( - $this->_sessionContainer, - $this->_sessionContainerPartition, - $id - ); - return unserialize(base64_decode($sessionRecord->serializedData)); - } - catch (Zend_Service_WindowsAzure_Exception $ex) - { - return ''; - } - } else if ($this->_storageType == self::STORAGE_TYPE_BLOB) { - // In blob storage - try - { - $data = $this->_storage->getBlobData( - $this->_sessionContainer, - $this->_sessionContainerPartition . '/' . $id - ); - return unserialize(base64_decode($data)); - } - catch (Zend_Service_WindowsAzure_Exception $ex) - { - return false; - } - } - } - - /** - * Write a specific session - * - * @param int $id Session Id - * @param string $serializedData Serialized PHP object - * @throws Exception - */ - public function write($id, $serializedData) - { - // Encode data - $serializedData = base64_encode(serialize($serializedData)); - if (strlen($serializedData) >= self::MAX_TS_PROPERTY_SIZE && $this->_storageType == self::STORAGE_TYPE_TABLE) { - throw new Zend_Service_WindowsAzure_Exception('Session data exceeds the maximum allowed size of ' . self::MAX_TS_PROPERTY_SIZE . ' bytes that can be stored using table storage. Consider switching to a blob storage back-end or try reducing session data size.'); - } - - // Store data - if ($this->_storageType == self::STORAGE_TYPE_TABLE) { - // In table storage - $sessionRecord = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($this->_sessionContainerPartition, $id); - $sessionRecord->sessionExpires = time(); - $sessionRecord->serializedData = $serializedData; - - $sessionRecord->setAzurePropertyType('sessionExpires', 'Edm.Int32'); - - try - { - $this->_storage->updateEntity($this->_sessionContainer, $sessionRecord); - } - catch (Zend_Service_WindowsAzure_Exception $unknownRecord) - { - $this->_storage->insertEntity($this->_sessionContainer, $sessionRecord); - } - } else if ($this->_storageType == self::STORAGE_TYPE_BLOB) { - // In blob storage - $this->_storage->putBlobData( - $this->_sessionContainer, - $this->_sessionContainerPartition . '/' . $id, - $serializedData, - array('sessionexpires' => time()) - ); - } - } - - /** - * Destroy a specific session - * - * @param int $id Session Id - * @return boolean - */ - public function destroy($id) - { - // Destroy data - if ($this->_storageType == self::STORAGE_TYPE_TABLE) { - // In table storage - try - { - $sessionRecord = $this->_storage->retrieveEntityById( - $this->_sessionContainer, - $this->_sessionContainerPartition, - $id - ); - $this->_storage->deleteEntity($this->_sessionContainer, $sessionRecord); - - return true; - } - catch (Zend_Service_WindowsAzure_Exception $ex) - { - return false; - } - } else if ($this->_storageType == self::STORAGE_TYPE_BLOB) { - // In blob storage - try - { - $this->_storage->deleteBlob( - $this->_sessionContainer, - $this->_sessionContainerPartition . '/' . $id - ); - - return true; - } - catch (Zend_Service_WindowsAzure_Exception $ex) - { - return false; - } - } - } - - /** - * Garbage collector - * - * @param int $lifeTime Session maximal lifetime - * @see session.gc_divisor 100 - * @see session.gc_maxlifetime 1440 - * @see session.gc_probability 1 - * @usage Execution rate 1/100 (session.gc_probability/session.gc_divisor) - * @return boolean - */ - public function gc($lifeTime) - { - if ($this->_storageType == self::STORAGE_TYPE_TABLE) { - // In table storage - try - { - $result = $this->_storage->retrieveEntities($this->_sessionContainer, 'PartitionKey eq \'' . $this->_sessionContainerPartition . '\' and sessionExpires lt ' . (time() - $lifeTime)); - foreach ($result as $sessionRecord) - { - $this->_storage->deleteEntity($this->_sessionContainer, $sessionRecord); - } - return true; - } - catch (Zend_Service_WindowsAzure_exception $ex) - { - return false; - } - } else if ($this->_storageType == self::STORAGE_TYPE_BLOB) { - // In blob storage - try - { - $result = $this->_storage->listBlobs($this->_sessionContainer, $this->_sessionContainerPartition, '', null, null, 'metadata'); - foreach ($result as $sessionRecord) - { - if ($sessionRecord->Metadata['sessionexpires'] < (time() - $lifeTime)) { - $this->_storage->deleteBlob($this->_sessionContainer, $sessionRecord->Name); - } - } - return true; - } - catch (Zend_Service_WindowsAzure_exception $ex) - { - return false; - } - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage.php b/lib/Zend/Service/WindowsAzure/Storage.php deleted file mode 100644 index d486abd8d35..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage.php +++ /dev/null @@ -1,564 +0,0 @@ -_host = $host; - $this->_accountName = $accountName; - $this->_accountKey = $accountKey; - $this->_usePathStyleUri = $usePathStyleUri; - - // Using local storage? - if (!$this->_usePathStyleUri - && ($this->_host == self::URL_DEV_BLOB - || $this->_host == self::URL_DEV_QUEUE - || $this->_host == self::URL_DEV_TABLE) - ) { - // Local storage - $this->_usePathStyleUri = true; - } - - if (is_null($this->_credentials)) { - $this->_credentials = new Zend_Service_WindowsAzure_Credentials_SharedKey( - $this->_accountName, $this->_accountKey, $this->_usePathStyleUri); - } - - $this->_retryPolicy = $retryPolicy; - if (is_null($this->_retryPolicy)) { - $this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry(); - } - - // Setup default Zend_Http_Client channel - $options = array( - 'adapter' => 'Zend_Http_Client_Adapter_Proxy' - ); - if (function_exists('curl_init')) { - // Set cURL options if cURL is used afterwards - $options['curloptions'] = array( - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_TIMEOUT => 120, - ); - } - $this->_httpClientChannel = new Zend_Http_Client(null, $options); - } - - /** - * Set the HTTP client channel to use - * - * @param Zend_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name. - */ - public function setHttpClientChannel($adapterInstance = 'Zend_Http_Client_Adapter_Proxy') - { - $this->_httpClientChannel->setAdapter($adapterInstance); - } - - /** - * Retrieve HTTP client channel - * - * @return Zend_Http_Client_Adapter_Interface - */ - public function getHttpClientChannel() - { - return $this->_httpClientChannel; - } - - /** - * Set retry policy to use when making requests - * - * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests - */ - public function setRetryPolicy(Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) - { - $this->_retryPolicy = $retryPolicy; - if (is_null($this->_retryPolicy)) { - $this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry(); - } - } - - /** - * Set proxy - * - * @param boolean $useProxy Use proxy? - * @param string $proxyUrl Proxy URL - * @param int $proxyPort Proxy port - * @param string $proxyCredentials Proxy credentials - */ - public function setProxy($useProxy = false, $proxyUrl = '', $proxyPort = 80, $proxyCredentials = '') - { - $this->_useProxy = $useProxy; - $this->_proxyUrl = $proxyUrl; - $this->_proxyPort = $proxyPort; - $this->_proxyCredentials = $proxyCredentials; - - if ($this->_useProxy) { - $credentials = explode(':', $this->_proxyCredentials); - - $this->_httpClientChannel->setConfig(array( - 'proxy_host' => $this->_proxyUrl, - 'proxy_port' => $this->_proxyPort, - 'proxy_user' => $credentials[0], - 'proxy_pass' => $credentials[1], - )); - } else { - $this->_httpClientChannel->setConfig(array( - 'proxy_host' => '', - 'proxy_port' => 8080, - 'proxy_user' => '', - 'proxy_pass' => '', - )); - } - } - - /** - * Returns the Windows Azure account name - * - * @return string - */ - public function getAccountName() - { - return $this->_accountName; - } - - /** - * Get base URL for creating requests - * - * @return string - */ - public function getBaseUrl() - { - if ($this->_usePathStyleUri) { - return 'http://' . $this->_host . '/' . $this->_accountName; - } else { - return 'http://' . $this->_accountName . '.' . $this->_host; - } - } - - /** - * Set Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance - * - * @param Zend_Service_WindowsAzure_Credentials_CredentialsAbstract $credentials Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance to use for request signing. - */ - public function setCredentials(Zend_Service_WindowsAzure_Credentials_CredentialsAbstract $credentials) - { - $this->_credentials = $credentials; - $this->_credentials->setAccountName($this->_accountName); - $this->_credentials->setAccountkey($this->_accountKey); - $this->_credentials->setUsePathStyleUri($this->_usePathStyleUri); - } - - /** - * Get Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance - * - * @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract - */ - public function getCredentials() - { - return $this->_credentials; - } - - /** - * Perform request using Zend_Http_Client channel - * - * @param string $path Path - * @param string $queryString Query string - * @param string $httpVerb HTTP verb the request will use - * @param array $headers x-ms headers to add - * @param boolean $forTableStorage Is the request for table storage? - * @param mixed $rawData Optional RAW HTTP data to be sent over the wire - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return Zend_Http_Response - */ - protected function _performRequest( - $path = '/', - $queryString = '', - $httpVerb = Zend_Http_Client::GET, - $headers = array(), - $forTableStorage = false, - $rawData = null, - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ - ) { - // Clean path - if (strpos($path, '/') !== 0) { - $path = '/' . $path; - } - - // Clean headers - if (is_null($headers)) { - $headers = array(); - } - - // Ensure cUrl will also work correctly: - // - disable Content-Type if required - // - disable Expect: 100 Continue - if (!isset($headers["Content-Type"])) { - $headers["Content-Type"] = ''; - } - $headers["Expect"]= ''; - - // Add version header - $headers['x-ms-version'] = $this->_apiVersion; - - // URL encoding - $path = self::urlencode($path); - $queryString = self::urlencode($queryString); - - // Generate URL and sign request - $requestUrl = $this->_credentials - ->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission); - $requestHeaders = $this->_credentials - ->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission, $rawData); - - // Prepare request - $this->_httpClientChannel->resetParameters(true); - $this->_httpClientChannel->setUri($requestUrl); - $this->_httpClientChannel->setHeaders($requestHeaders); - $this->_httpClientChannel->setRawData($rawData); - - // Execute request - $response = $this->_retryPolicy->execute( - array($this->_httpClientChannel, 'request'), - array($httpVerb) - ); - - return $response; - } - - /** - * Parse result from Zend_Http_Response - * - * @param Zend_Http_Response $response Response from HTTP call - * @return object - * @throws Zend_Service_WindowsAzure_Exception - */ - protected function _parseResponse(Zend_Http_Response $response = null) - { - if (is_null($response)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Response should not be null.'); - } - - $xml = Zend_Xml_Security::scan($response->getBody()); - - if ($xml !== false) { - // Fetch all namespaces - $namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true)); - - // Register all namespace prefixes - foreach ($namespaces as $prefix => $ns) { - if ($prefix != '') { - $xml->registerXPathNamespace($prefix, $ns); - } - } - } - - return $xml; - } - - /** - * Generate metadata headers - * - * @param array $metadata - * @return HTTP headers containing metadata - */ - protected function _generateMetadataHeaders($metadata = array()) - { - // Validate - if (!is_array($metadata)) { - return array(); - } - - // Return headers - $headers = array(); - foreach ($metadata as $key => $value) { - if (strpos($value, "\r") !== false || strpos($value, "\n") !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Metadata cannot contain newline characters.'); - } - - if (!self::isValidMetadataName($key)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Metadata name does not adhere to metadata naming conventions. See http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx for more information.'); - } - - $headers["x-ms-meta-" . strtolower($key)] = $value; - } - return $headers; - } - - /** - * Parse metadata headers - * - * @param array $headers HTTP headers containing metadata - * @return array - */ - protected function _parseMetadataHeaders($headers = array()) - { - // Validate - if (!is_array($headers)) { - return array(); - } - - // Return metadata - $metadata = array(); - foreach ($headers as $key => $value) { - if (substr(strtolower($key), 0, 10) == "x-ms-meta-") { - $metadata[str_replace("x-ms-meta-", '', strtolower($key))] = $value; - } - } - return $metadata; - } - - /** - * Parse metadata XML - * - * @param SimpleXMLElement $parentElement Element containing the Metadata element. - * @return array - */ - protected function _parseMetadataElement($element = null) - { - // Metadata present? - if (!is_null($element) && isset($element->Metadata) && !is_null($element->Metadata)) { - return get_object_vars($element->Metadata); - } - - return array(); - } - - /** - * Generate ISO 8601 compliant date string in UTC time zone - * - * @param int $timestamp - * @return string - */ - public function isoDate($timestamp = null) - { - $tz = @date_default_timezone_get(); - @date_default_timezone_set('UTC'); - - if (is_null($timestamp)) { - $timestamp = time(); - } - - $returnValue = str_replace('+00:00', '.0000000Z', @date('c', $timestamp)); - @date_default_timezone_set($tz); - return $returnValue; - } - - /** - * URL encode function - * - * @param string $value Value to encode - * @return string Encoded value - */ - public static function urlencode($value) - { - return str_replace(' ', '%20', $value); - } - - /** - * Is valid metadata name? - * - * @param string $metadataName Metadata name - * @return boolean - */ - public static function isValidMetadataName($metadataName = '') - { - if (preg_match("/^[a-zA-Z0-9_@][a-zA-Z0-9_]*$/", $metadataName) === 0) { - return false; - } - - if ($metadataName == '') { - return false; - } - - return true; - } - - /** - * Builds a query string from an array of elements - * - * @param array Array of elements - * @return string Assembled query string - */ - public static function createQueryStringFromArray($queryString) - { - return count($queryString) > 0 ? '?' . implode('&', $queryString) : ''; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/Batch.php b/lib/Zend/Service/WindowsAzure/Storage/Batch.php deleted file mode 100644 index 47f5df4bc4b..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/Batch.php +++ /dev/null @@ -1,241 +0,0 @@ -_storageClient = $storageClient; - $this->_baseUrl = $baseUrl; - $this->_beginBatch(); - } - - /** - * Get base URL for creating requests - * - * @return string - */ - public function getBaseUrl() - { - return $this->_baseUrl; - } - - /** - * Starts a new batch operation set - * - * @throws Zend_Service_WindowsAzure_Exception - */ - protected function _beginBatch() - { - $this->_storageClient->setCurrentBatch($this); - } - - /** - * Cleanup current batch - */ - protected function _clean() - { - unset($this->_operations); - $this->_storageClient->setCurrentBatch(null); - $this->_storageClient = null; - //unset($this); //removing $this is not possible - } - - /** - * Enlist operation in current batch - * - * @param string $path Path - * @param string $queryString Query string - * @param string $httpVerb HTTP verb the request will use - * @param array $headers x-ms headers to add - * @param boolean $forTableStorage Is the request for table storage? - * @param mixed $rawData Optional RAW HTTP data to be sent over the wire - * @throws Zend_Service_WindowsAzure_Exception - */ - public function enlistOperation($path = '/', $queryString = '', $httpVerb = Zend_Http_Client::GET, $headers = array(), $forTableStorage = false, $rawData = null) - { - // Set _forTableStorage - if ($forTableStorage) { - $this->_forTableStorage = true; - } - - // Set _isSingleSelect - if ($httpVerb == Zend_Http_Client::GET) { - if (count($this->_operations) > 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception("Select operations can only be performed in an empty batch transaction."); - } - $this->_isSingleSelect = true; - } - - // Clean path - if (strpos($path, '/') !== 0) { - $path = '/' . $path; - } - - // Clean headers - if (is_null($headers)) { - $headers = array(); - } - - // URL encoding - $path = Zend_Service_WindowsAzure_Storage::urlencode($path); - $queryString = Zend_Service_WindowsAzure_Storage::urlencode($queryString); - - // Generate URL - $requestUrl = $this->getBaseUrl() . $path . $queryString; - - // Generate $rawData - if (is_null($rawData)) { - $rawData = ''; - } - - // Add headers - if ($httpVerb != Zend_Http_Client::GET) { - $headers['Content-ID'] = count($this->_operations) + 1; - if ($httpVerb != Zend_Http_Client::DELETE) { - $headers['Content-Type'] = 'application/atom+xml;type=entry'; - } - $headers['Content-Length'] = strlen($rawData); - } - - // Generate $operation - $operation = ''; - $operation .= $httpVerb . ' ' . $requestUrl . ' HTTP/1.1' . "\n"; - foreach ($headers as $key => $value) - { - $operation .= $key . ': ' . $value . "\n"; - } - $operation .= "\n"; - - // Add data - $operation .= $rawData; - - // Store operation - $this->_operations[] = $operation; - } - - /** - * Commit current batch - * - * @return Zend_Http_Response - * @throws Zend_Service_WindowsAzure_Exception - */ - public function commit() - { - // Perform batch - $response = $this->_storageClient->performBatch($this->_operations, $this->_forTableStorage, $this->_isSingleSelect); - - // Dispose - $this->_clean(); - - // Parse response - $errors = null; - preg_match_all('/(.*)<\/message>/', $response->getBody(), $errors); - - // Error? - if (count($errors[2]) > 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('An error has occured while committing a batch: ' . $errors[2][0]); - } - - // Return - return $response; - } - - /** - * Rollback current batch - */ - public function rollback() - { - // Dispose - $this->_clean(); - } - - /** - * Get operation count - * - * @return integer - */ - public function getOperationCount() - { - return count($this->_operations); - } - - /** - * Is single select? - * - * @return boolean - */ - public function isSingleSelect() - { - return $this->_isSingleSelect; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php b/lib/Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php deleted file mode 100644 index a849b736dbf..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php +++ /dev/null @@ -1,174 +0,0 @@ -isInBatch()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Only one batch can be active at a time.'); - } - $this->_currentBatch = $batch; - } - - /** - * Get current batch - * - * @return Zend_Service_WindowsAzure_Storage_Batch - */ - public function getCurrentBatch() - { - return $this->_currentBatch; - } - - /** - * Is there a current batch? - * - * @return boolean - */ - public function isInBatch() - { - return !is_null($this->_currentBatch); - } - - /** - * Starts a new batch operation set - * - * @return Zend_Service_WindowsAzure_Storage_Batch - * @throws Zend_Service_WindowsAzure_Exception - */ - public function startBatch() - { - #require_once 'Zend/Service/WindowsAzure/Storage/Batch.php'; - return new Zend_Service_WindowsAzure_Storage_Batch($this, $this->getBaseUrl()); - } - - /** - * Perform batch using Zend_Http_Client channel, combining all batch operations into one request - * - * @param array $operations Operations in batch - * @param boolean $forTableStorage Is the request for table storage? - * @param boolean $isSingleSelect Is the request a single select statement? - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return Zend_Http_Response - */ - public function performBatch($operations = array(), $forTableStorage = false, $isSingleSelect = false, $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ) - { - // Generate boundaries - $batchBoundary = 'batch_' . md5(time() . microtime()); - $changesetBoundary = 'changeset_' . md5(time() . microtime()); - - // Set headers - $headers = array(); - - // Add version header - $headers['x-ms-version'] = $this->_apiVersion; - - // Add dataservice headers - $headers['DataServiceVersion'] = '1.0;NetFx'; - $headers['MaxDataServiceVersion'] = '1.0;NetFx'; - - // Add content-type header - $headers['Content-Type'] = 'multipart/mixed; boundary=' . $batchBoundary; - - // Set path and query string - $path = '/$batch'; - $queryString = ''; - - // Set verb - $httpVerb = Zend_Http_Client::POST; - - // Generate raw data - $rawData = ''; - - // Single select? - if ($isSingleSelect) { - $operation = $operations[0]; - $rawData .= '--' . $batchBoundary . "\n"; - $rawData .= 'Content-Type: application/http' . "\n"; - $rawData .= 'Content-Transfer-Encoding: binary' . "\n\n"; - $rawData .= $operation; - $rawData .= '--' . $batchBoundary . '--'; - } else { - $rawData .= '--' . $batchBoundary . "\n"; - $rawData .= 'Content-Type: multipart/mixed; boundary=' . $changesetBoundary . "\n\n"; - - // Add operations - foreach ($operations as $operation) - { - $rawData .= '--' . $changesetBoundary . "\n"; - $rawData .= 'Content-Type: application/http' . "\n"; - $rawData .= 'Content-Transfer-Encoding: binary' . "\n\n"; - $rawData .= $operation; - } - $rawData .= '--' . $changesetBoundary . '--' . "\n"; - - $rawData .= '--' . $batchBoundary . '--'; - } - - // Generate URL and sign request - $requestUrl = $this->_credentials->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission); - $requestHeaders = $this->_credentials->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission); - - // Prepare request - $this->_httpClientChannel->resetParameters(true); - $this->_httpClientChannel->setUri($requestUrl); - $this->_httpClientChannel->setHeaders($requestHeaders); - $this->_httpClientChannel->setRawData($rawData); - - // Execute request - $response = $this->_retryPolicy->execute( - array($this->_httpClientChannel, 'request'), - array($httpVerb) - ); - - return $response; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/Blob.php b/lib/Zend/Service/WindowsAzure/Storage/Blob.php deleted file mode 100644 index ae867e8619c..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/Blob.php +++ /dev/null @@ -1,2142 +0,0 @@ -_apiVersion = '2009-09-19'; - - // SharedAccessSignature credentials - $this->_sharedAccessSignatureCredentials = new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature($accountName, $accountKey, $usePathStyleUri); - } - - /** - * Check if a blob exists - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @return boolean - */ - public function blobExists($containerName = '', $blobName = '', $snapshotId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - - // Get blob instance - try { - $this->getBlobInstance($containerName, $blobName, $snapshotId); - } catch (Zend_Service_WindowsAzure_Exception $e) { - return false; - } - - return true; - } - - /** - * Check if a container exists - * - * @param string $containerName Container name - * @return boolean - */ - public function containerExists($containerName = '') - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // List containers - $containers = $this->listContainers($containerName, 1); - foreach ($containers as $container) { - if ($container->Name == $containerName) { - return true; - } - } - - return false; - } - - /** - * Create container - * - * @param string $containerName Container name - * @param array $metadata Key/value pairs of meta data - * @return object Container properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createContainer($containerName = '', $metadata = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if (!is_array($metadata)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); - } - - // Create metadata headers - $headers = array(); - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - - return new Zend_Service_WindowsAzure_Storage_BlobContainer( - $containerName, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Create container if it does not exist - * - * @param string $containerName Container name - * @param array $metadata Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createContainerIfNotExists($containerName = '', $metadata = array()) - { - if (!$this->containerExists($containerName)) { - $this->createContainer($containerName, $metadata); - } - } - - /** - * Get container ACL - * - * @param string $containerName Container name - * @param bool $signedIdentifiers Display only private/blob/container or display signed identifiers? - * @return string Acl, to be compared with Zend_Service_WindowsAzure_Storage_Blob::ACL_* - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getContainerAcl($containerName = '', $signedIdentifiers = false) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); - if ($response->isSuccessful()) { - if ($signedIdentifiers == false) { - // Only private/blob/container - $accessType = $response->getHeader(Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'); - if (strtolower($accessType) == 'true') { - $accessType = self::ACL_PUBLIC_CONTAINER; - } - return $accessType; - } else { - // Parse result - $result = $this->_parseResponse($response); - if (!$result) { - return array(); - } - - $entries = null; - if ($result->SignedIdentifier) { - if (count($result->SignedIdentifier) > 1) { - $entries = $result->SignedIdentifier; - } else { - $entries = array($result->SignedIdentifier); - } - } - - #require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php'; - // Return value - $returnValue = array(); - foreach ($entries as $entry) { - $returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier( - $entry->Id, - $entry->AccessPolicy ? $entry->AccessPolicy->Start ? $entry->AccessPolicy->Start : '' : '', - $entry->AccessPolicy ? $entry->AccessPolicy->Expiry ? $entry->AccessPolicy->Expiry : '' : '', - $entry->AccessPolicy ? $entry->AccessPolicy->Permission ? $entry->AccessPolicy->Permission : '' : '' - ); - } - - // Return - return $returnValue; - } - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Set container ACL - * - * @param string $containerName Container name - * @param bool $acl Zend_Service_WindowsAzure_Storage_Blob::ACL_* - * @param array $signedIdentifiers Signed identifiers - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Headers - $headers = array(); - - // Acl specified? - if ($acl != self::ACL_PRIVATE && !is_null($acl) && $acl != '') { - $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'] = $acl; - } - - // Policies - $policies = null; - if (is_array($signedIdentifiers) && count($signedIdentifiers) > 0) { - $policies = ''; - $policies .= '' . "\r\n"; - $policies .= '' . "\r\n"; - foreach ($signedIdentifiers as $signedIdentifier) { - $policies .= ' ' . "\r\n"; - $policies .= ' ' . $signedIdentifier->Id . '' . "\r\n"; - $policies .= ' ' . "\r\n"; - if ($signedIdentifier->Start != '') - $policies .= ' ' . $signedIdentifier->Start . '' . "\r\n"; - if ($signedIdentifier->Expiry != '') - $policies .= ' ' . $signedIdentifier->Expiry . '' . "\r\n"; - if ($signedIdentifier->Permissions != '') - $policies .= ' ' . $signedIdentifier->Permissions . '' . "\r\n"; - $policies .= ' ' . "\r\n"; - $policies .= ' ' . "\r\n"; - } - $policies .= '' . "\r\n"; - } - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::PUT, $headers, false, $policies, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get container - * - * @param string $containerName Container name - * @return Zend_Service_WindowsAzure_Storage_BlobContainer - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getContainer($containerName = '') - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); - if ($response->isSuccessful()) { - // Parse metadata - $metadata = $this->_parseMetadataHeaders($response->getHeaders()); - - // Return container - return new Zend_Service_WindowsAzure_Storage_BlobContainer( - $containerName, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get container metadata - * - * @param string $containerName Container name - * @return array Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getContainerMetadata($containerName = '') - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - return $this->getContainer($containerName)->Metadata; - } - - /** - * Set container metadata - * - * Calling the Set Container Metadata operation overwrites all existing metadata that is associated with the container. It's not possible to modify an individual name/value pair. - * - * @param string $containerName Container name - * @param array $metadata Key/value pairs of meta data - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if (!is_array($metadata)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); - } - if (count($metadata) == 0) { - return; - } - - // Create metadata headers - $headers = array(); - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container&comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Delete container - * - * @param string $containerName Container name - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteContainer($containerName = '', $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Additional headers? - $headers = array(); - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Perform request - $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * List containers - * - * @param string $prefix Optional. Filters the results to return only containers whose name begins with the specified prefix. - * @param int $maxResults Optional. Specifies the maximum number of containers to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000) - * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. - * @param string $include Optional. Include this parameter to specify that the container's metadata be returned as part of the response body. (allowed values: '', 'metadata') - * @param int $currentResultCount Current result count (internal use) - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function listContainers($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0) - { - // Build query string - $queryString = array('comp=list'); - if (!is_null($prefix)) { - $queryString[] = 'prefix=' . $prefix; - } - if (!is_null($maxResults)) { - $queryString[] = 'maxresults=' . $maxResults; - } - if (!is_null($marker)) { - $queryString[] = 'marker=' . $marker; - } - if (!is_null($include)) { - $queryString[] = 'include=' . $include; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Perform request - $response = $this->_performRequest('', $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST); - if ($response->isSuccessful()) { - $xmlContainers = $this->_parseResponse($response)->Containers->Container; - $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; - - $containers = array(); - if (!is_null($xmlContainers)) { - for ($i = 0; $i < count($xmlContainers); $i++) { - - $containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer( - (string)$xmlContainers[$i]->Name, - (string)$xmlContainers[$i]->Etag, - (string)$xmlContainers[$i]->LastModified, - $this->_parseMetadataElement($xmlContainers[$i]) - ); - } - } - $currentResultCount = $currentResultCount + count($containers); - if (!is_null($maxResults) && $currentResultCount < $maxResults) { - if (!is_null($xmlMarker) && $xmlMarker != '') { - $containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $include, $currentResultCount)); - } - } - if (!is_null($maxResults) && count($containers) > $maxResults) { - $containers = array_slice($containers, 0, $maxResults); - } - - return $containers; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $localFileName Local file name to be uploaded - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return object Partial blob properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($localFileName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); - } - if (!file_exists($localFileName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Check file size - if (filesize($localFileName) >= self::MAX_BLOB_SIZE) { - return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders); - } - - // Put the data to Windows Azure Storage - return $this->putBlobData($containerName, $blobName, file_get_contents($localFileName), $metadata, $leaseId, $additionalHeaders); - } - - /** - * Put blob data - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param mixed $data Data to store - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return object Partial blob properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putBlobData($containerName = '', $blobName = '', $data = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Specify blob type - $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_BLOCK; - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, $data, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - - return new Zend_Service_WindowsAzure_Storage_BlobInstance( - $containerName, - $blobName, - null, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, - strlen($data), - '', - '', - '', - false, - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put large blob (> 64 MB) - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $localFileName Local file name to be uploaded - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return object Partial blob properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($localFileName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); - } - if (!file_exists($localFileName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Check file size - if (filesize($localFileName) < self::MAX_BLOB_SIZE) { - return $this->putBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders); - } - - // Determine number of parts - $numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE ); - - // Generate block id's - $blockIdentifiers = array(); - for ($i = 0; $i < $numberOfParts; $i++) { - $blockIdentifiers[] = $this->_generateBlockId($i); - } - - // Open file - $fp = fopen($localFileName, 'r'); - if ($fp === false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Could not open local file.'); - } - - // Upload parts - for ($i = 0; $i < $numberOfParts; $i++) { - // Seek position in file - fseek($fp, $i * self::MAX_BLOB_TRANSFER_SIZE); - - // Read contents - $fileContents = fread($fp, self::MAX_BLOB_TRANSFER_SIZE); - - // Put block - $this->putBlock($containerName, $blobName, $blockIdentifiers[$i], $fileContents, $leaseId); - - // Dispose file contents - $fileContents = null; - unset($fileContents); - } - - // Close file - fclose($fp); - - // Put block list - $this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata, $leaseId, $additionalHeaders); - - // Return information of the blob - return $this->getBlobInstance($containerName, $blobName, null, $leaseId); - } - - /** - * Put large blob block - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $identifier Block ID - * @param array $contents Contents of the block - * @param string $leaseId Lease identifier - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '', $leaseId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($identifier === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Block identifier is not specified.'); - } - if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Block size is too big.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Upload - $response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put block list - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param array $blockList Array of block identifiers - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if (count($blockList) == 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Generate block list - $blocks = ''; - foreach ($blockList as $block) { - $blocks .= ' ' . base64_encode($block) . '' . "\n"; - } - - // Generate block list request - $fileContents = utf8_encode(implode("\n", array( - '', - '', - $blocks, - '' - ))); - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '?comp=blocklist', Zend_Http_Client::PUT, $headers, false, $fileContents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get block list - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @param integer $type Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlockList($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $type = 0) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($type < 0 || $type > 2) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.'); - } - - // Set $blockListType - $blockListType = 'all'; - if ($type == 1) { - $blockListType = 'committed'; - } - if ($type == 2) { - $blockListType = 'uncommitted'; - } - - // Headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Build query string - $queryString = array('comp=blocklist', 'blocklisttype=' . $blockListType); - if (!is_null($snapshotId)) { - $queryString[] = 'snapshot=' . $snapshotId; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); - if ($response->isSuccessful()) { - // Parse response - $blockList = $this->_parseResponse($response); - - // Create return value - $returnValue = array(); - if ($blockList->CommittedBlocks) { - foreach ($blockList->CommittedBlocks->Block as $block) { - $returnValue['CommittedBlocks'][] = (object)array( - 'Name' => (string)$block->Name, - 'Size' => (string)$block->Size - ); - } - } - if ($blockList->UncommittedBlocks) { - foreach ($blockList->UncommittedBlocks->Block as $block) { - $returnValue['UncommittedBlocks'][] = (object)array( - 'Name' => (string)$block->Name, - 'Size' => (string)$block->Size - ); - } - } - - return $returnValue; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Create page blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param int $size Size of the page blob in bytes - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return object Partial blob properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createPageBlob($containerName = '', $blobName = '', $size = 0, $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if ($size <= 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Page blob size must be specified.'); - } - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Specify blob type & blob length - $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_PAGE; - $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-content-length'] = $size; - $headers['Content-Length'] = 0; - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, '', Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - - return new Zend_Service_WindowsAzure_Storage_BlobInstance( - $containerName, - $blobName, - null, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, - $size, - '', - '', - '', - false, - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put page in page blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param int $startByteOffset Start byte offset - * @param int $endByteOffset End byte offset - * @param mixed $contents Page contents - * @param string $writeMethod Write method (Zend_Service_WindowsAzure_Storage_Blob::PAGE_WRITE_*) - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putPage($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $contents = '', $writeMethod = self::PAGE_WRITE_UPDATE, $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if ($startByteOffset % 512 != 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.'); - } - if (($endByteOffset + 1) % 512 != 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.'); - } - - // Determine size - $size = strlen($contents); - if ($size >= self::MAX_BLOB_TRANSFER_SIZE) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Page blob size must not be larger than ' + self::MAX_BLOB_TRANSFER_SIZE . ' bytes.'); - } - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Specify range - $headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset; - - // Write method - $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'page-write'] = $writeMethod; - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '?comp=page', Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put page in page blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param int $startByteOffset Start byte offset - * @param int $endByteOffset End byte offset - * @param string $leaseId Lease identifier - * @return array Array of page ranges - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getPageRegions($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $leaseId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if ($startByteOffset % 512 != 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.'); - } - if ($endByteOffset > 0 && ($endByteOffset + 1) % 512 != 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.'); - } - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Specify range? - if ($endByteOffset > 0) { - $headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '?comp=pagelist', Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - $result = $this->_parseResponse($response); - $xmlRanges = null; - if (count($result->PageRange) > 1) { - $xmlRanges = $result->PageRange; - } else { - $xmlRanges = array($result->PageRange); - } - - - $ranges = array(); - - for ($i = 0; $i < count($xmlRanges); $i++) { - $ranges[] = new Zend_Service_WindowsAzure_Storage_PageRegionInstance( - (int)$xmlRanges[$i]->Start, - (int)$xmlRanges[$i]->End - ); - } - - return $ranges; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Copy blob - * - * @param string $sourceContainerName Source container name - * @param string $sourceBlobName Source blob name - * @param string $destinationContainerName Destination container name - * @param string $destinationBlobName Destination blob name - * @param array $metadata Key/value pairs of meta data - * @param string $sourceSnapshotId Source snapshot identifier - * @param string $destinationLeaseId Destination lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information. - * @return object Partial blob properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $sourceSnapshotId = null, $destinationLeaseId = null, $additionalHeaders = array()) - { - if ($sourceContainerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Source container name is not specified.'); - } - if (!self::isValidContainerName($sourceContainerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Source container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($sourceBlobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Source blob name is not specified.'); - } - if ($destinationContainerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Destination container name is not specified.'); - } - if (!self::isValidContainerName($destinationContainerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Destination container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($destinationBlobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.'); - } - if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Create metadata headers - $headers = array(); - if (!is_null($destinationLeaseId)) { - $headers['x-ms-lease-id'] = $destinationLeaseId; - } - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource names - $sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName); - if (!is_null($sourceSnapshotId)) { - $sourceResourceName .= '?snapshot=' . $sourceSnapshotId; - } - $destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName); - - // Set source blob - $headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName; - - // Perform request - $response = $this->_performRequest($destinationResourceName, '', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - - return new Zend_Service_WindowsAzure_Storage_BlobInstance( - $destinationContainerName, - $destinationBlobName, - null, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $this->getBaseUrl() . '/' . $destinationContainerName . '/' . $destinationBlobName, - 0, - '', - '', - '', - false, - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $localFileName Local file name to store downloaded blob - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlob($containerName = '', $blobName = '', $localFileName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($localFileName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); - } - - // Fetch data - file_put_contents($localFileName, $this->getBlobData($containerName, $blobName, $snapshotId, $leaseId, $additionalHeaders)); - } - - /** - * Get blob data - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return mixed Blob contents - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlobData($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - - // Build query string - $queryString = array(); - if (!is_null($snapshotId)) { - $queryString[] = 'snapshot=' . $snapshotId; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Additional headers? - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); - if ($response->isSuccessful()) { - return $response->getBody(); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get blob instance - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return Zend_Service_WindowsAzure_Storage_BlobInstance - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlobInstance($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Build query string - $queryString = array(); - if (!is_null($snapshotId)) { - $queryString[] = 'snapshot=' . $snapshotId; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Additional headers? - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::HEAD, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); - if ($response->isSuccessful()) { - // Parse metadata - $metadata = $this->_parseMetadataHeaders($response->getHeaders()); - - // Return blob - return new Zend_Service_WindowsAzure_Storage_BlobInstance( - $containerName, - $blobName, - $snapshotId, - $response->getHeader('Etag'), - $response->getHeader('Last-modified'), - $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, - $response->getHeader('Content-Length'), - $response->getHeader('Content-Type'), - $response->getHeader('Content-Encoding'), - $response->getHeader('Content-Language'), - $response->getHeader('Cache-Control'), - $response->getHeader('x-ms-blob-type'), - $response->getHeader('x-ms-lease-status'), - false, - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get blob metadata - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @return array Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlobMetadata($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId)->Metadata; - } - - /** - * Set blob metadata - * - * Calling the Set Blob Metadata operation overwrites all existing metadata that is associated with the blob. It's not possible to modify an individual name/value pair. - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param array $metadata Key/value pairs of meta data - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if (count($metadata) == 0) { - return; - } - - // Create metadata headers - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Perform request - $response = $this->_performRequest($containerName . '/' . $blobName, '?comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Set blob properties - * - * All available properties are listed at http://msdn.microsoft.com/en-us/library/ee691966.aspx and should be provided in the $additionalHeaders parameter. - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setBlobProperties($containerName = '', $blobName = '', $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - if (count($additionalHeaders) == 0) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('No additional headers are specified.'); - } - - // Create headers - $headers = array(); - - // Lease set? - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Additional headers? - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Perform request - $response = $this->_performRequest($containerName . '/' . $blobName, '?comp=properties', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get blob properties - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @return Zend_Service_WindowsAzure_Storage_BlobInstance - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getBlobProperties($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId); - } - - /** - * Delete blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $snapshotId Snapshot identifier - * @param string $leaseId Lease identifier - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteBlob($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Build query string - $queryString = array(); - if (!is_null($snapshotId)) { - $queryString[] = 'snapshot=' . $snapshotId; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Additional headers? - $headers = array(); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Snapshot blob - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param array $metadata Key/value pairs of meta data - * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. - * @return string Date/Time value representing the snapshot identifier. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function snapshotBlob($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array()) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Additional headers? - $headers = array(); - foreach ($additionalHeaders as $key => $value) { - $headers[$key] = $value; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '?comp=snapshot', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - if ($response->isSuccessful()) { - return $response->getHeader('x-ms-snapshot'); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Lease blob - See (http://msdn.microsoft.com/en-us/library/ee691972.aspx) - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $leaseAction Lease action (Zend_Service_WindowsAzure_Storage_Blob::LEASE_*) - * @param string $leaseId Lease identifier, required to renew the lease or to release the lease. - * @return Zend_Service_WindowsAzure_Storage_LeaseInstance Lease instance - * @throws Zend_Service_WindowsAzure_Exception - */ - public function leaseBlob($containerName = '', $blobName = '', $leaseAction = self::LEASE_ACQUIRE, $leaseId = null) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - if ($blobName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); - } - if ($containerName === '$root' && strpos($blobName, '/') !== false) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); - } - - // Additional headers? - $headers = array(); - $headers['x-ms-lease-action'] = strtolower($leaseAction); - if (!is_null($leaseId)) { - $headers['x-ms-lease-id'] = $leaseId; - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Perform request - $response = $this->_performRequest($resourceName, '?comp=lease', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); - - - - if ($response->isSuccessful()) { - return new Zend_Service_WindowsAzure_Storage_LeaseInstance( - $containerName, - $blobName, - $response->getHeader('x-ms-lease-id'), - $response->getHeader('x-ms-lease-time')); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * List blobs - * - * @param string $containerName Container name - * @param string $prefix Optional. Filters the results to return only blobs whose name begins with the specified prefix. - * @param string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy - * @param int $maxResults Optional. Specifies the maximum number of blobs to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000) - * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. - * @param string $include Optional. Specifies that the response should include one or more of the following subsets: '', 'metadata', 'snapshots', 'uncommittedblobs'). Multiple values can be added separated with a comma (,) - * @param int $currentResultCount Current result count (internal use) - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $include = null, $currentResultCount = 0) - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Build query string - $queryString = array('restype=container', 'comp=list'); - if (!is_null($prefix)) { - $queryString[] = 'prefix=' . $prefix; - } - if ($delimiter !== '') { - $queryString[] = 'delimiter=' . $delimiter; - } - if (!is_null($maxResults)) { - $queryString[] = 'maxresults=' . $maxResults; - } - if (!is_null($marker)) { - $queryString[] = 'marker=' . $marker; - } - if (!is_null($include)) { - $queryString[] = 'include=' . $include; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Perform request - $response = $this->_performRequest($containerName, $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST); - if ($response->isSuccessful()) { - // Return value - $blobs = array(); - - // Blobs - $xmlBlobs = $this->_parseResponse($response)->Blobs->Blob; - if (!is_null($xmlBlobs)) { - - for ($i = 0; $i < count($xmlBlobs); $i++) { - $properties = (array)$xmlBlobs[$i]->Properties; - - $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( - $containerName, - (string)$xmlBlobs[$i]->Name, - (string)$xmlBlobs[$i]->Snapshot, - (string)$properties['Etag'], - (string)$properties['Last-Modified'], - (string)$xmlBlobs[$i]->Url, - (string)$properties['Content-Length'], - (string)$properties['Content-Type'], - (string)$properties['Content-Encoding'], - (string)$properties['Content-Language'], - (string)$properties['Cache-Control'], - (string)$properties['BlobType'], - (string)$properties['LeaseStatus'], - false, - $this->_parseMetadataElement($xmlBlobs[$i]) - ); - } - } - - // Blob prefixes (folders) - $xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix; - - if (!is_null($xmlBlobs)) { - - for ($i = 0; $i < count($xmlBlobs); $i++) { - $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( - $containerName, - (string)$xmlBlobs[$i]->Name, - null, - '', - '', - '', - 0, - '', - '', - '', - '', - '', - '', - true, - $this->_parseMetadataElement($xmlBlobs[$i]) - ); - } - } - - // More blobs? - $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; - $currentResultCount = $currentResultCount + count($blobs); - if (!is_null($maxResults) && $currentResultCount < $maxResults) { - if (!is_null($xmlMarker) && $xmlMarker != '') { - $blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $include, $currentResultCount)); - } - } - if (!is_null($maxResults) && count($blobs) > $maxResults) { - $blobs = array_slice($blobs, 0, $maxResults); - } - - return $blobs; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Generate shared access URL - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @param string $resource Signed resource - container (c) - blob (b) - * @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l) - * @param string $start The time at which the Shared Access Signature becomes valid. - * @param string $expiry The time at which the Shared Access Signature becomes invalid. - * @param string $identifier Signed identifier - * @return string - */ - public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '') - { - if ($containerName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); - } - if (!self::isValidContainerName($containerName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); - } - - // Resource name - $resourceName = self::createResourceName($containerName , $blobName); - - // Generate URL - return $this->getBaseUrl() . '/' . $resourceName . '?' . - $this->_sharedAccessSignatureCredentials->createSignedQueryString( - $resourceName, - '', - $resource, - $permissions, - $start, - $expiry, - $identifier); - } - - /** - * Register this object as stream wrapper client - * - * @param string $name Protocol name - * @return Zend_Service_WindowsAzure_Storage_Blob - */ - public function registerAsClient($name) - { - self::$_wrapperClients[$name] = $this; - return $this; - } - - /** - * Unregister this object as stream wrapper client - * - * @param string $name Protocol name - * @return Zend_Service_WindowsAzure_Storage_Blob - */ - public function unregisterAsClient($name) - { - unset(self::$_wrapperClients[$name]); - return $this; - } - - /** - * Get wrapper client for stream type - * - * @param string $name Protocol name - * @return Zend_Service_WindowsAzure_Storage_Blob - */ - public static function getWrapperClient($name) - { - return self::$_wrapperClients[$name]; - } - - /** - * Register this object as stream wrapper - * - * @param string $name Protocol name - */ - public function registerStreamWrapper($name = 'azure') - { - stream_register_wrapper($name, 'Zend_Service_WindowsAzure_Storage_Blob_Stream'); - $this->registerAsClient($name); - } - - /** - * Unregister this object as stream wrapper - * - * @param string $name Protocol name - * @return Zend_Service_WindowsAzure_Storage_Blob - */ - public function unregisterStreamWrapper($name = 'azure') - { - stream_wrapper_unregister($name); - $this->unregisterAsClient($name); - } - - /** - * Create resource name - * - * @param string $containerName Container name - * @param string $blobName Blob name - * @return string - */ - public static function createResourceName($containerName = '', $blobName = '') - { - // Resource name - $resourceName = $containerName . '/' . $blobName; - if ($containerName === '' || $containerName === '$root') { - $resourceName = $blobName; - } - if ($blobName === '') { - $resourceName = $containerName; - } - - return $resourceName; - } - - /** - * Is valid container name? - * - * @param string $containerName Container name - * @return boolean - */ - public static function isValidContainerName($containerName = '') - { - if ($containerName == '$root') { - return true; - } - - if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $containerName) === 0) { - return false; - } - - if (strpos($containerName, '--') !== false) { - return false; - } - - if (strtolower($containerName) != $containerName) { - return false; - } - - if (strlen($containerName) < 3 || strlen($containerName) > 63) { - return false; - } - - if (substr($containerName, -1) == '-') { - return false; - } - - return true; - } - - /** - * Get error message from Zend_Http_Response - * - * @param Zend_Http_Response $response Repsonse - * @param string $alternativeError Alternative error message - * @return string - */ - protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') - { - $response = $this->_parseResponse($response); - if ($response && $response->Message) { - return (string)$response->Message; - } else { - return $alternativeError; - } - } - - /** - * Generate block id - * - * @param int $part Block number - * @return string Windows Azure Blob Storage block number - */ - protected function _generateBlockId($part = 0) - { - $returnValue = $part; - while (strlen($returnValue) < 64) { - $returnValue = '0' . $returnValue; - } - - return $returnValue; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/Blob/Stream.php b/lib/Zend/Service/WindowsAzure/Storage/Blob/Stream.php deleted file mode 100644 index cef6e863c4c..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/Blob/Stream.php +++ /dev/null @@ -1,544 +0,0 @@ -_storageClient)) { - $url = explode(':', $path); - if (!$url) { - throw new Zend_Service_WindowsAzure_Exception('Could not parse path "' . $path . '".'); - } - - $this->_storageClient = Zend_Service_WindowsAzure_Storage_Blob::getWrapperClient($url[0]); - if (!$this->_storageClient) { - throw new Zend_Service_WindowsAzure_Exception('No storage client registered for stream type "' . $url[0] . '://".'); - } - } - - return $this->_storageClient; - } - - /** - * Extract container name - * - * @param string $path - * @return string - */ - protected function _getContainerName($path) - { - $url = parse_url($path); - if ($url['host']) { - return $url['host']; - } - - return ''; - } - - /** - * Extract file name - * - * @param string $path - * @return string - */ - protected function _getFileName($path) - { - $url = parse_url($path); - if ($url['host']) { - $fileName = isset($url['path']) ? $url['path'] : $url['host']; - if (strpos($fileName, '/') === 0) { - $fileName = substr($fileName, 1); - } - return $fileName; - } - - return ''; - } - - /** - * Open the stream - * - * @param string $path - * @param string $mode - * @param integer $options - * @param string $opened_path - * @return boolean - */ - public function stream_open($path, $mode, $options, &$opened_path) - { - $this->_fileName = $path; - $this->_temporaryFileName = tempnam(sys_get_temp_dir(), 'azure'); - - // Check the file can be opened - $fh = @fopen($this->_temporaryFileName, $mode); - if ($fh === false) { - return false; - } - fclose($fh); - - // Write mode? - if (strpbrk($mode, 'wax+')) { - $this->_writeMode = true; - } else { - $this->_writeMode = false; - } - - // If read/append, fetch the file - if (!$this->_writeMode || strpbrk($mode, 'ra+')) { - $this->_getStorageClient($this->_fileName)->getBlob( - $this->_getContainerName($this->_fileName), - $this->_getFileName($this->_fileName), - $this->_temporaryFileName - ); - } - - // Open temporary file handle - $this->_temporaryFileHandle = fopen($this->_temporaryFileName, $mode); - - // Ok! - return true; - } - - /** - * Close the stream - * - * @return void - */ - public function stream_close() - { - @fclose($this->_temporaryFileHandle); - - // Upload the file? - if ($this->_writeMode) { - // Make sure the container exists - $containerExists = $this->_getStorageClient($this->_fileName)->containerExists( - $this->_getContainerName($this->_fileName) - ); - if (!$containerExists) { - $this->_getStorageClient($this->_fileName)->createContainer( - $this->_getContainerName($this->_fileName) - ); - } - - // Upload the file - try { - $this->_getStorageClient($this->_fileName)->putBlob( - $this->_getContainerName($this->_fileName), - $this->_getFileName($this->_fileName), - $this->_temporaryFileName - ); - } catch (Zend_Service_WindowsAzure_Exception $ex) { - @unlink($this->_temporaryFileName); - unset($this->_storageClient); - - throw $ex; - } - } - - @unlink($this->_temporaryFileName); - unset($this->_storageClient); - } - - /** - * Read from the stream - * - * @param integer $count - * @return string - */ - public function stream_read($count) - { - if (!$this->_temporaryFileHandle) { - return false; - } - - return fread($this->_temporaryFileHandle, $count); - } - - /** - * Write to the stream - * - * @param string $data - * @return integer - */ - public function stream_write($data) - { - if (!$this->_temporaryFileHandle) { - return 0; - } - - $len = strlen($data); - fwrite($this->_temporaryFileHandle, $data, $len); - return $len; - } - - /** - * End of the stream? - * - * @return boolean - */ - public function stream_eof() - { - if (!$this->_temporaryFileHandle) { - return true; - } - - return feof($this->_temporaryFileHandle); - } - - /** - * What is the current read/write position of the stream? - * - * @return integer - */ - public function stream_tell() - { - return ftell($this->_temporaryFileHandle); - } - - /** - * Update the read/write position of the stream - * - * @param integer $offset - * @param integer $whence - * @return boolean - */ - public function stream_seek($offset, $whence) - { - if (!$this->_temporaryFileHandle) { - return false; - } - - return (fseek($this->_temporaryFileHandle, $offset, $whence) === 0); - } - - /** - * Flush current cached stream data to storage - * - * @return boolean - */ - public function stream_flush() - { - $result = fflush($this->_temporaryFileHandle); - - // Upload the file? - if ($this->_writeMode) { - // Make sure the container exists - $containerExists = $this->_getStorageClient($this->_fileName)->containerExists( - $this->_getContainerName($this->_fileName) - ); - if (!$containerExists) { - $this->_getStorageClient($this->_fileName)->createContainer( - $this->_getContainerName($this->_fileName) - ); - } - - // Upload the file - try { - $this->_getStorageClient($this->_fileName)->putBlob( - $this->_getContainerName($this->_fileName), - $this->_getFileName($this->_fileName), - $this->_temporaryFileName - ); - } catch (Zend_Service_WindowsAzure_Exception $ex) { - @unlink($this->_temporaryFileName); - unset($this->_storageClient); - - throw $ex; - } - } - - return $result; - } - - /** - * Returns data array of stream variables - * - * @return array - */ - public function stream_stat() - { - if (!$this->_temporaryFileHandle) { - return false; - } - - return $this->url_stat($this->_fileName, 0); - } - - /** - * Attempt to delete the item - * - * @param string $path - * @return boolean - */ - public function unlink($path) - { - $this->_getStorageClient($path)->deleteBlob( - $this->_getContainerName($path), - $this->_getFileName($path) - ); - - // Clear the stat cache for this path. - clearstatcache(true, $path); - return true; - } - - /** - * Attempt to rename the item - * - * @param string $path_from - * @param string $path_to - * @return boolean False - */ - public function rename($path_from, $path_to) - { - if ($this->_getContainerName($path_from) != $this->_getContainerName($path_to)) { - throw new Zend_Service_WindowsAzure_Exception('Container name can not be changed.'); - } - - if ($this->_getFileName($path_from) == $this->_getContainerName($path_to)) { - return true; - } - - $this->_getStorageClient($path_from)->copyBlob( - $this->_getContainerName($path_from), - $this->_getFileName($path_from), - $this->_getContainerName($path_to), - $this->_getFileName($path_to) - ); - $this->_getStorageClient($path_from)->deleteBlob( - $this->_getContainerName($path_from), - $this->_getFileName($path_from) - ); - - // Clear the stat cache for the affected paths. - clearstatcache(true, $path_from); - clearstatcache(true, $path_to); - return true; - } - - /** - * Return array of URL variables - * - * @param string $path - * @param integer $flags - * @return array - */ - public function url_stat($path, $flags) - { - $stat = array(); - $stat['dev'] = 0; - $stat['ino'] = 0; - $stat['mode'] = 0; - $stat['nlink'] = 0; - $stat['uid'] = 0; - $stat['gid'] = 0; - $stat['rdev'] = 0; - $stat['size'] = 0; - $stat['atime'] = 0; - $stat['mtime'] = 0; - $stat['ctime'] = 0; - $stat['blksize'] = 0; - $stat['blocks'] = 0; - - $info = null; - try { - $info = $this->_getStorageClient($path)->getBlobInstance( - $this->_getContainerName($path), - $this->_getFileName($path) - ); - $stat['size'] = $info->Size; - - // Set the modification time and last modified to the Last-Modified header. - $lastmodified = strtotime($info->LastModified); - $stat['mtime'] = $lastmodified; - $stat['ctime'] = $lastmodified; - - // Entry is a regular file. - $stat['mode'] = 0100000; - - return array_values($stat) + $stat; - } catch (Zend_Service_WindowsAzure_Exception $ex) { - // Unexisting file... - return false; - } - } - - /** - * Create a new directory - * - * @param string $path - * @param integer $mode - * @param integer $options - * @return boolean - */ - public function mkdir($path, $mode, $options) - { - if ($this->_getContainerName($path) == $this->_getFileName($path)) { - // Create container - try { - $this->_getStorageClient($path)->createContainer( - $this->_getContainerName($path) - ); - return true; - } catch (Zend_Service_WindowsAzure_Exception $ex) { - return false; - } - } else { - throw new Zend_Service_WindowsAzure_Exception('mkdir() with multiple levels is not supported on Windows Azure Blob Storage.'); - } - } - - /** - * Remove a directory - * - * @param string $path - * @param integer $options - * @return boolean - */ - public function rmdir($path, $options) - { - if ($this->_getContainerName($path) == $this->_getFileName($path)) { - // Clear the stat cache so that affected paths are refreshed. - clearstatcache(); - - // Delete container - try { - $this->_getStorageClient($path)->deleteContainer( - $this->_getContainerName($path) - ); - return true; - } catch (Zend_Service_WindowsAzure_Exception $ex) { - return false; - } - } else { - throw new Zend_Service_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.'); - } - } - - /** - * Attempt to open a directory - * - * @param string $path - * @param integer $options - * @return boolean - */ - public function dir_opendir($path, $options) - { - $this->_blobs = $this->_getStorageClient($path)->listBlobs( - $this->_getContainerName($path) - ); - return is_array($this->_blobs); - } - - /** - * Return the next filename in the directory - * - * @return string - */ - public function dir_readdir() - { - $object = current($this->_blobs); - if ($object !== false) { - next($this->_blobs); - return $object->Name; - } - return false; - } - - /** - * Reset the directory pointer - * - * @return boolean True - */ - public function dir_rewinddir() - { - reset($this->_blobs); - return true; - } - - /** - * Close a directory - * - * @return boolean True - */ - public function dir_closedir() - { - $this->_blobs = null; - return true; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/BlobContainer.php b/lib/Zend/Service/WindowsAzure/Storage/BlobContainer.php deleted file mode 100644 index 6b841803e5c..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/BlobContainer.php +++ /dev/null @@ -1,90 +0,0 @@ -_data = array( - 'name' => $name, - 'etag' => $etag, - 'lastmodified' => $lastModified, - 'metadata' => $metadata - ); - } - - /** - * Magic overload for setting properties - * - * @param string $name Name of the property - * @param string $value Value to set - */ - public function __set($name, $value) { - if (array_key_exists(strtolower($name), $this->_data)) { - $this->_data[strtolower($name)] = $value; - return; - } - - throw new Exception("Unknown property: " . $name); - } - - /** - * Magic overload for getting properties - * - * @param string $name Name of the property - */ - public function __get($name) { - if (array_key_exists(strtolower($name), $this->_data)) { - return $this->_data[strtolower($name)]; - } - - throw new Exception("Unknown property: " . $name); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/BlobInstance.php b/lib/Zend/Service/WindowsAzure/Storage/BlobInstance.php deleted file mode 100644 index 49d6dd29bfc..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/BlobInstance.php +++ /dev/null @@ -1,93 +0,0 @@ -_data = array( - 'container' => $containerName, - 'name' => $name, - 'snapshotid' => $snapshotId, - 'etag' => $etag, - 'lastmodified' => $lastModified, - 'url' => $url, - 'size' => $size, - 'contenttype' => $contentType, - 'contentencoding' => $contentEncoding, - 'contentlanguage' => $contentLanguage, - 'cachecontrol' => $cacheControl, - 'blobtype' => $blobType, - 'leasestatus' => $leaseStatus, - 'isprefix' => $isPrefix, - 'metadata' => $metadata - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/DynamicTableEntity.php b/lib/Zend/Service/WindowsAzure/Storage/DynamicTableEntity.php deleted file mode 100644 index fb7faf86fca..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/DynamicTableEntity.php +++ /dev/null @@ -1,219 +0,0 @@ -setAzureProperty($name, $value, null); - } - - /** - * Magic overload for getting properties - * - * @param string $name Name of the property - */ - public function __get($name) { - return $this->getAzureProperty($name); - } - - /** - * Set an Azure property - * - * @param string $name Property name - * @param mixed $value Property value - * @param string $type Property type (Edm.xxxx) - * @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity - */ - public function setAzureProperty($name, $value = '', $type = null) - { - if (strtolower($name) == 'partitionkey') { - $this->setPartitionKey($value); - } else if (strtolower($name) == 'rowkey') { - $this->setRowKey($value); - } else if (strtolower($name) == 'etag') { - $this->setEtag($value); - } else { - if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) { - // Determine type? - if (is_null($type)) { - $type = 'Edm.String'; - if (is_int($value)) { - $type = 'Edm.Int32'; - } else if (is_float($value)) { - $type = 'Edm.Double'; - } else if (is_bool($value)) { - $type = 'Edm.Boolean'; - } else if ($value instanceof DateTime || $this->_convertToDateTime($value) !== false) { - if (!$value instanceof DateTime) { - $value = $this->_convertToDateTime($value); - } - $type = 'Edm.DateTime'; - } - } - - // Set dynamic property - $this->_dynamicProperties[strtolower($name)] = (object)array( - 'Name' => $name, - 'Type' => $type, - 'Value' => $value, - ); - } - - // Set type? - if (!is_null($type)) { - $this->_dynamicProperties[strtolower($name)]->Type = $type; - - // Try to convert the type - if ($type == 'Edm.Int32' || $type == 'Edm.Int64') { - $value = intval($value); - } else if ($type == 'Edm.Double') { - $value = floatval($value); - } else if ($type == 'Edm.Boolean') { - if (!is_bool($value)) { - $value = strtolower($value) == 'true'; - } - } else if ($type == 'Edm.DateTime') { - if (!$value instanceof DateTime) { - $value = $this->_convertToDateTime($value); - } - } - } - - // Set value - $this->_dynamicProperties[strtolower($name)]->Value = $value; - } - return $this; - } - - /** - * Set an Azure property type - * - * @param string $name Property name - * @param string $type Property type (Edm.xxxx) - * @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity - */ - public function setAzurePropertyType($name, $type = 'Edm.String') - { - if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) { - $this->setAzureProperty($name, '', $type); - } else { - $this->_dynamicProperties[strtolower($name)]->Type = $type; - } - return $this; - } - - /** - * Get an Azure property - * - * @param string $name Property name - * @param mixed $value Property value - * @param string $type Property type (Edm.xxxx) - * @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity - */ - public function getAzureProperty($name) - { - if (strtolower($name) == 'partitionkey') { - return $this->getPartitionKey(); - } - if (strtolower($name) == 'rowkey') { - return $this->getRowKey(); - } - if (strtolower($name) == 'etag') { - return $this->getEtag(); - } - - if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) { - $this->setAzureProperty($name); - } - - return $this->_dynamicProperties[strtolower($name)]->Value; - } - - /** - * Get an Azure property type - * - * @param string $name Property name - * @return string Property type (Edm.xxxx) - */ - public function getAzurePropertyType($name) - { - if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) { - $this->setAzureProperty($name, '', $type); - } - - return $this->_dynamicProperties[strtolower($name)]->Type; - } - - /** - * Get Azure values - * - * @return array - */ - public function getAzureValues() - { - return array_merge(array_values($this->_dynamicProperties), parent::getAzureValues()); - } - - /** - * Set Azure values - * - * @param array $values - * @param boolean $throwOnError Throw Zend_Service_WindowsAzure_Exception when a property is not specified in $values? - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setAzureValues($values = array(), $throwOnError = false) - { - // Set parent values - parent::setAzureValues($values, false); - - // Set current values - foreach ($values as $key => $value) - { - $this->$key = $value; - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/LeaseInstance.php b/lib/Zend/Service/WindowsAzure/Storage/LeaseInstance.php deleted file mode 100644 index 322e66c8dbb..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/LeaseInstance.php +++ /dev/null @@ -1,60 +0,0 @@ -_data = array( - 'container' => $containerName, - 'name' => $name, - 'leaseid' => $leaseId, - 'leasetime' => $leaseTime - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/PageRegionInstance.php b/lib/Zend/Service/WindowsAzure/Storage/PageRegionInstance.php deleted file mode 100644 index 6c4a912a41d..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/PageRegionInstance.php +++ /dev/null @@ -1,54 +0,0 @@ -_data = array( - 'start' => $start, - 'end' => $end - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/Queue.php b/lib/Zend/Service/WindowsAzure/Storage/Queue.php deleted file mode 100644 index 3dbd0a98a6f..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/Queue.php +++ /dev/null @@ -1,592 +0,0 @@ -_apiVersion = '2009-09-19'; - } - - /** - * Check if a queue exists - * - * @param string $queueName Queue name - * @return boolean - */ - public function queueExists($queueName = '') - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - // List queues - $queues = $this->listQueues($queueName, 1); - foreach ($queues as $queue) { - if ($queue->Name == $queueName) { - return true; - } - } - - return false; - } - - /** - * Create queue - * - * @param string $queueName Queue name - * @param array $metadata Key/value pairs of meta data - * @return object Queue properties - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createQueue($queueName = '', $metadata = array()) - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - // Create metadata headers - $headers = array(); - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Perform request - $response = $this->_performRequest($queueName, '', Zend_Http_Client::PUT, $headers); - if ($response->isSuccessful()) { - - return new Zend_Service_WindowsAzure_Storage_QueueInstance( - $queueName, - $metadata - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Create queue if it does not exist - * - * @param string $queueName Queue name - * @param array $metadata Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createQueueIfNotExists($queueName = '', $metadata = array()) - { - if (!$this->queueExists($queueName)) { - $this->createQueue($queueName, $metadata); - } - } - - /** - * Get queue - * - * @param string $queueName Queue name - * @return Zend_Service_WindowsAzure_Storage_QueueInstance - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getQueue($queueName = '') - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - // Perform request - $response = $this->_performRequest($queueName, '?comp=metadata', Zend_Http_Client::GET); - if ($response->isSuccessful()) { - // Parse metadata - $metadata = $this->_parseMetadataHeaders($response->getHeaders()); - - // Return queue - $queue = new Zend_Service_WindowsAzure_Storage_QueueInstance( - $queueName, - $metadata - ); - $queue->ApproximateMessageCount = intval($response->getHeader('x-ms-approximate-message-count')); - return $queue; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Get queue metadata - * - * @param string $queueName Queue name - * @return array Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getQueueMetadata($queueName = '') - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - return $this->getQueue($queueName)->Metadata; - } - - /** - * Set queue metadata - * - * Calling the Set Queue Metadata operation overwrites all existing metadata that is associated with the queue. It's not possible to modify an individual name/value pair. - * - * @param string $queueName Queue name - * @param array $metadata Key/value pairs of meta data - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setQueueMetadata($queueName = '', $metadata = array()) - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - if (count($metadata) == 0) { - return; - } - - // Create metadata headers - $headers = array(); - $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); - - // Perform request - $response = $this->_performRequest($queueName, '?comp=metadata', Zend_Http_Client::PUT, $headers); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Delete queue - * - * @param string $queueName Queue name - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteQueue($queueName = '') - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - // Perform request - $response = $this->_performRequest($queueName, '', Zend_Http_Client::DELETE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * List queues - * - * @param string $prefix Optional. Filters the results to return only queues whose name begins with the specified prefix. - * @param int $maxResults Optional. Specifies the maximum number of queues to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000) - * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. - * @param string $include Optional. Include this parameter to specify that the queue's metadata be returned as part of the response body. (allowed values: '', 'metadata') - * @param int $currentResultCount Current result count (internal use) - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function listQueues($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0) - { - // Build query string - $queryString = array('comp=list'); - if (!is_null($prefix)) { - $queryString[] = 'prefix=' . $prefix; - } - if (!is_null($maxResults)) { - $queryString[] = 'maxresults=' . $maxResults; - } - if (!is_null($marker)) { - $queryString[] = 'marker=' . $marker; - } - if (!is_null($include)) { - $queryString[] = 'include=' . $include; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Perform request - $response = $this->_performRequest('', $queryString, Zend_Http_Client::GET); - if ($response->isSuccessful()) { - $xmlQueues = $this->_parseResponse($response)->Queues->Queue; - $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; - - $queues = array(); - if (!is_null($xmlQueues)) { - - for ($i = 0; $i < count($xmlQueues); $i++) { - $queues[] = new Zend_Service_WindowsAzure_Storage_QueueInstance( - (string)$xmlQueues[$i]->Name, - $this->_parseMetadataElement($xmlQueues[$i]) - ); - } - } - $currentResultCount = $currentResultCount + count($queues); - if (!is_null($maxResults) && $currentResultCount < $maxResults) { - if (!is_null($xmlMarker) && $xmlMarker != '') { - $queues = array_merge($queues, $this->listQueues($prefix, $maxResults, $xmlMarker, $include, $currentResultCount)); - } - } - if (!is_null($maxResults) && count($queues) > $maxResults) { - $queues = array_slice($queues, 0, $maxResults); - } - - return $queues; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Put message into queue - * - * @param string $queueName Queue name - * @param string $message Message - * @param int $ttl Message Time-To-Live (in seconds). Defaults to 7 days if the parameter is omitted. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function putMessage($queueName = '', $message = '', $ttl = null) - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - if (strlen($message) > self::MAX_MESSAGE_SIZE) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Message is too big. Message content should be < 8KB.'); - } - if ($message == '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Message is not specified.'); - } - if (!is_null($ttl) && ($ttl <= 0 || $ttl > self::MAX_MESSAGE_SIZE)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Message TTL is invalid. Maximal TTL is 7 days (' . self::MAX_MESSAGE_SIZE . ' seconds) and should be greater than zero.'); - } - - // Build query string - $queryString = array(); - if (!is_null($ttl)) { - $queryString[] = 'messagettl=' . $ttl; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Build body - $rawData = ''; - $rawData .= ''; - $rawData .= ' ' . base64_encode($message) . ''; - $rawData .= ''; - - // Perform request - $response = $this->_performRequest($queueName . '/messages', $queryString, Zend_Http_Client::POST, array(), false, $rawData); - - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Error putting message into queue.'); - } - } - - /** - * Get queue messages - * - * @param string $queueName Queue name - * @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation. - * @param int $visibilityTimeout Optional. An integer value that specifies the message's visibility timeout in seconds. The maximum value is 2 hours. The default message visibility timeout is 30 seconds. - * @param string $peek Peek only? - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function getMessages($queueName = '', $numOfMessages = 1, $visibilityTimeout = null, $peek = false) - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - if ($numOfMessages < 1 || $numOfMessages > 32 || intval($numOfMessages) != $numOfMessages) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Invalid number of messages to retrieve.'); - } - if (!is_null($visibilityTimeout) && ($visibilityTimeout <= 0 || $visibilityTimeout > 7200)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Visibility timeout is invalid. Maximum value is 2 hours (7200 seconds) and should be greater than zero.'); - } - - // Build query string - $queryString = array(); - if ($peek) { - $queryString[] = 'peekonly=true'; - } - if ($numOfMessages > 1) { - $queryString[] = 'numofmessages=' . $numOfMessages; - } - if (!$peek && !is_null($visibilityTimeout)) { - $queryString[] = 'visibilitytimeout=' . $visibilityTimeout; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Perform request - $response = $this->_performRequest($queueName . '/messages', $queryString, Zend_Http_Client::GET); - if ($response->isSuccessful()) { - // Parse results - $result = $this->_parseResponse($response); - if (!$result) { - return array(); - } - - $xmlMessages = null; - if (count($result->QueueMessage) > 1) { - $xmlMessages = $result->QueueMessage; - } else { - $xmlMessages = array($result->QueueMessage); - } - - $messages = array(); - for ($i = 0; $i < count($xmlMessages); $i++) { - $messages[] = new Zend_Service_WindowsAzure_Storage_QueueMessage( - (string)$xmlMessages[$i]->MessageId, - (string)$xmlMessages[$i]->InsertionTime, - (string)$xmlMessages[$i]->ExpirationTime, - ($peek ? '' : (string)$xmlMessages[$i]->PopReceipt), - ($peek ? '' : (string)$xmlMessages[$i]->TimeNextVisible), - (string)$xmlMessages[$i]->DequeueCount, - base64_decode((string)$xmlMessages[$i]->MessageText) - ); - } - - return $messages; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Peek queue messages - * - * @param string $queueName Queue name - * @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation. - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function peekMessages($queueName = '', $numOfMessages = 1) - { - return $this->getMessages($queueName, $numOfMessages, null, true); - } - - /** - * Checks to see if a given queue has messages - * - * @param string $queueName Queue name - * @return boolean - * @throws Zend_Service_WindowsAzure_Exception - */ - public function hasMessages($queueName = '') - { - return count($this->peekMessages($queueName)) > 0; - } - - /** - * Clear queue messages - * - * @param string $queueName Queue name - * @throws Zend_Service_WindowsAzure_Exception - */ - public function clearMessages($queueName = '') - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - - // Perform request - $response = $this->_performRequest($queueName . '/messages', '', Zend_Http_Client::DELETE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Error clearing messages from queue.'); - } - } - - /** - * Delete queue message - * - * @param string $queueName Queue name - * @param Zend_Service_WindowsAzure_Storage_QueueMessage $message Message to delete from queue. A message retrieved using "peekMessages" can NOT be deleted! - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteMessage($queueName, Zend_Service_WindowsAzure_Storage_QueueMessage $message) - { - if ($queueName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.'); - } - if (!self::isValidQueueName($queueName)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.'); - } - if ($message->PopReceipt == '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('A message retrieved using "peekMessages" can NOT be deleted! Use "getMessages" instead.'); - } - - // Perform request - $response = $this->_performRequest($queueName . '/messages/' . $message->MessageId, '?popreceipt=' . urlencode($message->PopReceipt), Zend_Http_Client::DELETE); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Is valid queue name? - * - * @param string $queueName Queue name - * @return boolean - */ - public static function isValidQueueName($queueName = '') - { - if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $queueName) === 0) { - return false; - } - - if (strpos($queueName, '--') !== false) { - return false; - } - - if (strtolower($queueName) != $queueName) { - return false; - } - - if (strlen($queueName) < 3 || strlen($queueName) > 63) { - return false; - } - - if (substr($queueName, -1) == '-') { - return false; - } - - return true; - } - - /** - * Get error message from Zend_Http_Response - * - * @param Zend_Http_Response $response Repsonse - * @param string $alternativeError Alternative error message - * @return string - */ - protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') - { - $response = $this->_parseResponse($response); - if ($response && $response->Message) { - return (string)$response->Message; - } else { - return $alternativeError; - } - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/QueueInstance.php b/lib/Zend/Service/WindowsAzure/Storage/QueueInstance.php deleted file mode 100644 index 115578fed45..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/QueueInstance.php +++ /dev/null @@ -1,56 +0,0 @@ -_data = array( - 'name' => $name, - 'metadata' => $metadata, - 'approximatemessagecount' => 0 - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/QueueMessage.php b/lib/Zend/Service/WindowsAzure/Storage/QueueMessage.php deleted file mode 100644 index 68746ff843d..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/QueueMessage.php +++ /dev/null @@ -1,69 +0,0 @@ -_data = array( - 'messageid' => $messageId, - 'insertiontime' => $insertionTime, - 'expirationtime' => $expirationTime, - 'popreceipt' => $popReceipt, - 'timenextvisible' => $timeNextVisible, - 'dequeuecount' => $dequeueCount, - 'messagetext' => $messageText - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/SignedIdentifier.php b/lib/Zend/Service/WindowsAzure/Storage/SignedIdentifier.php deleted file mode 100644 index 4e7d39b0eb7..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/SignedIdentifier.php +++ /dev/null @@ -1,60 +0,0 @@ -_data = array( - 'id' => $id, - 'start' => $start, - 'expiry' => $expiry, - 'permissions' => $permissions - ); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/StorageEntityAbstract.php b/lib/Zend/Service/WindowsAzure/Storage/StorageEntityAbstract.php deleted file mode 100644 index dcd3e4cddf0..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/StorageEntityAbstract.php +++ /dev/null @@ -1,67 +0,0 @@ -_data)) { - $this->_data[strtolower($name)] = $value; - return; - } - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception("Unknown property: " . $name); - } - - /** - * Magic overload for getting properties - * - * @param string $name Name of the property - */ - public function __get($name) { - if (array_key_exists(strtolower($name), $this->_data)) { - return $this->_data[strtolower($name)]; - } - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception("Unknown property: " . $name); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/Table.php b/lib/Zend/Service/WindowsAzure/Storage/Table.php deleted file mode 100644 index c4f0852ff28..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/Table.php +++ /dev/null @@ -1,931 +0,0 @@ -_throwExceptionOnMissingData = $value; - } - - /** - * Throw Zend_Service_WindowsAzure_Exception when a property is not specified in Windows Azure? - */ - public function getThrowExceptionOnMissingData() - { - return $this->_throwExceptionOnMissingData; - } - - /** - * Creates a new Zend_Service_WindowsAzure_Storage_Table instance - * - * @param string $host Storage host name - * @param string $accountName Account name for Windows Azure - * @param string $accountKey Account key for Windows Azure - * @param boolean $usePathStyleUri Use path-style URI's - * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests - */ - public function __construct($host = Zend_Service_WindowsAzure_Storage::URL_DEV_TABLE, $accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) - { - parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy); - - // Always use SharedKeyLite authentication - $this->_credentials = new Zend_Service_WindowsAzure_Credentials_SharedKeyLite($accountName, $accountKey, $this->_usePathStyleUri); - - // API version - $this->_apiVersion = '2009-09-19'; - } - - /** - * Check if a table exists - * - * @param string $tableName Table name - * @return boolean - */ - public function tableExists($tableName = '') - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - - // List tables - $tables = $this->listTables(); // 2009-09-19 does not support $this->listTables($tableName); all of a sudden... - foreach ($tables as $table) { - if ($table->Name == $tableName) { - return true; - } - } - - return false; - } - - /** - * List tables - * - * @param string $nextTableName Next table name, used for listing tables when total amount of tables is > 1000. - * @return array - * @throws Zend_Service_WindowsAzure_Exception - */ - public function listTables($nextTableName = '') - { - // Build query string - $queryString = array(); - if ($nextTableName != '') { - $queryString[] = 'NextTableName=' . $nextTableName; - } - $queryString = self::createQueryStringFromArray($queryString); - - // Perform request - $response = $this->_performRequest('Tables', $queryString, Zend_Http_Client::GET, null, true); - if ($response->isSuccessful()) { - // Parse result - $result = $this->_parseResponse($response); - - if (!$result || !$result->entry) { - return array(); - } - - $entries = null; - if (count($result->entry) > 1) { - $entries = $result->entry; - } else { - $entries = array($result->entry); - } - - // Create return value - $returnValue = array(); - foreach ($entries as $entry) { - $tableName = $entry->xpath('.//m:properties/d:TableName'); - $tableName = (string)$tableName[0]; - - $returnValue[] = new Zend_Service_WindowsAzure_Storage_TableInstance( - (string)$entry->id, - $tableName, - (string)$entry->link['href'], - (string)$entry->updated - ); - } - - // More tables? - if (!is_null($response->getHeader('x-ms-continuation-NextTableName'))) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - $returnValue = array_merge($returnValue, $this->listTables($response->getHeader('x-ms-continuation-NextTableName'))); - } - - return $returnValue; - } else { - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Create table - * - * @param string $tableName Table name - * @return Zend_Service_WindowsAzure_Storage_TableInstance - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createTable($tableName = '') - { - if ($tableName === '') { - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - - // Generate request body - $requestBody = ' - - - <updated>{tpl:Updated}</updated> - <author> - <name /> - </author> - <id /> - <content type="application/xml"> - <m:properties> - <d:TableName>{tpl:TableName}</d:TableName> - </m:properties> - </content> - </entry>'; - - $requestBody = $this->_fillTemplate($requestBody, array( - 'BaseUrl' => $this->getBaseUrl(), - 'TableName' => htmlspecialchars($tableName), - 'Updated' => $this->isoDate(), - 'AccountName' => $this->_accountName - )); - - // Add header information - $headers = array(); - $headers['Content-Type'] = 'application/atom+xml'; - $headers['DataServiceVersion'] = '1.0;NetFx'; - $headers['MaxDataServiceVersion'] = '1.0;NetFx'; - - // Perform request - $response = $this->_performRequest('Tables', '', Zend_Http_Client::POST, $headers, true, $requestBody); - if ($response->isSuccessful()) { - // Parse response - $entry = $this->_parseResponse($response); - - $tableName = $entry->xpath('.//m:properties/d:TableName'); - $tableName = (string)$tableName[0]; - - - return new Zend_Service_WindowsAzure_Storage_TableInstance( - (string)$entry->id, - $tableName, - (string)$entry->link['href'], - (string)$entry->updated - ); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Create table if it does not exist - * - * @param string $tableName Table name - * @throws Zend_Service_WindowsAzure_Exception - */ - public function createTableIfNotExists($tableName = '') - { - if (!$this->tableExists($tableName)) { - $this->createTable($tableName); - } - } - - /** - * Delete table - * - * @param string $tableName Table name - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteTable($tableName = '') - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - - // Add header information - $headers = array(); - $headers['Content-Type'] = 'application/atom+xml'; - - // Perform request - $response = $this->_performRequest('Tables(\'' . $tableName . '\')', '', Zend_Http_Client::DELETE, $headers, true, null); - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Insert entity into table - * - * @param string $tableName Table name - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to insert - * @return Zend_Service_WindowsAzure_Storage_TableEntity - * @throws Zend_Service_WindowsAzure_Exception - */ - public function insertEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null) - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - if (is_null($entity)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.'); - } - - // Generate request body - $requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?> - <entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> - <title /> - <updated>{tpl:Updated}</updated> - <author> - <name /> - </author> - <id /> - <content type="application/xml"> - <m:properties> - {tpl:Properties} - </m:properties> - </content> - </entry>'; - - $requestBody = $this->_fillTemplate($requestBody, array( - 'Updated' => $this->isoDate(), - 'Properties' => $this->_generateAzureRepresentation($entity) - )); - - // Add header information - $headers = array(); - $headers['Content-Type'] = 'application/atom+xml'; - - // Perform request - $response = null; - if ($this->isInBatch()) { - $this->getCurrentBatch()->enlistOperation($tableName, '', Zend_Http_Client::POST, $headers, true, $requestBody); - return null; - } else { - $response = $this->_performRequest($tableName, '', Zend_Http_Client::POST, $headers, true, $requestBody); - } - if ($response->isSuccessful()) { - // Parse result - $result = $this->_parseResponse($response); - - $timestamp = $result->xpath('//m:properties/d:Timestamp'); - $timestamp = $this->_convertToDateTime( (string)$timestamp[0] ); - - $etag = $result->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'); - $etag = (string)$etag['etag']; - - // Update properties - $entity->setTimestamp($timestamp); - $entity->setEtag($etag); - - return $entity; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Delete entity from table - * - * @param string $tableName Table name - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to delete - * @param boolean $verifyEtag Verify etag of the entity (used for concurrency) - * @throws Zend_Service_WindowsAzure_Exception - */ - public function deleteEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false) - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - if (is_null($entity)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.'); - } - - // Add header information - $headers = array(); - if (!$this->isInBatch()) { - // http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/9e255447-4dc7-458a-99d3-bdc04bdc5474/ - $headers['Content-Type'] = 'application/atom+xml'; - } - $headers['Content-Length'] = 0; - if (!$verifyEtag) { - $headers['If-Match'] = '*'; - } else { - $headers['If-Match'] = $entity->getEtag(); - } - - // Perform request - $response = null; - if ($this->isInBatch()) { - $this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Zend_Http_Client::DELETE, $headers, true, null); - return null; - } else { - $response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Zend_Http_Client::DELETE, $headers, true, null); - } - if (!$response->isSuccessful()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Retrieve entity from table, by id - * - * @param string $tableName Table name - * @param string $partitionKey Partition key - * @param string $rowKey Row key - * @param string $entityClass Entity class name* - * @return Zend_Service_WindowsAzure_Storage_TableEntity - * @throws Zend_Service_WindowsAzure_Exception - */ - public function retrieveEntityById($tableName, $partitionKey, $rowKey, $entityClass = 'Zend_Service_WindowsAzure_Storage_DynamicTableEntity') - { - if (is_null($tableName) || $tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - if (is_null($partitionKey) || $partitionKey === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Partition key is not specified.'); - } - if (is_null($rowKey) || $rowKey === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Row key is not specified.'); - } - if (is_null($entityClass) || $entityClass === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity class is not specified.'); - } - - - // Check for combined size of partition key and row key - // http://msdn.microsoft.com/en-us/library/dd179421.aspx - if (strlen($partitionKey . $rowKey) >= 256) { - // Start a batch if possible - if ($this->isInBatch()) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity cannot be retrieved. A transaction is required to retrieve the entity, but another transaction is already active.'); - } - - $this->startBatch(); - } - - // Fetch entities from Azure - $result = $this->retrieveEntities( - $this->select() - ->from($tableName) - ->wherePartitionKey($partitionKey) - ->whereRowKey($rowKey), - '', - $entityClass - ); - - // Return - if (count($result) == 1) { - return $result[0]; - } - - return null; - } - - /** - * Create a new Zend_Service_WindowsAzure_Storage_TableEntityQuery - * - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function select() - { - - return new Zend_Service_WindowsAzure_Storage_TableEntityQuery(); - } - - /** - * Retrieve entities from table - * - * @param string $tableName|Zend_Service_WindowsAzure_Storage_TableEntityQuery Table name -or- Zend_Service_WindowsAzure_Storage_TableEntityQuery instance - * @param string $filter Filter condition (not applied when $tableName is a Zend_Service_WindowsAzure_Storage_TableEntityQuery instance) - * @param string $entityClass Entity class name - * @param string $nextPartitionKey Next partition key, used for listing entities when total amount of entities is > 1000. - * @param string $nextRowKey Next row key, used for listing entities when total amount of entities is > 1000. - * @return array Array of Zend_Service_WindowsAzure_Storage_TableEntity - * @throws Zend_Service_WindowsAzure_Exception - */ - public function retrieveEntities($tableName = '', $filter = '', $entityClass = 'Zend_Service_WindowsAzure_Storage_DynamicTableEntity', $nextPartitionKey = null, $nextRowKey = null) - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - if ($entityClass === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity class is not specified.'); - } - - // Convenience... - if (class_exists($filter)) { - $entityClass = $filter; - $filter = ''; - } - - // Query string - $queryString = ''; - - // Determine query - if (is_string($tableName)) { - // Option 1: $tableName is a string - - // Append parentheses - if (strpos($tableName, '()') === false) { - $tableName .= '()'; - } - - // Build query - $query = array(); - - // Filter? - if ($filter !== '') { - $query[] = '$filter=' . Zend_Service_WindowsAzure_Storage_TableEntityQuery::encodeQuery($filter); - } - - // Build queryString - if (count($query) > 0) { - $queryString = '?' . implode('&', $query); - } - } else if (get_class($tableName) == 'Zend_Service_WindowsAzure_Storage_TableEntityQuery') { - // Option 2: $tableName is a Zend_Service_WindowsAzure_Storage_TableEntityQuery instance - - // Build queryString - $queryString = $tableName->assembleQueryString(true); - - // Change $tableName - $tableName = $tableName->assembleFrom(true); - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Invalid argument: $tableName'); - } - - // Add continuation querystring parameters? - if (!is_null($nextPartitionKey) && !is_null($nextRowKey)) { - if ($queryString !== '') { - $queryString .= '&'; - } else { - $queryString .= '?'; - } - - $queryString .= 'NextPartitionKey=' . rawurlencode($nextPartitionKey) . '&NextRowKey=' . rawurlencode($nextRowKey); - } - - // Perform request - $response = null; - if ($this->isInBatch() && $this->getCurrentBatch()->getOperationCount() == 0) { - $this->getCurrentBatch()->enlistOperation($tableName, $queryString, Zend_Http_Client::GET, array(), true, null); - $response = $this->getCurrentBatch()->commit(); - - // Get inner response (multipart) - $innerResponse = $response->getBody(); - $innerResponse = substr($innerResponse, strpos($innerResponse, 'HTTP/1.1 200 OK')); - $innerResponse = substr($innerResponse, 0, strpos($innerResponse, '--batchresponse')); - $response = Zend_Http_Response::fromString($innerResponse); - } else { - $response = $this->_performRequest($tableName, $queryString, Zend_Http_Client::GET, array(), true, null); - } - - if ($response->isSuccessful()) { - // Parse result - $result = $this->_parseResponse($response); - if (!$result) { - return array(); - } - - $entries = null; - if ($result->entry) { - if (count($result->entry) > 1) { - $entries = $result->entry; - } else { - $entries = array($result->entry); - } - } else { - // This one is tricky... If we have properties defined, we have an entity. - $properties = $result->xpath('//m:properties'); - if ($properties) { - $entries = array($result); - } else { - return array(); - } - } - - // Create return value - $returnValue = array(); - foreach ($entries as $entry) { - // Parse properties - $properties = $entry->xpath('.//m:properties'); - $properties = $properties[0]->children('http://schemas.microsoft.com/ado/2007/08/dataservices'); - - // Create entity - $entity = new $entityClass('', ''); - $entity->setAzureValues((array)$properties, $this->_throwExceptionOnMissingData); - - // If we have a Zend_Service_WindowsAzure_Storage_DynamicTableEntity, make sure all property types are set - if ($entity instanceof Zend_Service_WindowsAzure_Storage_DynamicTableEntity) { - foreach ($properties as $key => $value) { - $attributes = $value->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'); - $type = (string)$attributes['type']; - if ($type !== '') { - $entity->setAzureProperty($key, (string)$value, $type); - } - } - } - - // Update etag - $etag = $entry->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'); - $etag = (string)$etag['etag']; - $entity->setEtag($etag); - - // Add to result - $returnValue[] = $entity; - } - - // More entities? - if (!is_null($response->getHeader('x-ms-continuation-NextPartitionKey')) && !is_null($response->getHeader('x-ms-continuation-NextRowKey'))) { - if (strpos($queryString, '$top') === false) { - $returnValue = array_merge($returnValue, $this->retrieveEntities($tableName, $filter, $entityClass, $response->getHeader('x-ms-continuation-NextPartitionKey'), $response->getHeader('x-ms-continuation-NextRowKey'))); - } - } - - // Return - return $returnValue; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Update entity by replacing it - * - * @param string $tableName Table name - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update - * @param boolean $verifyEtag Verify etag of the entity (used for concurrency) - * @throws Zend_Service_WindowsAzure_Exception - */ - public function updateEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false) - { - return $this->_changeEntity(Zend_Http_Client::PUT, $tableName, $entity, $verifyEtag); - } - - /** - * Update entity by adding or updating properties - * - * @param string $tableName Table name - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update - * @param boolean $verifyEtag Verify etag of the entity (used for concurrency) - * @param array $properties Properties to merge. All properties will be used when omitted. - * @throws Zend_Service_WindowsAzure_Exception - */ - public function mergeEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false, $properties = array()) - { - $mergeEntity = null; - if (is_array($properties) && count($properties) > 0) { - - // Build a new object - $mergeEntity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($entity->getPartitionKey(), $entity->getRowKey()); - - // Keep only values mentioned in $properties - $azureValues = $entity->getAzureValues(); - foreach ($azureValues as $key => $value) { - if (in_array($value->Name, $properties)) { - $mergeEntity->setAzureProperty($value->Name, $value->Value, $value->Type); - } - } - } else { - $mergeEntity = $entity; - } - - // Ensure entity timestamp matches updated timestamp - $entity->setTimestamp(new DateTime()); - - return $this->_changeEntity(Zend_Http_Client::MERGE, $tableName, $mergeEntity, $verifyEtag); - } - - /** - * Get error message from Zend_Http_Response - * - * @param Zend_Http_Response $response Repsonse - * @param string $alternativeError Alternative error message - * @return string - */ - protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') - { - $response = $this->_parseResponse($response); - if ($response && $response->message) { - return (string)$response->message; - } else { - return $alternativeError; - } - } - - /** - * Update entity / merge entity - * - * @param string $httpVerb HTTP verb to use (PUT = update, MERGE = merge) - * @param string $tableName Table name - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update - * @param boolean $verifyEtag Verify etag of the entity (used for concurrency) - * @throws Zend_Service_WindowsAzure_Exception - */ - protected function _changeEntity($httpVerb = Zend_Http_Client::PUT, $tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false) - { - if ($tableName === '') { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.'); - } - if (is_null($entity)) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.'); - } - - // Add header information - $headers = array(); - $headers['Content-Type'] = 'application/atom+xml'; - $headers['Content-Length'] = 0; - if (!$verifyEtag) { - $headers['If-Match'] = '*'; - } else { - $headers['If-Match'] = $entity->getEtag(); - } - - // Generate request body - $requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?> - <entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> - <title /> - <updated>{tpl:Updated}</updated> - <author> - <name /> - </author> - <id /> - <content type="application/xml"> - <m:properties> - {tpl:Properties} - </m:properties> - </content> - </entry>'; - - // Attempt to get timestamp from entity - $timestamp = $entity->getTimestamp(); - - $requestBody = $this->_fillTemplate($requestBody, array( - 'Updated' => $this->_convertToEdmDateTime($timestamp), - 'Properties' => $this->_generateAzureRepresentation($entity) - )); - - // Add header information - $headers = array(); - $headers['Content-Type'] = 'application/atom+xml'; - if (!$verifyEtag) { - $headers['If-Match'] = '*'; - } else { - $headers['If-Match'] = $entity->getEtag(); - } - - // Perform request - $response = null; - if ($this->isInBatch()) { - $this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody); - return null; - } else { - $response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody); - } - if ($response->isSuccessful()) { - // Update properties - $entity->setEtag($response->getHeader('Etag')); - $entity->setTimestamp( $this->_convertToDateTime($response->getHeader('Last-modified')) ); - - return $entity; - } else { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); - } - } - - /** - * Generate RFC 1123 compliant date string - * - * @return string - */ - protected function _rfcDate() - { - return gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123 - } - - /** - * Fill text template with variables from key/value array - * - * @param string $templateText Template text - * @param array $variables Array containing key/value pairs - * @return string - */ - protected function _fillTemplate($templateText, $variables = array()) - { - foreach ($variables as $key => $value) { - $templateText = str_replace('{tpl:' . $key . '}', $value, $templateText); - } - return $templateText; - } - - /** - * Generate Azure representation from entity (creates atompub markup from properties) - * - * @param Zend_Service_WindowsAzure_Storage_TableEntity $entity - * @return string - */ - protected function _generateAzureRepresentation(Zend_Service_WindowsAzure_Storage_TableEntity $entity = null) - { - // Generate Azure representation from entity - $azureRepresentation = array(); - $azureValues = $entity->getAzureValues(); - foreach ($azureValues as $azureValue) { - $value = array(); - $value[] = '<d:' . $azureValue->Name; - if ($azureValue->Type != '') { - $value[] = ' m:type="' . $azureValue->Type . '"'; - } - if (is_null($azureValue->Value)) { - $value[] = ' m:null="true"'; - } - $value[] = '>'; - - if (!is_null($azureValue->Value)) { - if (strtolower($azureValue->Type) == 'edm.boolean') { - $value[] = ($azureValue->Value == true ? '1' : '0'); - } else if (strtolower($azureValue->Type) == 'edm.datetime') { - $value[] = $this->_convertToEdmDateTime($azureValue->Value); - } else { - $value[] = htmlspecialchars($azureValue->Value); - } - } - - $value[] = '</d:' . $azureValue->Name . '>'; - $azureRepresentation[] = implode('', $value); - } - - return implode('', $azureRepresentation); - } - - /** - * Perform request using Zend_Http_Client channel - * - * @param string $path Path - * @param string $queryString Query string - * @param string $httpVerb HTTP verb the request will use - * @param array $headers x-ms headers to add - * @param boolean $forTableStorage Is the request for table storage? - * @param mixed $rawData Optional RAW HTTP data to be sent over the wire - * @param string $resourceType Resource type - * @param string $requiredPermission Required permission - * @return Zend_Http_Response - */ - protected function _performRequest( - $path = '/', - $queryString = '', - $httpVerb = Zend_Http_Client::GET, - $headers = array(), - $forTableStorage = false, - $rawData = null, - $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, - $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ - ) { - // Add headers - $headers['DataServiceVersion'] = '1.0;NetFx'; - $headers['MaxDataServiceVersion'] = '1.0;NetFx'; - - // Perform request - return parent::_performRequest( - $path, - $queryString, - $httpVerb, - $headers, - $forTableStorage, - $rawData, - $resourceType, - $requiredPermission - ); - } - - /** - * Converts a string to a DateTime object. Returns false on failure. - * - * @param string $value The string value to parse - * @return DateTime|boolean - */ - protected function _convertToDateTime($value = '') - { - if ($value instanceof DateTime) { - return $value; - } - - try { - if (substr($value, -1) == 'Z') { - $value = substr($value, 0, strlen($value) - 1); - } - return new DateTime($value, new DateTimeZone('UTC')); - } - catch (Exception $ex) { - return false; - } - } - - /** - * Converts a DateTime object into an Edm.DaeTime value in UTC timezone, - * represented as a string. - * - * @param DateTime $value - * @return string - */ - protected function _convertToEdmDateTime(DateTime $value) - { - $cloned = clone $value; - $cloned->setTimezone(new DateTimeZone('UTC')); - return str_replace('+0000', 'Z', $cloned->format(DateTime::ISO8601)); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/TableEntity.php b/lib/Zend/Service/WindowsAzure/Storage/TableEntity.php deleted file mode 100644 index 9ac374d1b66..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/TableEntity.php +++ /dev/null @@ -1,354 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_WindowsAzure_Storage_TableEntity -{ - /** - * Partition key - * - * @var string - */ - protected $_partitionKey; - - /** - * Row key - * - * @var string - */ - protected $_rowKey; - - /** - * Timestamp - * - * @var string - */ - protected $_timestamp; - - /** - * Etag - * - * @var string - */ - protected $_etag = ''; - - /** - * Constructor - * - * @param string $partitionKey Partition key - * @param string $rowKey Row key - */ - public function __construct($partitionKey = '', $rowKey = '') - { - $this->_partitionKey = $partitionKey; - $this->_rowKey = $rowKey; - } - - /** - * Get partition key - * - * @azure PartitionKey - * @return string - */ - public function getPartitionKey() - { - return $this->_partitionKey; - } - - /** - * Set partition key - * - * @azure PartitionKey - * @param string $value - */ - public function setPartitionKey($value) - { - $this->_partitionKey = $value; - } - - /** - * Get row key - * - * @azure RowKey - * @return string - */ - public function getRowKey() - { - return $this->_rowKey; - } - - /** - * Set row key - * - * @azure RowKey - * @param string $value - */ - public function setRowKey($value) - { - $this->_rowKey = $value; - } - - /** - * Get timestamp - * - * @azure Timestamp Edm.DateTime - * @return string - */ - public function getTimestamp() - { - if (null === $this->_timestamp) { - $this->setTimestamp(new DateTime()); - } - return $this->_timestamp; - } - - /** - * Set timestamp - * - * @azure Timestamp Edm.DateTime - * @param DateTime $value - */ - public function setTimestamp(DateTime $value) - { - $this->_timestamp = $value; - } - - /** - * Get etag - * - * @return string - */ - public function getEtag() - { - return $this->_etag; - } - - /** - * Set etag - * - * @param string $value - */ - public function setEtag($value = '') - { - $this->_etag = $value; - } - - /** - * Get Azure values - * - * @return array - */ - public function getAzureValues() - { - // Get accessors - $accessors = self::getAzureAccessors(get_class($this)); - - // Loop accessors and retrieve values - $returnValue = array(); - foreach ($accessors as $accessor) { - if ($accessor->EntityType == 'ReflectionProperty') { - $property = $accessor->EntityAccessor; - $returnValue[] = (object)array( - 'Name' => $accessor->AzurePropertyName, - 'Type' => $accessor->AzurePropertyType, - 'Value' => $this->$property, - ); - } else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'get') { - $method = $accessor->EntityAccessor; - $returnValue[] = (object)array( - 'Name' => $accessor->AzurePropertyName, - 'Type' => $accessor->AzurePropertyType, - 'Value' => $this->$method(), - ); - } - } - - // Return - return $returnValue; - } - - /** - * Set Azure values - * - * @param array $values - * @param boolean $throwOnError Throw Zend_Service_WindowsAzure_Exception when a property is not specified in $values? - * @throws Zend_Service_WindowsAzure_Exception - */ - public function setAzureValues($values = array(), $throwOnError = false) - { - // Get accessors - $accessors = self::getAzureAccessors(get_class($this)); - - // Loop accessors and set values - $returnValue = array(); - foreach ($accessors as $accessor) { - if (isset($values[$accessor->AzurePropertyName])) { - // Cast to correct type - if ($accessor->AzurePropertyType != '') { - switch (strtolower($accessor->AzurePropertyType)) { - case 'edm.int32': - case 'edm.int64': - $values[$accessor->AzurePropertyName] = intval($values[$accessor->AzurePropertyName]); break; - case 'edm.boolean': - if ($values[$accessor->AzurePropertyName] == 'true' || $values[$accessor->AzurePropertyName] == '1') - $values[$accessor->AzurePropertyName] = true; - else - $values[$accessor->AzurePropertyName] = false; - break; - case 'edm.double': - $values[$accessor->AzurePropertyName] = floatval($values[$accessor->AzurePropertyName]); break; - case 'edm.datetime': - $values[$accessor->AzurePropertyName] = $this->_convertToDateTime($values[$accessor->AzurePropertyName]); break; - } - } - - // Assign value - if ($accessor->EntityType == 'ReflectionProperty') { - $property = $accessor->EntityAccessor; - $this->$property = $values[$accessor->AzurePropertyName]; - } else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'set') { - $method = $accessor->EntityAccessor; - $this->$method($values[$accessor->AzurePropertyName]); - } - } else if ($throwOnError) { - #require_once 'Zend/Service/WindowsAzure/Exception.php'; - throw new Zend_Service_WindowsAzure_Exception("Property '" . $accessor->AzurePropertyName . "' was not found in \$values array"); - } - } - - // Return - return $returnValue; - } - - /** - * Get Azure accessors from class - * - * @param string $className Class to get accessors for - * @return array - */ - public static function getAzureAccessors($className = '') - { - // List of accessors - $azureAccessors = array(); - - // Get all types - $type = new ReflectionClass($className); - - // Loop all properties - $properties = $type->getProperties(); - foreach ($properties as $property) { - $accessor = self::getAzureAccessor($property); - if (!is_null($accessor)) { - $azureAccessors[] = $accessor; - } - } - - // Loop all methods - $methods = $type->getMethods(); - foreach ($methods as $method) { - $accessor = self::getAzureAccessor($method); - if (!is_null($accessor)) { - $azureAccessors[] = $accessor; - } - } - - // Return - return $azureAccessors; - } - - /** - * Get Azure accessor from reflection member - * - * @param ReflectionProperty|ReflectionMethod $member - * @return object - */ - public static function getAzureAccessor($member) - { - // Get comment - $docComment = $member->getDocComment(); - - // Check for Azure comment - if (strpos($docComment, '@azure') === false) - { - return null; - } - - // Search for @azure contents - $azureComment = ''; - $commentLines = explode("\n", $docComment); - foreach ($commentLines as $commentLine) { - if (strpos($commentLine, '@azure') !== false) { - $azureComment = trim(substr($commentLine, strpos($commentLine, '@azure') + 6)); - while (strpos($azureComment, ' ') !== false) { - $azureComment = str_replace(' ', ' ', $azureComment); - } - break; - } - } - - // Fetch @azure properties - $azureProperties = explode(' ', $azureComment); - return (object)array( - 'EntityAccessor' => $member->getName(), - 'EntityType' => get_class($member), - 'AzurePropertyName' => $azureProperties[0], - 'AzurePropertyType' => isset($azureProperties[1]) ? $azureProperties[1] : '' - ); - } - - /** - * Converts a string to a DateTime object. Returns false on failure. - * - * @param string $value The string value to parse - * @return DateTime|boolean - */ - protected function _convertToDateTime($value = '') - { - if ($value === '') { - return false; - } - - if ($value instanceof DateTime) { - return $value; - } - - if (@strtotime($value) !== false) { - try { - if (substr($value, -1) == 'Z') { - $value = substr($value, 0, strlen($value) - 1); - } - return new DateTime($value, new DateTimeZone('UTC')); - } - catch (Exception $ex) { - return false; - } - } - - return false; - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php b/lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php deleted file mode 100644 index 9b0ae93fcad..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php +++ /dev/null @@ -1,351 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_WindowsAzure_Storage_TableEntityQuery -{ - /** - * From - * - * @var string - */ - protected $_from = ''; - - /** - * Where - * - * @var array - */ - protected $_where = array(); - - /** - * Order by - * - * @var array - */ - protected $_orderBy = array(); - - /** - * Top - * - * @var int - */ - protected $_top = null; - - /** - * Partition key - * - * @var string - */ - protected $_partitionKey = null; - - /** - * Row key - * - * @var string - */ - protected $_rowKey = null; - - /** - * Select clause - * - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function select() - { - return $this; - } - - /** - * From clause - * - * @param string $name Table name to select entities from - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function from($name) - { - $this->_from = $name; - return $this; - } - - /** - * Specify partition key - * - * @param string $value Partition key to query for - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function wherePartitionKey($value = null) - { - $this->_partitionKey = $value; - return $this; - } - - /** - * Specify row key - * - * @param string $value Row key to query for - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function whereRowKey($value = null) - { - $this->_rowKey = $value; - return $this; - } - - /** - * Add where clause - * - * @param string $condition Condition, can contain question mark(s) (?) for parameter insertion. - * @param string|array $value Value(s) to insert in question mark (?) parameters. - * @param string $cond Condition for the clause (and/or/not) - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function where($condition, $value = null, $cond = '') - { - $condition = $this->_replaceOperators($condition); - - if (!is_null($value)) { - $condition = $this->_quoteInto($condition, $value); - } - - if (count($this->_where) == 0) { - $cond = ''; - } else if ($cond !== '') { - $cond = ' ' . strtolower(trim($cond)) . ' '; - } - - $this->_where[] = $cond . $condition; - return $this; - } - - /** - * Add where clause with AND condition - * - * @param string $condition Condition, can contain question mark(s) (?) for parameter insertion. - * @param string|array $value Value(s) to insert in question mark (?) parameters. - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function andWhere($condition, $value = null) - { - return $this->where($condition, $value, 'and'); - } - - /** - * Add where clause with OR condition - * - * @param string $condition Condition, can contain question mark(s) (?) for parameter insertion. - * @param string|array $value Value(s) to insert in question mark (?) parameters. - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function orWhere($condition, $value = null) - { - return $this->where($condition, $value, 'or'); - } - - /** - * OrderBy clause - * - * @param string $column Column to sort by - * @param string $direction Direction to sort (asc/desc) - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function orderBy($column, $direction = 'asc') - { - $this->_orderBy[] = $column . ' ' . $direction; - return $this; - } - - /** - * Top clause - * - * @param int $top Top to fetch - * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery - */ - public function top($top = null) - { - $this->_top = (int)$top; - return $this; - } - - /** - * Assembles the query string - * - * @param boolean $urlEncode Apply URL encoding to the query string - * @return string - */ - public function assembleQueryString($urlEncode = false) - { - $query = array(); - if (count($this->_where) != 0) { - $filter = implode('', $this->_where); - $query[] = '$filter=' . ($urlEncode ? self::encodeQuery($filter) : $filter); - } - - if (count($this->_orderBy) != 0) { - $orderBy = implode(',', $this->_orderBy); - $query[] = '$orderby=' . ($urlEncode ? self::encodeQuery($orderBy) : $orderBy); - } - - if (!is_null($this->_top)) { - $query[] = '$top=' . $this->_top; - } - - if (count($query) != 0) { - return '?' . implode('&', $query); - } - - return ''; - } - - /** - * Assemble from - * - * @param boolean $includeParentheses Include parentheses? () - * @return string - */ - public function assembleFrom($includeParentheses = true) - { - $identifier = ''; - if ($includeParentheses) { - $identifier .= '('; - - if (!is_null($this->_partitionKey)) { - $identifier .= 'PartitionKey=\'' . self::encodeQuery($this->_partitionKey) . '\''; - } - - if (!is_null($this->_partitionKey) && !is_null($this->_rowKey)) { - $identifier .= ', '; - } - - if (!is_null($this->_rowKey)) { - $identifier .= 'RowKey=\'' . self::encodeQuery($this->_rowKey) . '\''; - } - - $identifier .= ')'; - } - return $this->_from . $identifier; - } - - /** - * Assemble full query - * - * @return string - */ - public function assembleQuery() - { - $assembledQuery = $this->assembleFrom(); - - $queryString = $this->assembleQueryString(); - if ($queryString !== '') { - $assembledQuery .= $queryString; - } - - return $assembledQuery; - } - - /** - * Quotes a variable into a condition - * - * @param string $text Condition, can contain question mark(s) (?) for parameter insertion. - * @param string|array $value Value(s) to insert in question mark (?) parameters. - * @return string - */ - protected function _quoteInto($text, $value = null) - { - if (!is_array($value)) { - $text = str_replace('?', '\'' . addslashes($value) . '\'', $text); - } else { - $i = 0; - while(strpos($text, '?') !== false) { - if (is_numeric($value[$i])) { - $text = substr_replace($text, $value[$i++], strpos($text, '?'), 1); - } else { - $text = substr_replace($text, '\'' . addslashes($value[$i++]) . '\'', strpos($text, '?'), 1); - } - } - } - return $text; - } - - /** - * Replace operators - * - * @param string $text - * @return string - */ - protected function _replaceOperators($text) - { - $text = str_replace('==', 'eq', $text); - $text = str_replace('>', 'gt', $text); - $text = str_replace('<', 'lt', $text); - $text = str_replace('>=', 'ge', $text); - $text = str_replace('<=', 'le', $text); - $text = str_replace('!=', 'ne', $text); - - $text = str_replace('&&', 'and', $text); - $text = str_replace('||', 'or', $text); - $text = str_replace('!', 'not', $text); - - return $text; - } - - /** - * urlencode a query - * - * @param string $query Query to encode - * @return string Encoded query - */ - public static function encodeQuery($query) - { - $query = str_replace('/', '%2F', $query); - $query = str_replace('?', '%3F', $query); - $query = str_replace(':', '%3A', $query); - $query = str_replace('@', '%40', $query); - $query = str_replace('&', '%26', $query); - $query = str_replace('=', '%3D', $query); - $query = str_replace('+', '%2B', $query); - $query = str_replace(',', '%2C', $query); - $query = str_replace('$', '%24', $query); - $query = str_replace('{', '%7B', $query); - $query = str_replace('}', '%7D', $query); - - $query = str_replace(' ', '%20', $query); - - return $query; - } - - /** - * __toString overload - * - * @return string - */ - public function __toString() - { - return $this->assembleQuery(); - } -} diff --git a/lib/Zend/Service/WindowsAzure/Storage/TableInstance.php b/lib/Zend/Service/WindowsAzure/Storage/TableInstance.php deleted file mode 100644 index 2799449b466..00000000000 --- a/lib/Zend/Service/WindowsAzure/Storage/TableInstance.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Service_WindowsAzure_Storage_StorageEntityAbstract - */ -#require_once 'Zend/Service/WindowsAzure/Storage/StorageEntityAbstract.php'; - -/** - * @category Zend - * @package Zend_Service_WindowsAzure - * @subpackage Storage - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * - * @property string $Id Id - * @property string $Name Name - * @property string $Href Href - * @property string $Updated Updated - */ -class Zend_Service_WindowsAzure_Storage_TableInstance - extends Zend_Service_WindowsAzure_Storage_StorageEntityAbstract -{ - /** - * Constructor - * - * @param string $id Id - * @param string $name Name - * @param string $href Href - * @param string $updated Updated - */ - public function __construct($id, $name, $href, $updated) - { - $this->_data = array( - 'id' => $id, - 'name' => $name, - 'href' => $href, - 'updated' => $updated - ); - } -} diff --git a/lib/Zend/Service/Yahoo.php b/lib/Zend/Service/Yahoo.php deleted file mode 100644 index 0c632598219..00000000000 --- a/lib/Zend/Service/Yahoo.php +++ /dev/null @@ -1,951 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** @see Zend_Xml_Security */ -#require_once 'Zend/Xml/Security.php'; - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo -{ - /** - * Yahoo Developer Application ID - * - * @var string - */ - public $appId; - - /** - * Reference to the REST client - * - * @var Zend_Rest_Client - */ - protected $_rest; - - - /** - * Sets the application ID and instantiates the REST client - * - * @param string $appId specified the developer's appid - * @return void - */ - public function __construct($appId) - { - $this->appId = (string) $appId; - /** - * @see Zend_Rest_Client - */ - #require_once 'Zend/Rest/Client.php'; - $this->_rest = new Zend_Rest_Client('http://search.yahooapis.com'); - } - - - /** - * Retrieve Inlink Data from siteexplorer.yahoo.com. A basic query - * consists simply of a URL. Additional options that can be - * specified consist of: - * 'results' => int How many results to return, max is 100 - * 'start' => int The start offset for search results - * 'entire_site' => bool Data for the whole site or a single page - * 'omit_inlinks' => (none|domain|subdomain) Filter inlinks from these sources - * - * @param string $query the query being run - * @param array $options any optional parameters - * @return Zend_Service_Yahoo_ResultSet The return set - * @throws Zend_Service_Exception - */ - public function inlinkDataSearch($query, array $options = array()) - { - static $defaultOptions = array('results' => '50', - 'start' => 1); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - $this->_validateInlinkDataSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/SiteExplorerService/V1/inlinkData', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_Yahoo_InlinkDataResultSet - */ - #require_once 'Zend/Service/Yahoo/InlinkDataResultSet.php'; - return new Zend_Service_Yahoo_InlinkDataResultSet($dom); - } - - - /** - * Perform a search of images. The most basic query consists simply - * of a plain text search, but you can also specify the type of - * image, the format, color, etc. - * - * The specific options are: - * 'type' => (all|any|phrase) How to parse the query terms - * 'results' => int How many results to return, max is 50 - * 'start' => int The start offset for search results - * 'format' => (any|bmp|gif|jpeg|png) The type of images to search for - * 'coloration' => (any|color|bw) The coloration of images to search for - * 'adult_ok' => bool Flag to allow 'adult' images. - * - * @param string $query the query to be run - * @param array $options an optional array of query options - * @return Zend_Service_Yahoo_ImageResultSet the search results - * @throws Zend_Service_Exception - */ - public function imageSearch($query, array $options = array()) - { - static $defaultOptions = array('type' => 'all', - 'results' => 10, - 'start' => 1, - 'format' => 'any', - 'coloration' => 'any'); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - - $this->_validateImageSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/ImageSearchService/V1/imageSearch', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_YahooImageResultSet - */ - #require_once 'Zend/Service/Yahoo/ImageResultSet.php'; - return new Zend_Service_Yahoo_ImageResultSet($dom); - } - - - /** - * Perform a search on local.yahoo.com. The basic search - * consists of a query and some fragment of location information; - * for example zipcode, latitude/longitude, or street address. - * - * Query options include: - * 'results' => int How many results to return, max is 50 - * 'start' => int The start offset for search results - * 'sort' => (relevance|title|distance|rating) How to order your results - * - * 'radius' => float The radius (in miles) in which to search - * - * 'longitude' => float The longitude of the location to search around - * 'latitude' => float The latitude of the location to search around - * - * 'zip' => string The zipcode to search around - * - * 'street' => string The street address to search around - * 'city' => string The city for address search - * 'state' => string The state for address search - * 'location' => string An adhoc location string to search around - * - * @param string $query The query string you want to run - * @param array $options The search options, including location - * @return Zend_Service_Yahoo_LocalResultSet The results - * @throws Zend_Service_Exception - */ - public function localSearch($query, array $options = array()) - { - static $defaultOptions = array('results' => 10, - 'start' => 1, - 'sort' => 'distance', - 'radius' => 5); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - - $this->_validateLocalSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://local.yahooapis.com'); - $response = $this->_rest->restGet('/LocalSearchService/V1/localSearch', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_Yahoo_LocalResultSet - */ - #require_once 'Zend/Service/Yahoo/LocalResultSet.php'; - return new Zend_Service_Yahoo_LocalResultSet($dom); - } - - - /** - * Execute a search on news.yahoo.com. This method minimally takes a - * text query to search on. - * - * Query options coonsist of: - * - * 'results' => int How many results to return, max is 50 - * 'start' => int The start offset for search results - * 'sort' => (rank|date) How to order your results - * 'language' => lang The target document language to match - * 'type' => (all|any|phrase) How the query should be parsed - * 'site' => string A site to which your search should be restricted - * - * @param string $query The query to run - * @param array $options The array of optional parameters - * @return Zend_Service_Yahoo_NewsResultSet The query return set - * @throws Zend_Service_Exception - */ - public function newsSearch($query, array $options = array()) - { - static $defaultOptions = array('type' => 'all', - 'start' => 1, - 'sort' => 'rank'); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - - $this->_validateNewsSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/NewsSearchService/V1/newsSearch', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_Yahoo_NewsResultSet - */ - #require_once 'Zend/Service/Yahoo/NewsResultSet.php'; - return new Zend_Service_Yahoo_NewsResultSet($dom); - } - - - /** - * Retrieve Page Data from siteexplorer.yahoo.com. A basic query - * consists simply of a URL. Additional options that can be - * specified consist of: - * 'results' => int How many results to return, max is 100 - * 'start' => int The start offset for search results - * 'domain_only' => bool Data for just the given domain or all sub-domains also - * - * @param string $query the query being run - * @param array $options any optional parameters - * @return Zend_Service_Yahoo_ResultSet The return set - * @throws Zend_Service_Exception - */ - public function pageDataSearch($query, array $options = array()) - { - static $defaultOptions = array('results' => '50', - 'start' => 1); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - $this->_validatePageDataSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/SiteExplorerService/V1/pageData', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_Yahoo_PageDataResultSet - */ - #require_once 'Zend/Service/Yahoo/PageDataResultSet.php'; - return new Zend_Service_Yahoo_PageDataResultSet($dom); - } - - - /** - * Perform a search of videos. The most basic query consists simply - * of a plain text search, but you can also specify the format of - * video. - * - * The specific options are: - * 'type' => (all|any|phrase) How to parse the query terms - * 'results' => int How many results to return, max is 50 - * 'start' => int The start offset for search results - * 'format' => (any|avi|flash|mpeg|msmedia|quicktime|realmedia) The type of videos to search for - * 'adult_ok' => bool Flag to allow 'adult' videos. - * - * @param string $query the query to be run - * @param array $options an optional array of query options - * @return Zend_Service_Yahoo_VideoResultSet the search results - * @throws Zend_Service_Exception - */ - public function videoSearch($query, array $options = array()) - { - static $defaultOptions = array('type' => 'all', - 'results' => 10, - 'start' => 1, - 'format' => 'any'); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - - $this->_validateVideoSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/VideoSearchService/V1/videoSearch', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_YahooVideoResultSet - */ - #require_once 'Zend/Service/Yahoo/VideoResultSet.php'; - return new Zend_Service_Yahoo_VideoResultSet($dom); - } - - - /** - * Perform a web content search on search.yahoo.com. A basic query - * consists simply of a text query. Additional options that can be - * specified consist of: - * 'results' => int How many results to return, max is 50 - * 'start' => int The start offset for search results - * 'language' => lang The target document language to match - * 'type' => (all|any|phrase) How the query should be parsed - * 'site' => string A site to which your search should be restricted - * 'format' => (any|html|msword|pdf|ppt|rss|txt|xls) - * 'adult_ok' => bool permit 'adult' content in the search results - * 'similar_ok' => bool permit similar results in the result set - * 'country' => string The country code for the content searched - * 'license' => (any|cc_any|cc_commercial|cc_modifiable) The license of content being searched - * 'region' => The regional search engine on which the service performs the search. default us. - * - * @param string $query the query being run - * @param array $options any optional parameters - * @return Zend_Service_Yahoo_WebResultSet The return set - * @throws Zend_Service_Exception - */ - public function webSearch($query, array $options = array()) - { - static $defaultOptions = array('type' => 'all', - 'start' => 1, - 'results' => 10, - 'format' => 'any'); - - $options = $this->_prepareOptions($query, $options, $defaultOptions); - $this->_validateWebSearch($options); - - $this->_rest->getHttpClient()->resetParameters(); - $this->_rest->setUri('http://search.yahooapis.com'); - $response = $this->_rest->restGet('/WebSearchService/V1/webSearch', $options); - - if ($response->isError()) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('An error occurred sending request. Status code: ' . - $response->getStatus()); - } - - $dom = new DOMDocument(); - $dom = Zend_Xml_Security::scan($response->getBody(), $dom); - self::_checkErrors($dom); - - /** - * @see Zend_Service_Yahoo_WebResultSet - */ - #require_once 'Zend/Service/Yahoo/WebResultSet.php'; - return new Zend_Service_Yahoo_WebResultSet($dom); - } - - - /** - * Returns a reference to the REST client - * - * @return Zend_Rest_Client - */ - public function getRestClient() - { - return $this->_rest; - } - - - /** - * Validate Inlink Data Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateInlinkDataSearch(array $options) - { - $validOptions = array('appid', 'query', 'results', 'start', 'entire_site', 'omit_inlinks'); - - $this->_compareOptions($options, $validOptions); - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 100, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(100)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['omit_inlinks'])) { - $this->_validateInArray('omit_inlinks', $options['omit_inlinks'], array('none', 'domain', 'subdomain')); - } - } - - - /** - * Validate Image Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateImageSearch(array $options) - { - $validOptions = array('appid', 'query', 'type', 'results', 'start', 'format', 'coloration', 'adult_ok'); - - $this->_compareOptions($options, $validOptions); - - if (isset($options['type'])) { - switch($options['type']) { - case 'all': - case 'any': - case 'phrase': - break; - default: - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'type': '{$options['type']}'"); - } - } - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 50, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(50)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['format'])) { - switch ($options['format']) { - case 'any': - case 'bmp': - case 'gif': - case 'jpeg': - case 'png': - break; - default: - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'format': {$options['format']}"); - } - } - - if (isset($options['coloration'])) { - switch ($options['coloration']) { - case 'any': - case 'color': - case 'bw': - break; - default: - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'coloration': " - . "{$options['coloration']}"); - } - } - } - - - /** - * Validate Local Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateLocalSearch(array $options) - { - $validOptions = array('appid', 'query', 'results', 'start', 'sort', 'radius', 'street', - 'city', 'state', 'zip', 'location', 'latitude', 'longitude'); - - $this->_compareOptions($options, $validOptions); - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 20, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(20)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['longitude']) && !$between->setMin(-90)->setMax(90)->isValid($options['longitude'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'longitude': {$options['longitude']}"); - } - - if (isset($options['latitude']) && !$between->setMin(-180)->setMax(180)->isValid($options['latitude'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'latitude': {$options['latitude']}"); - } - - if (isset($options['zip']) && !preg_match('/(^\d{5}$)|(^\d{5}-\d{4}$)/', $options['zip'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'zip': {$options['zip']}"); - } - - $hasLocation = false; - $locationFields = array('street', 'city', 'state', 'zip', 'location'); - foreach ($locationFields as $field) { - if (isset($options[$field]) && $options[$field] != '') { - $hasLocation = true; - break; - } - } - - if (!$hasLocation && (!isset($options['latitude']) || !isset($options['longitude']))) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('Location data are required but missing'); - } - - if (!in_array($options['sort'], array('relevance', 'title', 'distance', 'rating'))) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'sort': {$options['sort']}"); - } - } - - - /** - * Validate News Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateNewsSearch(array $options) - { - $validOptions = array('appid', 'query', 'results', 'start', 'sort', 'language', 'type', 'site'); - - $this->_compareOptions($options, $validOptions); - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 50, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(50)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['language'])) { - $this->_validateLanguage($options['language']); - } - - $this->_validateInArray('sort', $options['sort'], array('rank', 'date')); - $this->_validateInArray('type', $options['type'], array('all', 'any', 'phrase')); - } - - - /** - * Validate Page Data Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validatePageDataSearch(array $options) - { - $validOptions = array('appid', 'query', 'results', 'start', 'domain_only'); - - $this->_compareOptions($options, $validOptions); - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 100, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(100)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - } - - - /** - * Validate Video Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateVideoSearch(array $options) - { - $validOptions = array('appid', 'query', 'type', 'results', 'start', 'format', 'adult_ok'); - - $this->_compareOptions($options, $validOptions); - - if (isset($options['type'])) { - $this->_validateInArray('type', $options['type'], array('all', 'any', 'phrase')); - } - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 50, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(50)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['format'])) { - $this->_validateInArray('format', $options['format'], array('any', 'avi', 'flash', 'mpeg', 'msmedia', 'quicktime', 'realmedia')); - } - } - - - /** - * Validate Web Search Options - * - * @param array $options - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateWebSearch(array $options) - { - $validOptions = array('appid', 'query', 'results', 'start', 'language', 'type', 'format', 'adult_ok', - 'similar_ok', 'country', 'site', 'subscription', 'license', 'region'); - - $this->_compareOptions($options, $validOptions); - - /** - * @see Zend_Validate_Between - */ - #require_once 'Zend/Validate/Between.php'; - $between = new Zend_Validate_Between(1, 100, true); - - if (isset($options['results']) && !$between->setMin(1)->setMax(100)->isValid($options['results'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'results': {$options['results']}"); - } - - if (isset($options['start']) && !$between->setMin(1)->setMax(1000)->isValid($options['start'])) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option 'start': {$options['start']}"); - } - - if (isset($options['language'])) { - $this->_validateLanguage($options['language']); - } - - $this->_validateInArray('type', $options['type'], array('all', 'any', 'phrase')); - $this->_validateInArray('format', $options['format'], array('any', 'html', 'msword', 'pdf', 'ppt', 'rss', - 'txt', 'xls')); - if (isset($options['license'])) { - $this->_validateInArray('license', $options['license'], array('any', 'cc_any', 'cc_commercial', - 'cc_modifiable')); - } - - if (isset($options['region'])){ - $this->_validateInArray('region', $options['region'], array('ar', 'au', 'at', 'br', 'ca', 'ct', 'dk', 'fi', - 'fr', 'de', 'in', 'id', 'it', 'my', 'mx', - 'nl', 'no', 'ph', 'ru', 'sg', 'es', 'se', - 'ch', 'th', 'uk', 'us')); - } - } - - - /** - * Prepare options for sending to Yahoo! - * - * @param string $query Search Query - * @param array $options User specified options - * @param array $defaultOptions Required/Default options - * @return array - */ - protected function _prepareOptions($query, array $options, array $defaultOptions = array()) - { - $options['appid'] = $this->appId; - $options['query'] = (string) $query; - - return array_merge($defaultOptions, $options); - } - - - /** - * Throws an exception if the chosen language is not supported - * - * @param string $lang Language code - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateLanguage($lang) - { - $languages = array('ar', 'bg', 'ca', 'szh', 'tzh', 'hr', 'cs', 'da', 'nl', 'en', 'et', 'fi', 'fr', 'de', 'el', - 'he', 'hu', 'is', 'id', 'it', 'ja', 'ko', 'lv', 'lt', 'no', 'fa', 'pl', 'pt', 'ro', 'ru', 'sk', 'sr', 'sl', - 'es', 'sv', 'th', 'tr' - ); - if (!in_array($lang, $languages)) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("The selected language '$lang' is not supported"); - } - } - - - /** - * Utility function to check for a difference between two arrays. - * - * @param array $options User specified options - * @param array $validOptions Valid options - * @return void - * @throws Zend_Service_Exception if difference is found (e.g., unsupported query option) - */ - protected function _compareOptions(array $options, array $validOptions) - { - $difference = array_diff(array_keys($options), $validOptions); - if ($difference) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('The following parameters are invalid: ' . join(', ', $difference)); - } - } - - - /** - * Check that a named value is in the given array - * - * @param string $name Name associated with the value - * @param mixed $value Value - * @param array $array Array in which to check for the value - * @return void - * @throws Zend_Service_Exception - */ - protected function _validateInArray($name, $value, array $array) - { - if (!in_array($value, $array)) { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception("Invalid value for option '$name': $value"); - } - } - - - /** - * Check if response is an error - * - * @param DOMDocument $dom DOM Object representing the result XML - * @return void - * @throws Zend_Service_Exception Thrown when the result from Yahoo! is an error - */ - protected static function _checkErrors(DOMDocument $dom) - { - $xpath = new DOMXPath($dom); - $xpath->registerNamespace('yapi', 'urn:yahoo:api'); - - if ($xpath->query('//yapi:Error')->length >= 1) { - $message = $xpath->query('//yapi:Error/yapi:Message/text()')->item(0)->data; - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception($message); - } - } -} diff --git a/lib/Zend/Service/Yahoo/Image.php b/lib/Zend/Service/Yahoo/Image.php deleted file mode 100644 index defdddec45f..00000000000 --- a/lib/Zend/Service/Yahoo/Image.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_Image -{ - /** - * Image URL - * - * @var string - */ - public $Url; - - /** - * Image height in pixels - * - * @var int - */ - public $Height; - - /** - * Image width in pixels - * - * @var int - */ - public $Width; - - - /** - * Initializes the image - * - * @param DOMNode $dom - * @param string $namespace - * @return void - */ - public function __construct(DOMNode $dom, $namespace) - { - $xpath = new DOMXPath($dom->ownerDocument); - $xpath->registerNamespace('yh', $namespace); - $this->Url = Zend_Uri::factory($xpath->query('./yh:Url/text()', $dom)->item(0)->data); - $this->Height = (int) $xpath->query('./yh:Height/text()', $dom)->item(0)->data; - $this->Width = (int) $xpath->query('./yh:Width/text()', $dom)->item(0)->data; - } -} diff --git a/lib/Zend/Service/Yahoo/ImageResult.php b/lib/Zend/Service/Yahoo/ImageResult.php deleted file mode 100644 index 4e1b9558de8..00000000000 --- a/lib/Zend/Service/Yahoo/ImageResult.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_ImageResult extends Zend_Service_Yahoo_Result -{ - /** - * Summary info for the image - * - * @var string - */ - public $Summary; - - /** - * The URL of the webpage hosting the image - * - * @var string - */ - public $RefererUrl; - - /** - * The size of the files in bytes - * - * @var string - */ - public $FileSize; - - /** - * The type of file (bmp, gif, jpeg, etc.) - * - * @var string - */ - public $FileFormat; - - /** - * The height of the image in pixels - * - * @var string - */ - public $Height; - - /** - * The width of the image in pixels - * - * @var string - */ - public $Width; - - /** - * The thubmnail image for the article, if it exists - * - * @var Zend_Service_Yahoo_Image - */ - public $Thumbnail; - - /** - * Image result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srchmi'; - - - /** - * Initializes the image result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array('Summary', 'RefererUrl', 'FileSize', 'FileFormat', 'Height', 'Width', 'Thumbnail'); - - parent::__construct($result); - - $this->_setThumbnail(); - } -} diff --git a/lib/Zend/Service/Yahoo/ImageResultSet.php b/lib/Zend/Service/Yahoo/ImageResultSet.php deleted file mode 100644 index 1d6fcad13c0..00000000000 --- a/lib/Zend/Service/Yahoo/ImageResultSet.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_ImageResult - */ -#require_once 'Zend/Service/Yahoo/ImageResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_ImageResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * Image result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srchmi'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_ImageResult - */ - public function current() - { - return new Zend_Service_Yahoo_ImageResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/InlinkDataResult.php b/lib/Zend/Service/Yahoo/InlinkDataResult.php deleted file mode 100644 index e12243cb6ea..00000000000 --- a/lib/Zend/Service/Yahoo/InlinkDataResult.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_InlinkDataResult extends Zend_Service_Yahoo_Result -{ - /** - * Web result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Initializes the web result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array(); - parent::__construct($result); - } -} diff --git a/lib/Zend/Service/Yahoo/InlinkDataResultSet.php b/lib/Zend/Service/Yahoo/InlinkDataResultSet.php deleted file mode 100644 index cc3836eae25..00000000000 --- a/lib/Zend/Service/Yahoo/InlinkDataResultSet.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_WebResult - */ -#require_once 'Zend/Service/Yahoo/InlinkDataResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_InlinkDataResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * Web result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_InlinkDataResult - */ - public function current() - { - return new Zend_Service_Yahoo_InlinkDataResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/LocalResult.php b/lib/Zend/Service/Yahoo/LocalResult.php deleted file mode 100644 index 3e865baf9e6..00000000000 --- a/lib/Zend/Service/Yahoo/LocalResult.php +++ /dev/null @@ -1,124 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_LocalResult extends Zend_Service_Yahoo_Result -{ - /** - * Street address of the result - * - * @var string - */ - public $Address; - - /** - * City in which the result resides - * - * @var string - */ - public $City; - - /** - * State in which the result resides - * - * @var string - */ - public $State; - - /** - * Phone number for the result - * - * @var string - */ - public $Phone; - - /** - * User-submitted rating for the result - * - * @var string - */ - public $Rating; - - /** - * The distance to the result from your specified location - * - * @var string - */ - public $Distance; - - /** - * A URL of a map for the result - * - * @var string - */ - public $MapUrl; - - /** - * The URL for the business website, if known - * - * @var string - */ - public $BusinessUrl; - - /** - * The URL for linking to the business website, if known - * - * @var string - */ - public $BusinessClickUrl; - - /** - * Local result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:lcl'; - - - /** - * Initializes the local result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array('Address','City', 'City', 'State', 'Phone', 'Rating', 'Distance', 'MapUrl', - 'BusinessUrl', 'BusinessClickUrl'); - - parent::__construct($result); - } -} diff --git a/lib/Zend/Service/Yahoo/LocalResultSet.php b/lib/Zend/Service/Yahoo/LocalResultSet.php deleted file mode 100644 index d64b53972b4..00000000000 --- a/lib/Zend/Service/Yahoo/LocalResultSet.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_LocalResult - */ -#require_once 'Zend/Service/Yahoo/LocalResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_LocalResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * The URL of a webpage containing a map graphic with all returned results plotted on it. - * - * @var string - */ - public $resultSetMapURL; - - /** - * Local result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:lcl'; - - - /** - * Initializes the local result set - * - * @param DOMDocument $dom - * @return void - */ - public function __construct(DOMDocument $dom) - { - parent::__construct($dom); - - $this->resultSetMapURL = $this->_xpath->query('//yh:ResultSetMapUrl/text()')->item(0)->data; - } - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_LocalResult - */ - public function current() - { - return new Zend_Service_Yahoo_LocalResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/NewsResult.php b/lib/Zend/Service/Yahoo/NewsResult.php deleted file mode 100644 index 83d25caccbb..00000000000 --- a/lib/Zend/Service/Yahoo/NewsResult.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_NewsResult extends Zend_Service_Yahoo_Result -{ - /** - * Sumamry text associated with the result article - * - * @var string - */ - public $Summary; - - /** - * The company who distributed the article - * - * @var string - */ - public $NewsSource; - - /** - * The URL for the company who distributed the article - * - * @var string - */ - public $NewsSourceUrl; - - /** - * The language the article is in - * - * @var string - */ - public $Language; - - /** - * The date the article was published (in unix timestamp format) - * - * @var string - */ - public $PublishDate; - - /** - * The date the article was modified (in unix timestamp format) - * - * @var string - */ - public $ModificationDate; - - /** - * The thubmnail image for the article, if it exists - * - * @var Zend_Service_Yahoo_Image - */ - public $Thumbnail; - - /** - * News result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:yn'; - - - /** - * Initializes the news result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array('Summary', 'NewsSource', 'NewsSourceUrl', 'Language', 'PublishDate', - 'ModificationDate', 'Thumbnail'); - - parent::__construct($result); - - $this->_setThumbnail(); - } -} diff --git a/lib/Zend/Service/Yahoo/NewsResultSet.php b/lib/Zend/Service/Yahoo/NewsResultSet.php deleted file mode 100644 index 7fd347cf30d..00000000000 --- a/lib/Zend/Service/Yahoo/NewsResultSet.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_NewsResult - */ -#require_once 'Zend/Service/Yahoo/NewsResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_NewsResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * News result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:yn'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_NewsResult - */ - public function current() - { - return new Zend_Service_Yahoo_NewsResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/PageDataResult.php b/lib/Zend/Service/Yahoo/PageDataResult.php deleted file mode 100644 index 2dc767a58a9..00000000000 --- a/lib/Zend/Service/Yahoo/PageDataResult.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_PageDataResult extends Zend_Service_Yahoo_Result -{ - /** - * Web result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Initializes the web result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array(); - parent::__construct($result); - } -} diff --git a/lib/Zend/Service/Yahoo/PageDataResultSet.php b/lib/Zend/Service/Yahoo/PageDataResultSet.php deleted file mode 100644 index 582f3966598..00000000000 --- a/lib/Zend/Service/Yahoo/PageDataResultSet.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_WebResult - */ -#require_once 'Zend/Service/Yahoo/PageDataResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_PageDataResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * Web result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_WebResult - */ - public function current() - { - return new Zend_Service_Yahoo_PageDataResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/Result.php b/lib/Zend/Service/Yahoo/Result.php deleted file mode 100644 index 6fba287df7d..00000000000 --- a/lib/Zend/Service/Yahoo/Result.php +++ /dev/null @@ -1,126 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_Result -{ - /** - * The title of the search entry - * - * @var string - */ - public $Title; - - /** - * The URL of the found object - * - * @var string - */ - public $Url; - - /** - * The URL for linking to the found object - * - * @var string - */ - public $ClickUrl; - - /** - * Result fields - * - * @var array - */ - protected $_fields; - - /** - * REST response fragment for the result - * - * @var DOMElement - */ - protected $_result; - - /** - * Object for XPath queries - * - * @var DOMXPath - */ - protected $_xpath; - - - /** - * Initializes the result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - // default fields for all search results: - $fields = array('Title', 'Url', 'ClickUrl'); - - // merge w/ child's fields - $this->_fields = array_merge($this->_fields, $fields); - - $this->_xpath = new DOMXPath($result->ownerDocument); - $this->_xpath->registerNamespace('yh', $this->_namespace); - - // add search results to appropriate fields - - foreach ($this->_fields as $f) { - $query = "./yh:$f/text()"; - $node = $this->_xpath->query($query, $result); - if ($node->length == 1) { - $this->{$f} = $node->item(0)->data; - } - } - - $this->_result = $result; - } - - - /** - * Sets the Thumbnail property - * - * @return void - */ - protected function _setThumbnail() - { - $node = $this->_xpath->query('./yh:Thumbnail', $this->_result); - if ($node->length == 1) { - /** - * @see Zend_Service_Yahoo_Image - */ - #require_once 'Zend/Service/Yahoo/Image.php'; - $this->Thumbnail = new Zend_Service_Yahoo_Image($node->item(0), $this->_namespace); - } else { - $this->Thumbnail = null; - } - } -} diff --git a/lib/Zend/Service/Yahoo/ResultSet.php b/lib/Zend/Service/Yahoo/ResultSet.php deleted file mode 100644 index b81f0a28cbd..00000000000 --- a/lib/Zend/Service/Yahoo/ResultSet.php +++ /dev/null @@ -1,195 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_ResultSet implements SeekableIterator -{ - /** - * Total number of results available - * - * @var int - */ - public $totalResultsAvailable; - - /** - * The number of results in this result set - * - * @var int - */ - public $totalResultsReturned; - - /** - * The offset in the total result set of this search set - * - * @var int - */ - public $firstResultPosition; - - /** - * A DOMNodeList of results - * - * @var DOMNodeList - */ - protected $_results; - - /** - * Yahoo Web Service Return Document - * - * @var DOMDocument - */ - protected $_dom; - - /** - * Xpath Object for $this->_dom - * - * @var DOMXPath - */ - protected $_xpath; - - /** - * Current Index for SeekableIterator - * - * @var int - */ - protected $_currentIndex = 0; - - - /** - * Parse the search response and retrieve the results for iteration - * - * @param DOMDocument $dom the REST fragment for this object - * @return void - */ - public function __construct(DOMDocument $dom) - { - $this->totalResultsAvailable = (int) $dom->documentElement->getAttribute('totalResultsAvailable'); - $this->totalResultsReturned = (int) $dom->documentElement->getAttribute('totalResultsReturned'); - $this->firstResultPosition = (int) $dom->documentElement->getAttribute('firstResultPosition'); - - $this->_dom = $dom; - $this->_xpath = new DOMXPath($dom); - - $this->_xpath->registerNamespace('yh', $this->_namespace); - - $this->_results = $this->_xpath->query('//yh:Result'); - } - - - /** - * Total Number of results returned - * - * @return int Total number of results returned - */ - public function totalResults() - { - return $this->totalResultsReturned; - } - - - /** - * Implement SeekableIterator::current() - * - * Must be implemented by child classes - * - * @throws Zend_Service_Exception - * @return Zend_Service_Yahoo_Result - */ - public function current() - { - /** - * @see Zend_Service_Exception - */ - #require_once 'Zend/Service/Exception.php'; - throw new Zend_Service_Exception('Zend_Service_Yahoo_ResultSet::current() must be implemented by child ' - . 'classes'); - } - - - /** - * Implement SeekableIterator::key() - * - * @return int - */ - public function key() - { - return $this->_currentIndex; - } - - - /** - * Implement SeekableIterator::next() - * - * @return void - */ - public function next() - { - $this->_currentIndex += 1; - } - - - /** - * Implement SeekableIterator::rewind() - * - * @return void - */ - public function rewind() - { - $this->_currentIndex = 0; - } - - - /** - * Implement SeekableIterator::seek() - * - * @param int $index - * @return void - * @throws OutOfBoundsException - */ - public function seek($index) - { - $indexInt = (int) $index; - if ($indexInt >= 0 && $indexInt < $this->_results->length) { - $this->_currentIndex = $indexInt; - } else { - throw new OutOfBoundsException("Illegal index '$index'"); - } - } - - - /** - * Implement SeekableIterator::valid() - * - * @return boolean - */ - public function valid() - { - return $this->_currentIndex < $this->_results->length; - } -} diff --git a/lib/Zend/Service/Yahoo/VideoResult.php b/lib/Zend/Service/Yahoo/VideoResult.php deleted file mode 100644 index 1f177fcbdfd..00000000000 --- a/lib/Zend/Service/Yahoo/VideoResult.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_VideoResult extends Zend_Service_Yahoo_Result -{ - /** - * Summary info for the video - * - * @var string - */ - public $Summary; - - /** - * The URL of the webpage hosting the video - * - * @var string - */ - public $RefererUrl; - - /** - * The size of the files in bytes - * - * @var string - */ - public $FileSize; - - /** - * The type of file (bmp, gif, jpeg, etc.) - * - * @var string - */ - public $FileFormat; - - /** - * The height of the video in pixels - * - * @var string - */ - public $Height; - - /** - * The width of the video in pixels - * - * @var string - */ - public $Width; - - /** - * The duration of the video in seconds - * - * @var string - */ - public $Duration; - - /** - * The number of audio channels in the video - * - * @var string - */ - public $Channels; - - /** - * Whether the video is streamed or not - * - * @var boolean - */ - public $Streaming; - - /** - * The thubmnail video for the article, if it exists - * - * @var Zend_Service_Yahoo_Video - */ - public $Thumbnail; - - /** - * Video result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srchmv'; - - - /** - * Initializes the video result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array('Summary', 'RefererUrl', 'FileSize', 'FileFormat', 'Height', 'Width', 'Duration', 'Channels', 'Streaming', 'Thumbnail'); - - parent::__construct($result); - - $this->_setThumbnail(); - } -} diff --git a/lib/Zend/Service/Yahoo/VideoResultSet.php b/lib/Zend/Service/Yahoo/VideoResultSet.php deleted file mode 100644 index a5dece73f33..00000000000 --- a/lib/Zend/Service/Yahoo/VideoResultSet.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_VideoResult - */ -#require_once 'Zend/Service/Yahoo/VideoResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_VideoResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * Video result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srchmv'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_VideoResult - */ - public function current() - { - return new Zend_Service_Yahoo_VideoResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Service/Yahoo/WebResult.php b/lib/Zend/Service/Yahoo/WebResult.php deleted file mode 100644 index d0f3affc9ce..00000000000 --- a/lib/Zend/Service/Yahoo/WebResult.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_Result - */ -#require_once 'Zend/Service/Yahoo/Result.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_WebResult extends Zend_Service_Yahoo_Result -{ - /** - * A summary of the result - * - * @var string - */ - public $Summary; - - /** - * The file type of the result (text, html, pdf, etc.) - * - * @var string - */ - public $MimeType; - - /** - * The modification time of the result (as a unix timestamp) - * - * @var string - */ - public $ModificationDate; - - /** - * The URL for the Yahoo cache of this page, if it exists - * - * @var string - */ - public $CacheUrl; - - /** - * The size of the cache entry - * - * @var int - */ - public $CacheSize; - - /** - * Web result namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Initializes the web result - * - * @param DOMElement $result - * @return void - */ - public function __construct(DOMElement $result) - { - $this->_fields = array('Summary', 'MimeType', 'ModificationDate'); - parent::__construct($result); - - $this->_xpath = new DOMXPath($result->ownerDocument); - $this->_xpath->registerNamespace('yh', $this->_namespace); - - // check if the cache section exists - $cacheUrl = $this->_xpath->query('./yh:Cache/yh:Url/text()', $result)->item(0); - if ($cacheUrl instanceof DOMNode) - { - $this->CacheUrl = $cacheUrl->data; - } - $cacheSize = $this->_xpath->query('./yh:Cache/yh:Size/text()', $result)->item(0); - if ($cacheSize instanceof DOMNode) - { - $this->CacheSize = (int) $cacheSize->data; - } - } -} diff --git a/lib/Zend/Service/Yahoo/WebResultSet.php b/lib/Zend/Service/Yahoo/WebResultSet.php deleted file mode 100644 index a9b7fb13ab5..00000000000 --- a/lib/Zend/Service/Yahoo/WebResultSet.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -/** - * @see Zend_Service_Yahoo_ResultSet - */ -#require_once 'Zend/Service/Yahoo/ResultSet.php'; - - -/** - * @see Zend_Service_Yahoo_WebResult - */ -#require_once 'Zend/Service/Yahoo/WebResult.php'; - - -/** - * @category Zend - * @package Zend_Service - * @subpackage Yahoo - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Service_Yahoo_WebResultSet extends Zend_Service_Yahoo_ResultSet -{ - /** - * Web result set namespace - * - * @var string - */ - protected $_namespace = 'urn:yahoo:srch'; - - - /** - * Overrides Zend_Service_Yahoo_ResultSet::current() - * - * @return Zend_Service_Yahoo_WebResult - */ - public function current() - { - return new Zend_Service_Yahoo_WebResult($this->_results->item($this->_currentIndex)); - } -} diff --git a/lib/Zend/Session.php b/lib/Zend/Session.php deleted file mode 100644 index 8281631b06b..00000000000 --- a/lib/Zend/Session.php +++ /dev/null @@ -1,912 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - - -/** - * @see Zend_Session_Abstract - */ -#require_once 'Zend/Session/Abstract.php'; - -/** - * @see Zend_Session_Namespace - */ -#require_once 'Zend/Session/Namespace.php'; - -/** - * @see Zend_Session_SaveHandler_Interface - */ -#require_once 'Zend/Session/SaveHandler/Interface.php'; - - -/** - * Zend_Session - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session extends Zend_Session_Abstract -{ - /** - * Whether or not Zend_Session is being used with unit tests - * - * @internal - * @var bool - */ - public static $_unitTestEnabled = false; - - /** - * $_throwStartupException - * - * @var bool|bitset This could also be a combiniation of error codes to catch - */ - protected static $_throwStartupExceptions = true; - - /** - * Check whether or not the session was started - * - * @var bool - */ - private static $_sessionStarted = false; - - /** - * Whether or not the session id has been regenerated this request. - * - * Id regeneration state - * <0 - regenerate requested when session is started - * 0 - do nothing - * >0 - already called session_regenerate_id() - * - * @var int - */ - private static $_regenerateIdState = 0; - - /** - * Private list of php's ini values for ext/session - * null values will default to the php.ini value, otherwise - * the value below will overwrite the default ini value, unless - * the user has set an option explicity with setOptions() - * - * @var array - */ - private static $_defaultOptions = array( - 'save_path' => null, - 'name' => null, /* this should be set to a unique value for each application */ - 'save_handler' => null, - //'auto_start' => null, /* intentionally excluded (see manual) */ - 'gc_probability' => null, - 'gc_divisor' => null, - 'gc_maxlifetime' => null, - 'serialize_handler' => null, - 'cookie_lifetime' => null, - 'cookie_path' => null, - 'cookie_domain' => null, - 'cookie_secure' => null, - 'cookie_httponly' => null, - 'use_cookies' => null, - 'use_only_cookies' => 'on', - 'referer_check' => null, - 'entropy_file' => null, - 'entropy_length' => null, - 'cache_limiter' => null, - 'cache_expire' => null, - 'use_trans_sid' => null, - 'bug_compat_42' => null, - 'bug_compat_warn' => null, - 'hash_function' => null, - 'hash_bits_per_character' => null - ); - - /** - * List of options pertaining to Zend_Session that can be set by developers - * using Zend_Session::setOptions(). This list intentionally duplicates - * the individual declaration of static "class" variables by the same names. - * - * @var array - */ - private static $_localOptions = array( - 'strict' => '_strict', - 'remember_me_seconds' => '_rememberMeSeconds', - 'throw_startup_exceptions' => '_throwStartupExceptions' - ); - - /** - * Whether or not write close has been performed. - * - * @var bool - */ - private static $_writeClosed = false; - - /** - * Whether or not session id cookie has been deleted - * - * @var bool - */ - private static $_sessionCookieDeleted = false; - - /** - * Whether or not session has been destroyed via session_destroy() - * - * @var bool - */ - private static $_destroyed = false; - - /** - * Whether or not session must be initiated before usage - * - * @var bool - */ - private static $_strict = false; - - /** - * Default number of seconds the session will be remembered for when asked to be remembered - * - * @var int - */ - private static $_rememberMeSeconds = 1209600; // 2 weeks - - /** - * Whether the default options listed in Zend_Session::$_localOptions have been set - * - * @var bool - */ - private static $_defaultOptionsSet = false; - - /** - * A reference to the set session save handler - * - * @var Zend_Session_SaveHandler_Interface - */ - private static $_saveHandler = null; - - - /** - * Constructor overriding - make sure that a developer cannot instantiate - */ - protected function __construct() - { - } - - - /** - * setOptions - set both the class specified - * - * @param array $userOptions - pass-by-keyword style array of <option name, option value> pairs - * @throws Zend_Session_Exception - * @return void - */ - public static function setOptions(array $userOptions = array()) - { - // set default options on first run only (before applying user settings) - if (!self::$_defaultOptionsSet) { - foreach (self::$_defaultOptions as $defaultOptionName => $defaultOptionValue) { - if (isset(self::$_defaultOptions[$defaultOptionName])) { - ini_set("session.$defaultOptionName", $defaultOptionValue); - } - } - - self::$_defaultOptionsSet = true; - } - - // set the options the user has requested to set - foreach ($userOptions as $userOptionName => $userOptionValue) { - - $userOptionName = strtolower($userOptionName); - - // set the ini based values - if (array_key_exists($userOptionName, self::$_defaultOptions)) { - ini_set("session.$userOptionName", $userOptionValue); - } - elseif (isset(self::$_localOptions[$userOptionName])) { - self::${self::$_localOptions[$userOptionName]} = $userOptionValue; - } - else { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("Unknown option: $userOptionName = $userOptionValue"); - } - } - } - - /** - * getOptions() - * - * @param string $optionName OPTIONAL - * @return array|string - */ - public static function getOptions($optionName = null) - { - $options = array(); - foreach (ini_get_all('session') as $sysOptionName => $sysOptionValues) { - $options[substr($sysOptionName, 8)] = $sysOptionValues['local_value']; - } - foreach (self::$_localOptions as $localOptionName => $localOptionMemberName) { - $options[$localOptionName] = self::${$localOptionMemberName}; - } - - if ($optionName) { - if (array_key_exists($optionName, $options)) { - return $options[$optionName]; - } - return null; - } - - return $options; - } - - /** - * setSaveHandler() - Session Save Handler assignment - * - * @param Zend_Session_SaveHandler_Interface $interface - * @throws Zend_Session_Exception When the session_set_save_handler call fails - * @return void - */ - public static function setSaveHandler(Zend_Session_SaveHandler_Interface $saveHandler) - { - self::$_saveHandler = $saveHandler; - - if (self::$_unitTestEnabled) { - return; - } - - $result = session_set_save_handler( - array(&$saveHandler, 'open'), - array(&$saveHandler, 'close'), - array(&$saveHandler, 'read'), - array(&$saveHandler, 'write'), - array(&$saveHandler, 'destroy'), - array(&$saveHandler, 'gc') - ); - - if (!$result) { - throw new Zend_Session_Exception('Unable to set session handler'); - } - } - - - /** - * getSaveHandler() - Get the session Save Handler - * - * @return Zend_Session_SaveHandler_Interface - */ - public static function getSaveHandler() - { - return self::$_saveHandler; - } - - - /** - * regenerateId() - Regenerate the session id. Best practice is to call this after - * session is started. If called prior to session starting, session id will be regenerated - * at start time. - * - * @throws Zend_Session_Exception - * @return void - */ - public static function regenerateId() - { - if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ . - "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); - } - - if ( !self::$_sessionStarted ) { - self::$_regenerateIdState = -1; - } else { - if (!self::$_unitTestEnabled) { - session_regenerate_id(true); - } - self::$_regenerateIdState = 1; - } - } - - - /** - * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of - * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems, - * large values are recommended to avoid undesirable expiration of session cookies. - * - * @param int $seconds OPTIONAL specifies TTL for cookie in seconds from present time - * @return void - */ - public static function rememberMe($seconds = null) - { - $seconds = (int) $seconds; - $seconds = ($seconds > 0) ? $seconds : self::$_rememberMeSeconds; - - self::rememberUntil($seconds); - } - - - /** - * forgetMe() - Write a volatile session cookie, removing any persistent cookie that may have existed. The session - * would end upon, for example, termination of a web browser program. - * - * @return void - */ - public static function forgetMe() - { - self::rememberUntil(0); - } - - - /** - * rememberUntil() - This method does the work of changing the state of the session cookie and making - * sure that it gets resent to the browser via regenerateId() - * - * @param int $seconds - * @return void - */ - public static function rememberUntil($seconds = 0) - { - if (self::$_unitTestEnabled) { - self::regenerateId(); - return; - } - - $cookieParams = session_get_cookie_params(); - - session_set_cookie_params( - $seconds, - $cookieParams['path'], - $cookieParams['domain'], - $cookieParams['secure'] - ); - - // normally "rememberMe()" represents a security context change, so should use new session id - self::regenerateId(); - } - - - /** - * sessionExists() - whether or not a session exists for the current request - * - * @return bool - */ - public static function sessionExists() - { - if ((bool)ini_get('session.use_cookies') == true && isset($_COOKIE[session_name()])) { - return true; - } elseif ((bool)ini_get('session.use_only_cookies') == false && isset($_REQUEST[session_name()])) { - return true; - } elseif (self::$_unitTestEnabled) { - return true; - } - - return false; - } - - - /** - * Whether or not session has been destroyed via session_destroy() - * - * @return bool - */ - public static function isDestroyed() - { - return self::$_destroyed; - } - - - /** - * start() - Start the session. - * - * @param bool|array $options OPTIONAL Either user supplied options, or flag indicating if start initiated automatically - * @throws Zend_Session_Exception - * @return void - */ - public static function start($options = false) - { - // Check to see if we've been passed an invalid session ID - if ( self::getId() && !self::_checkId(self::getId()) ) { - // Generate a valid, temporary replacement - self::setId(md5(self::getId())); - // Force a regenerate after session is started - self::$_regenerateIdState = -1; - } - - if (self::$_sessionStarted && self::$_destroyed) { - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.'); - } - - if (self::$_sessionStarted) { - return; // already started - } - - // make sure our default options (at the least) have been set - if (!self::$_defaultOptionsSet) { - self::setOptions(is_array($options) ? $options : array()); - } - - // In strict mode, do not allow auto-starting Zend_Session, such as via "new Zend_Session_Namespace()" - if (self::$_strict && $options === true) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('You must explicitly start the session with Zend_Session::start() when session options are set to strict.'); - } - - $filename = $linenum = null; - if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("Session must be started before any output has been sent to the browser;" - . " output started in {$filename}/{$linenum}"); - } - - // See http://www.php.net/manual/en/ref.session.php for explanation - if (!self::$_unitTestEnabled && defined('SID')) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('session has already been started by session.auto-start or session_start()'); - } - - /** - * Hack to throw exceptions on start instead of php errors - * @see http://framework.zend.com/issues/browse/ZF-1325 - */ - - $errorLevel = (is_int(self::$_throwStartupExceptions)) ? self::$_throwStartupExceptions : E_ALL; - - /** @see Zend_Session_Exception */ - if (!self::$_unitTestEnabled) { - - if (self::$_throwStartupExceptions) { - #require_once 'Zend/Session/Exception.php'; - set_error_handler(array('Zend_Session_Exception', 'handleSessionStartError'), $errorLevel); - } - - $startedCleanly = session_start(); - - if (self::$_throwStartupExceptions) { - restore_error_handler(); - } - - if (!$startedCleanly || Zend_Session_Exception::$sessionStartError != null) { - if (self::$_throwStartupExceptions) { - set_error_handler(array('Zend_Session_Exception', 'handleSilentWriteClose'), $errorLevel); - } - session_write_close(); - if (self::$_throwStartupExceptions) { - restore_error_handler(); - throw new Zend_Session_Exception(__CLASS__ . '::' . __FUNCTION__ . '() - ' . Zend_Session_Exception::$sessionStartError); - } - } - } - - parent::$_readable = true; - parent::$_writable = true; - self::$_sessionStarted = true; - if (self::$_regenerateIdState === -1) { - self::regenerateId(); - } - - // run validators if they exist - if (isset($_SESSION['__ZF']['VALID'])) { - self::_processValidators(); - } - - self::_processStartupMetadataGlobal(); - } - - /** - * Perform a hash-bits check on the session ID - * - * @param string $id Session ID - * @return bool - */ - protected static function _checkId($id) - { - $saveHandler = ini_get('session.save_handler'); - if ($saveHandler == 'cluster') { // Zend Server SC, validate only after last dash - $dashPos = strrpos($id, '-'); - if ($dashPos) { - $id = substr($id, $dashPos + 1); - } - } - - $hashBitsPerChar = ini_get('session.hash_bits_per_character'); - if (!$hashBitsPerChar) { - $hashBitsPerChar = 5; // the default value - } - switch($hashBitsPerChar) { - case 4: $pattern = '^[0-9a-f]*$'; break; - case 5: $pattern = '^[0-9a-v]*$'; break; - case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break; - } - return preg_match('#'.$pattern.'#', $id); - } - - - /** - * _processGlobalMetadata() - this method initizes the sessions GLOBAL - * metadata, mostly global data expiration calculations. - * - * @return void - */ - private static function _processStartupMetadataGlobal() - { - // process global metadata - if (isset($_SESSION['__ZF'])) { - - // expire globally expired values - foreach ($_SESSION['__ZF'] as $namespace => $namespace_metadata) { - - // Expire Namespace by Time (ENT) - if (isset($namespace_metadata['ENT']) && ($namespace_metadata['ENT'] > 0) && (time() > $namespace_metadata['ENT']) ) { - unset($_SESSION[$namespace]); - unset($_SESSION['__ZF'][$namespace]); - } - - // Expire Namespace by Global Hop (ENGH) if it wasnt expired above - if (isset($_SESSION['__ZF'][$namespace]) && isset($namespace_metadata['ENGH']) && $namespace_metadata['ENGH'] >= 1) { - - $_SESSION['__ZF'][$namespace]['ENGH']--; - - if ($_SESSION['__ZF'][$namespace]['ENGH'] === 0) { - if (isset($_SESSION[$namespace])) { - parent::$_expiringData[$namespace] = $_SESSION[$namespace]; - unset($_SESSION[$namespace]); - } - unset($_SESSION['__ZF'][$namespace]); - } - } - - // Expire Namespace Variables by Time (ENVT) - if (isset($namespace_metadata['ENVT'])) { - foreach ($namespace_metadata['ENVT'] as $variable => $time) { - if (time() > $time) { - unset($_SESSION[$namespace][$variable]); - unset($_SESSION['__ZF'][$namespace]['ENVT'][$variable]); - } - } - if (empty($_SESSION['__ZF'][$namespace]['ENVT'])) { - unset($_SESSION['__ZF'][$namespace]['ENVT']); - } - } - - // Expire Namespace Variables by Global Hop (ENVGH) - if (isset($namespace_metadata['ENVGH'])) { - foreach ($namespace_metadata['ENVGH'] as $variable => $hops) { - $_SESSION['__ZF'][$namespace]['ENVGH'][$variable]--; - - if ($_SESSION['__ZF'][$namespace]['ENVGH'][$variable] === 0) { - if (isset($_SESSION[$namespace][$variable])) { - parent::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable]; - unset($_SESSION[$namespace][$variable]); - } - unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]); - } - } - if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) { - unset($_SESSION['__ZF'][$namespace]['ENVGH']); - } - } - - if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) { - unset($_SESSION['__ZF'][$namespace]); - } - } - } - - if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) { - unset($_SESSION['__ZF']); - } - } - - - /** - * isStarted() - convenience method to determine if the session is already started. - * - * @return bool - */ - public static function isStarted() - { - return self::$_sessionStarted; - } - - - /** - * isRegenerated() - convenience method to determine if session_regenerate_id() - * has been called during this request by Zend_Session. - * - * @return bool - */ - public static function isRegenerated() - { - return ( (self::$_regenerateIdState > 0) ? true : false ); - } - - - /** - * getId() - get the current session id - * - * @return string - */ - public static function getId() - { - return session_id(); - } - - - /** - * setId() - set an id to a user specified id - * - * @throws Zend_Session_Exception - * @param string $id - * @return void - */ - public static function setId($id) - { - if (!self::$_unitTestEnabled && defined('SID')) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('The session has already been started. The session id must be set first.'); - } - - if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("You must call ".__CLASS__.'::'.__FUNCTION__. - "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); - } - - if (!is_string($id) || $id === '') { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('You must provide a non-empty string as a session identifier.'); - } - - session_id($id); - } - - - /** - * registerValidator() - register a validator that will attempt to validate this session for - * every future request - * - * @param Zend_Session_Validator_Interface $validator - * @return void - */ - public static function registerValidator(Zend_Session_Validator_Interface $validator) - { - $validator->setup(); - } - - - /** - * stop() - Disable write access. Optionally disable read (not implemented). - * - * @return void - */ - public static function stop() - { - parent::$_writable = false; - } - - - /** - * writeClose() - Shutdown the sesssion, close writing and detach $_SESSION from the back-end storage mechanism. - * This will complete the internal data transformation on this request. - * - * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes) - * @return void - */ - public static function writeClose($readonly = true) - { - if (self::$_unitTestEnabled) { - return; - } - - if (self::$_writeClosed) { - return; - } - - if ($readonly) { - parent::$_writable = false; - } - - session_write_close(); - self::$_writeClosed = true; - } - - - /** - * destroy() - This is used to destroy session data, and optionally, the session cookie itself - * - * @param bool $remove_cookie - OPTIONAL remove session id cookie, defaults to true (remove cookie) - * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes) - * @return void - */ - public static function destroy($remove_cookie = true, $readonly = true) - { - if (self::$_unitTestEnabled) { - return; - } - - if (self::$_destroyed) { - return; - } - - if ($readonly) { - parent::$_writable = false; - } - - session_destroy(); - self::$_destroyed = true; - - if ($remove_cookie) { - self::expireSessionCookie(); - } - } - - - /** - * expireSessionCookie() - Sends an expired session id cookie, causing the client to delete the session cookie - * - * @return void - */ - public static function expireSessionCookie() - { - if (self::$_unitTestEnabled) { - return; - } - - if (self::$_sessionCookieDeleted) { - return; - } - - self::$_sessionCookieDeleted = true; - - if (isset($_COOKIE[session_name()])) { - $cookie_params = session_get_cookie_params(); - - setcookie( - session_name(), - false, - 315554400, // strtotime('1980-01-01'), - $cookie_params['path'], - $cookie_params['domain'], - $cookie_params['secure'] - ); - } - } - - - /** - * _processValidator() - internal function that is called in the existence of VALID metadata - * - * @throws Zend_Session_Exception - * @return void - */ - private static function _processValidators() - { - foreach ($_SESSION['__ZF']['VALID'] as $validator_name => $valid_data) { - if (!class_exists($validator_name)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($validator_name); - } - $validator = new $validator_name; - if ($validator->validate() === false) { - /** @see Zend_Session_Validator_Exception */ - #require_once 'Zend/Session/Validator/Exception.php'; - throw new Zend_Session_Validator_Exception("This session is not valid according to {$validator_name}."); - } - } - } - - - /** - * namespaceIsset() - check to see if a namespace is set - * - * @param string $namespace - * @return bool - */ - public static function namespaceIsset($namespace) - { - return parent::_namespaceIsset($namespace); - } - - - /** - * namespaceUnset() - unset a namespace or a variable within a namespace - * - * @param string $namespace - * @throws Zend_Session_Exception - * @return void - */ - public static function namespaceUnset($namespace) - { - parent::_namespaceUnset($namespace); - Zend_Session_Namespace::resetSingleInstance($namespace); - } - - - /** - * namespaceGet() - get all variables in a namespace - * Deprecated: Use getIterator() in Zend_Session_Namespace. - * - * @deprecated - * @param string $namespace - * @return array - */ - public static function namespaceGet($namespace) - { - return parent::_namespaceGetAll($namespace); - } - - - /** - * getIterator() - return an iteratable object for use in foreach and the like, - * this completes the IteratorAggregate interface - * - * @throws Zend_Session_Exception - * @return ArrayObject - */ - public static function getIterator() - { - if (parent::$_readable === false) { - /** @see Zend_Session_Exception */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(parent::_THROW_NOT_READABLE_MSG); - } - - $spaces = array(); - if (isset($_SESSION)) { - $spaces = array_keys($_SESSION); - foreach($spaces as $key => $space) { - if (!strncmp($space, '__', 2) || !is_array($_SESSION[$space])) { - unset($spaces[$key]); - } - } - } - - return new ArrayObject(array_merge($spaces, array_keys(parent::$_expiringData))); - } - - - /** - * isWritable() - returns a boolean indicating if namespaces can write (use setters) - * - * @return bool - */ - public static function isWritable() - { - return parent::$_writable; - } - - - /** - * isReadable() - returns a boolean indicating if namespaces can write (use setters) - * - * @return bool - */ - public static function isReadable() - { - return parent::$_readable; - } - -} diff --git a/lib/Zend/Session/Abstract.php b/lib/Zend/Session/Abstract.php deleted file mode 100644 index bb4f216175b..00000000000 --- a/lib/Zend/Session/Abstract.php +++ /dev/null @@ -1,185 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - - -/** - * Zend_Session_Abstract - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Session_Abstract -{ - /** - * Whether or not session permits writing (modification of $_SESSION[]) - * - * @var bool - */ - protected static $_writable = false; - - /** - * Whether or not session permits reading (reading data in $_SESSION[]) - * - * @var bool - */ - protected static $_readable = false; - - /** - * Since expiring data is handled at startup to avoid __destruct difficulties, - * the data that will be expiring at end of this request is held here - * - * @var array - */ - protected static $_expiringData = array(); - - - /** - * Error message thrown when an action requires modification, - * but current Zend_Session has been marked as read-only. - */ - const _THROW_NOT_WRITABLE_MSG = 'Zend_Session is currently marked as read-only.'; - - - /** - * Error message thrown when an action requires reading session data, - * but current Zend_Session is not marked as readable. - */ - const _THROW_NOT_READABLE_MSG = 'Zend_Session is not marked as readable.'; - - - /** - * namespaceIsset() - check to see if a namespace or a variable within a namespace is set - * - * @param string $namespace - * @param string $name - * @return bool - */ - protected static function _namespaceIsset($namespace, $name = null) - { - if (self::$_readable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(self::_THROW_NOT_READABLE_MSG); - } - - if ($name === null) { - return ( isset($_SESSION[$namespace]) || isset(self::$_expiringData[$namespace]) ); - } else { - return ( isset($_SESSION[$namespace][$name]) || isset(self::$_expiringData[$namespace][$name]) ); - } - } - - - /** - * namespaceUnset() - unset a namespace or a variable within a namespace - * - * @param string $namespace - * @param string $name - * @throws Zend_Session_Exception - * @return void - */ - protected static function _namespaceUnset($namespace, $name = null) - { - if (self::$_writable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(self::_THROW_NOT_WRITABLE_MSG); - } - - $name = (string) $name; - - // check to see if the api wanted to remove a var from a namespace or a namespace - if ($name === '') { - unset($_SESSION[$namespace]); - unset(self::$_expiringData[$namespace]); - } else { - unset($_SESSION[$namespace][$name]); - unset(self::$_expiringData[$namespace][$name]); - } - - // if we remove the last value, remove namespace. - if (empty($_SESSION[$namespace])) { - unset($_SESSION[$namespace]); - } - } - - - /** - * namespaceGet() - Get $name variable from $namespace, returning by reference. - * - * @param string $namespace - * @param string $name - * @return mixed - */ - protected static function & _namespaceGet($namespace, $name = null) - { - if (self::$_readable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(self::_THROW_NOT_READABLE_MSG); - } - - if ($name === null) { - if (isset($_SESSION[$namespace])) { // check session first for data requested - return $_SESSION[$namespace]; - } elseif (isset(self::$_expiringData[$namespace])) { // check expiring data for data reqeusted - return self::$_expiringData[$namespace]; - } else { - return $_SESSION[$namespace]; // satisfy return by reference - } - } else { - if (isset($_SESSION[$namespace][$name])) { // check session first - return $_SESSION[$namespace][$name]; - } elseif (isset(self::$_expiringData[$namespace][$name])) { // check expiring data - return self::$_expiringData[$namespace][$name]; - } else { - return $_SESSION[$namespace][$name]; // satisfy return by reference - } - } - } - - - /** - * namespaceGetAll() - Get an array containing $namespace, including expiring data. - * - * @param string $namespace - * @param string $name - * @return mixed - */ - protected static function _namespaceGetAll($namespace) - { - $currentData = (isset($_SESSION[$namespace]) && is_array($_SESSION[$namespace])) ? - $_SESSION[$namespace] : array(); - $expiringData = (isset(self::$_expiringData[$namespace]) && is_array(self::$_expiringData[$namespace])) ? - self::$_expiringData[$namespace] : array(); - return array_merge($currentData, $expiringData); - } -} diff --git a/lib/Zend/Session/Exception.php b/lib/Zend/Session/Exception.php deleted file mode 100644 index 765e752c373..00000000000 --- a/lib/Zend/Session/Exception.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - - -/** - * @see Zend_Exception - */ -#require_once 'Zend/Exception.php'; - - -/** - * Zend_Session_Exception - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_Exception extends Zend_Exception -{ - /** - * sessionStartError - * - * @see http://framework.zend.com/issues/browse/ZF-1325 - * @var string PHP Error Message - */ - static public $sessionStartError = null; - - /** - * handleSessionStartError() - interface for set_error_handler() - * - * @see http://framework.zend.com/issues/browse/ZF-1325 - * @param int $errno - * @param string $errstr - * @return void - */ - static public function handleSessionStartError($errno, $errstr, $errfile, $errline, $errcontext) - { - self::$sessionStartError = $errfile . '(Line:' . $errline . '): Error #' . $errno . ' ' . $errstr; - } - - /** - * handleSilentWriteClose() - interface for set_error_handler() - * - * @see http://framework.zend.com/issues/browse/ZF-1325 - * @param int $errno - * @param string $errstr - * @return void - */ - static public function handleSilentWriteClose($errno, $errstr, $errfile, $errline, $errcontext) - { - self::$sessionStartError .= PHP_EOL . $errfile . '(Line:' . $errline . '): Error #' . $errno . ' ' . $errstr; - } -} - diff --git a/lib/Zend/Session/Namespace.php b/lib/Zend/Session/Namespace.php deleted file mode 100644 index 2b64ce4b305..00000000000 --- a/lib/Zend/Session/Namespace.php +++ /dev/null @@ -1,529 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - - -/** - * @see Zend_Session - */ -#require_once 'Zend/Session.php'; - - -/** - * @see Zend_Session_Abstract - */ -#require_once 'Zend/Session/Abstract.php'; - - -/** - * Zend_Session_Namespace - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_Namespace extends Zend_Session_Abstract implements IteratorAggregate -{ - - /** - * used as option to constructor to prevent additional instances to the same namespace - */ - const SINGLE_INSTANCE = true; - - /** - * Namespace - which namespace this instance of zend-session is saving-to/getting-from - * - * @var string - */ - protected $_namespace = "Default"; - - /** - * Namespace locking mechanism - * - * @var array - */ - protected static $_namespaceLocks = array(); - - /** - * Single instance namespace array to ensure data security. - * - * @var array - */ - protected static $_singleInstances = array(); - - /** - * resetSingleInstance() - * - * @param string $namespaceName - * @return null - */ - public static function resetSingleInstance($namespaceName = null) - { - if ($namespaceName != null) { - if (array_key_exists($namespaceName, self::$_singleInstances)) { - unset(self::$_singleInstances[$namespaceName]); - } - return; - } - - self::$_singleInstances = array(); - return; - } - - /** - * __construct() - Returns an instance object bound to a particular, isolated section - * of the session, identified by $namespace name (defaulting to 'Default'). - * The optional argument $singleInstance will prevent construction of additional - * instance objects acting as accessors to this $namespace. - * - * @param string $namespace - programmatic name of the requested namespace - * @param bool $singleInstance - prevent creation of additional accessor instance objects for this namespace - * @return void - */ - public function __construct($namespace = 'Default', $singleInstance = false) - { - if ($namespace === '') { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Session namespace must be a non-empty string.'); - } - - if ($namespace[0] == "_") { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Session namespace must not start with an underscore.'); - } - - if (preg_match('#(^[0-9])#i', $namespace[0])) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Session namespace must not start with a number.'); - } - - if (isset(self::$_singleInstances[$namespace])) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("A session namespace object already exists for this namespace ('$namespace'), and no additional accessors (session namespace objects) for this namespace are permitted."); - } - - if ($singleInstance === true) { - self::$_singleInstances[$namespace] = true; - } - - $this->_namespace = $namespace; - - // Process metadata specific only to this namespace. - Zend_Session::start(true); // attempt auto-start (throws exception if strict option set) - - if (self::$_readable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(self::_THROW_NOT_READABLE_MSG); - } - - if (!isset($_SESSION['__ZF'])) { - return; // no further processing needed - } - - // do not allow write access to namespaces, after stop() or writeClose() - if (parent::$_writable === true) { - if (isset($_SESSION['__ZF'][$namespace])) { - - // Expire Namespace by Namespace Hop (ENNH) - if (isset($_SESSION['__ZF'][$namespace]['ENNH'])) { - $_SESSION['__ZF'][$namespace]['ENNH']--; - - if ($_SESSION['__ZF'][$namespace]['ENNH'] === 0) { - if (isset($_SESSION[$namespace])) { - self::$_expiringData[$namespace] = $_SESSION[$namespace]; - unset($_SESSION[$namespace]); - } - unset($_SESSION['__ZF'][$namespace]); - } - } - - // Expire Namespace Variables by Namespace Hop (ENVNH) - if (isset($_SESSION['__ZF'][$namespace]['ENVNH'])) { - foreach ($_SESSION['__ZF'][$namespace]['ENVNH'] as $variable => $hops) { - $_SESSION['__ZF'][$namespace]['ENVNH'][$variable]--; - - if ($_SESSION['__ZF'][$namespace]['ENVNH'][$variable] === 0) { - if (isset($_SESSION[$namespace][$variable])) { - self::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable]; - unset($_SESSION[$namespace][$variable]); - } - unset($_SESSION['__ZF'][$namespace]['ENVNH'][$variable]); - } - } - if(empty($_SESSION['__ZF'][$namespace]['ENVNH'])) { - unset($_SESSION['__ZF'][$namespace]['ENVNH']); - } - } - } - - if (empty($_SESSION['__ZF'][$namespace])) { - unset($_SESSION['__ZF'][$namespace]); - } - - if (empty($_SESSION['__ZF'])) { - unset($_SESSION['__ZF']); - } - } - } - - - /** - * getIterator() - return an iteratable object for use in foreach and the like, - * this completes the IteratorAggregate interface - * - * @return ArrayObject - iteratable container of the namespace contents - */ - public function getIterator() - { - return new ArrayObject(parent::_namespaceGetAll($this->_namespace)); - } - - - /** - * lock() - mark a session/namespace as readonly - * - * @return void - */ - public function lock() - { - self::$_namespaceLocks[$this->_namespace] = true; - } - - - /** - * unlock() - unmark a session/namespace to enable read & write - * - * @return void - */ - public function unlock() - { - unset(self::$_namespaceLocks[$this->_namespace]); - } - - - /** - * unlockAll() - unmark all session/namespaces to enable read & write - * - * @return void - */ - public static function unlockAll() - { - self::$_namespaceLocks = array(); - } - - - /** - * isLocked() - return lock status, true if, and only if, read-only - * - * @return bool - */ - public function isLocked() - { - return isset(self::$_namespaceLocks[$this->_namespace]); - } - - - /** - * unsetAll() - unset all variables in this namespace - * - * @return true - */ - public function unsetAll() - { - return parent::_namespaceUnset($this->_namespace); - } - - - /** - * __get() - method to get a variable in this object's current namespace - * - * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace - * @return mixed - */ - public function & __get($name) - { - if ($name === '') { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("The '$name' key must be a non-empty string"); - } - - return parent::_namespaceGet($this->_namespace, $name); - } - - - /** - * __set() - method to set a variable/value in this object's namespace - * - * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace - * @param mixed $value - value in the <key,value> pair to assign to the $name key - * @throws Zend_Session_Exception - * @return true - */ - public function __set($name, $value) - { - if (isset(self::$_namespaceLocks[$this->_namespace])) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('This session/namespace has been marked as read-only.'); - } - - if ($name === '') { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("The '$name' key must be a non-empty string"); - } - - if (parent::$_writable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG); - } - - $name = (string) $name; - - $_SESSION[$this->_namespace][$name] = $value; - } - - - /** - * apply() - enables applying user-selected function, such as array_merge() to the namespace - * Parameters following the $callback argument are passed to the callback function. - * Caveat: ignores members expiring now. - * - * Example: - * $namespace->apply('array_merge', array('tree' => 'apple', 'fruit' => 'peach'), array('flower' => 'rose')); - * $namespace->apply('count'); - * - * @param string|array $callback - callback function - */ - public function apply($callback) - { - $arg_list = func_get_args(); - $arg_list[0] = $_SESSION[$this->_namespace]; - return call_user_func_array($callback, $arg_list); - } - - - /** - * applySet() - enables applying user-selected function, and sets entire namespace to the result - * Result of $callback must be an array. - * Parameters following the $callback argument are passed to the callback function. - * Caveat: ignores members expiring now. - * - * Example: - * $namespace->applySet('array_merge', array('tree' => 'apple', 'fruit' => 'peach'), array('flower' => 'rose')); - * - * @param string|array $callback - callback function - */ - public function applySet($callback) - { - $arg_list = func_get_args(); - $arg_list[0] = $_SESSION[$this->_namespace]; - $result = call_user_func_array($callback, $arg_list); - if (!is_array($result)) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Result must be an array. Got: ' . gettype($result)); - } - $_SESSION[$this->_namespace] = $result; - return $result; - } - - - /** - * __isset() - determine if a variable in this object's namespace is set - * - * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace - * @return bool - */ - public function __isset($name) - { - if ($name === '') { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("The '$name' key must be a non-empty string"); - } - - return parent::_namespaceIsset($this->_namespace, $name); - } - - - /** - * __unset() - unset a variable in this object's namespace. - * - * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace - * @return true - */ - public function __unset($name) - { - if ($name === '') { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception("The '$name' key must be a non-empty string"); - } - - return parent::_namespaceUnset($this->_namespace, $name); - } - - - /** - * setExpirationSeconds() - expire the namespace, or specific variables after a specified - * number of seconds - * - * @param int $seconds - expires in this many seconds - * @param mixed $variables - OPTIONAL list of variables to expire (defaults to all) - * @throws Zend_Session_Exception - * @return void - */ - public function setExpirationSeconds($seconds, $variables = null) - { - if (parent::$_writable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG); - } - - if ($seconds <= 0) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Seconds must be positive.'); - } - - if ($variables === null) { - - // apply expiration to entire namespace - $_SESSION['__ZF'][$this->_namespace]['ENT'] = time() + $seconds; - - } else { - - if (is_string($variables)) { - $variables = array($variables); - } - - foreach ($variables as $variable) { - if (!empty($variable)) { - $_SESSION['__ZF'][$this->_namespace]['ENVT'][$variable] = time() + $seconds; - } - } - } - } - - - /** - * setExpirationHops() - expire the namespace, or specific variables after a specified - * number of page hops - * - * @param int $hops - how many "hops" (number of subsequent requests) before expiring - * @param mixed $variables - OPTIONAL list of variables to expire (defaults to all) - * @param boolean $hopCountOnUsageOnly - OPTIONAL if set, only count a hop/request if this namespace is used - * @throws Zend_Session_Exception - * @return void - */ - public function setExpirationHops($hops, $variables = null, $hopCountOnUsageOnly = false) - { - if (parent::$_writable === false) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG); - } - - if ($hops <= 0) { - /** - * @see Zend_Session_Exception - */ - #require_once 'Zend/Session/Exception.php'; - throw new Zend_Session_Exception('Hops must be positive number.'); - } - - if ($variables === null) { - - // apply expiration to entire namespace - if ($hopCountOnUsageOnly === false) { - $_SESSION['__ZF'][$this->_namespace]['ENGH'] = $hops; - } else { - $_SESSION['__ZF'][$this->_namespace]['ENNH'] = $hops; - } - - } else { - - if (is_string($variables)) { - $variables = array($variables); - } - - foreach ($variables as $variable) { - if (!empty($variable)) { - if ($hopCountOnUsageOnly === false) { - $_SESSION['__ZF'][$this->_namespace]['ENVGH'][$variable] = $hops; - } else { - $_SESSION['__ZF'][$this->_namespace]['ENVNH'][$variable] = $hops; - } - } - } - } - } - - /** - * Returns the namespace name - * - * @return string - */ - public function getNamespace() - { - return $this->_namespace; - } -} diff --git a/lib/Zend/Session/SaveHandler/DbTable.php b/lib/Zend/Session/SaveHandler/DbTable.php deleted file mode 100644 index 17cc99c2d1b..00000000000 --- a/lib/Zend/Session/SaveHandler/DbTable.php +++ /dev/null @@ -1,591 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-webat this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Session - */ -#require_once 'Zend/Session.php'; - -/** - * @see Zend_Db_Table_Abstract - */ -#require_once 'Zend/Db/Table/Abstract.php'; - -/** - * @see Zend_Db_Table_Row_Abstract - */ -#require_once 'Zend/Db/Table/Row/Abstract.php'; - -/** - * @see Zend_Config - */ -#require_once 'Zend/Config.php'; - -/** - * Zend_Session_SaveHandler_DbTable - * - * @category Zend - * @package Zend_Session - * @subpackage SaveHandler - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_SaveHandler_DbTable - extends Zend_Db_Table_Abstract - implements Zend_Session_SaveHandler_Interface -{ - const PRIMARY_ASSIGNMENT = 'primaryAssignment'; - const PRIMARY_ASSIGNMENT_SESSION_SAVE_PATH = 'sessionSavePath'; - const PRIMARY_ASSIGNMENT_SESSION_NAME = 'sessionName'; - const PRIMARY_ASSIGNMENT_SESSION_ID = 'sessionId'; - - const MODIFIED_COLUMN = 'modifiedColumn'; - const LIFETIME_COLUMN = 'lifetimeColumn'; - const DATA_COLUMN = 'dataColumn'; - - const LIFETIME = 'lifetime'; - const OVERRIDE_LIFETIME = 'overrideLifetime'; - - const PRIMARY_TYPE_NUM = 'PRIMARY_TYPE_NUM'; - const PRIMARY_TYPE_PRIMARYNUM = 'PRIMARY_TYPE_PRIMARYNUM'; - const PRIMARY_TYPE_ASSOC = 'PRIMARY_TYPE_ASSOC'; - const PRIMARY_TYPE_WHERECLAUSE = 'PRIMARY_TYPE_WHERECLAUSE'; - - /** - * Session table primary key value assignment - * - * @var array - */ - protected $_primaryAssignment = null; - - /** - * Session table last modification time column - * - * @var string - */ - protected $_modifiedColumn = null; - - /** - * Session table lifetime column - * - * @var string - */ - protected $_lifetimeColumn = null; - - /** - * Session table data column - * - * @var string - */ - protected $_dataColumn = null; - - /** - * Session lifetime - * - * @var int - */ - protected $_lifetime = false; - - /** - * Whether or not the lifetime of an existing session should be overridden - * - * @var boolean - */ - protected $_overrideLifetime = false; - - /** - * Session save path - * - * @var string - */ - protected $_sessionSavePath; - - /** - * Session name - * - * @var string - */ - protected $_sessionName; - - /** - * Constructor - * - * $config is an instance of Zend_Config or an array of key/value pairs containing configuration options for - * Zend_Session_SaveHandler_DbTable and Zend_Db_Table_Abstract. These are the configuration options for - * Zend_Session_SaveHandler_DbTable: - * - * primaryAssignment => (string|array) Session table primary key value assignment - * (optional; default: 1 => sessionId) You have to assign a value to each primary key of your session table. - * The value of this configuration option is either a string if you have only one primary key or an array if - * you have multiple primary keys. The array consists of numeric keys starting at 1 and string values. There - * are some values which will be replaced by session information: - * - * sessionId => The id of the current session - * sessionName => The name of the current session - * sessionSavePath => The save path of the current session - * - * NOTE: One of your assignments MUST contain 'sessionId' as value! - * - * modifiedColumn => (string) Session table last modification time column - * - * lifetimeColumn => (string) Session table lifetime column - * - * dataColumn => (string) Session table data column - * - * lifetime => (integer) Session lifetime (optional; default: ini_get('session.gc_maxlifetime')) - * - * overrideLifetime => (boolean) Whether or not the lifetime of an existing session should be overridden - * (optional; default: false) - * - * @param Zend_Config|array $config User-provided configuration - * @return void - * @throws Zend_Session_SaveHandler_Exception - */ - public function __construct($config) - { - if ($config instanceof Zend_Config) { - $config = $config->toArray(); - } else if (!is_array($config)) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - '$config must be an instance of Zend_Config or array of key/value pairs containing ' - . 'configuration options for Zend_Session_SaveHandler_DbTable and Zend_Db_Table_Abstract.'); - } - - foreach ($config as $key => $value) { - do { - switch ($key) { - case self::PRIMARY_ASSIGNMENT: - $this->_primaryAssignment = $value; - break; - case self::MODIFIED_COLUMN: - $this->_modifiedColumn = (string) $value; - break; - case self::LIFETIME_COLUMN: - $this->_lifetimeColumn = (string) $value; - break; - case self::DATA_COLUMN: - $this->_dataColumn = (string) $value; - break; - case self::LIFETIME: - $this->setLifetime($value); - break; - case self::OVERRIDE_LIFETIME: - $this->setOverrideLifetime($value); - break; - default: - // unrecognized options passed to parent::__construct() - break 2; - } - unset($config[$key]); - } while (false); - } - - parent::__construct($config); - } - - /** - * Destructor - * - * @return void - */ - public function __destruct() - { - Zend_Session::writeClose(); - } - - /** - * Set session lifetime and optional whether or not the lifetime of an existing session should be overridden - * - * $lifetime === false resets lifetime to session.gc_maxlifetime - * - * @param int $lifetime - * @param boolean $overrideLifetime (optional) - * @return Zend_Session_SaveHandler_DbTable - */ - public function setLifetime($lifetime, $overrideLifetime = null) - { - if ($lifetime < 0) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - throw new Zend_Session_SaveHandler_Exception(); - } else if (empty($lifetime)) { - $this->_lifetime = (int) ini_get('session.gc_maxlifetime'); - } else { - $this->_lifetime = (int) $lifetime; - } - - if ($overrideLifetime != null) { - $this->setOverrideLifetime($overrideLifetime); - } - - return $this; - } - - /** - * Retrieve session lifetime - * - * @return int - */ - public function getLifetime() - { - return $this->_lifetime; - } - - /** - * Set whether or not the lifetime of an existing session should be overridden - * - * @param boolean $overrideLifetime - * @return Zend_Session_SaveHandler_DbTable - */ - public function setOverrideLifetime($overrideLifetime) - { - $this->_overrideLifetime = (boolean) $overrideLifetime; - - return $this; - } - - /** - * Retrieve whether or not the lifetime of an existing session should be overridden - * - * @return boolean - */ - public function getOverrideLifetime() - { - return $this->_overrideLifetime; - } - - /** - * Open Session - * - * @param string $save_path - * @param string $name - * @return boolean - */ - public function open($save_path, $name) - { - $this->_sessionSavePath = $save_path; - $this->_sessionName = $name; - - return true; - } - - /** - * Close session - * - * @return boolean - */ - public function close() - { - return true; - } - - /** - * Read session data - * - * @param string $id - * @return string - */ - public function read($id) - { - $return = ''; - - $rows = call_user_func_array(array(&$this, 'find'), $this->_getPrimary($id)); - - if (count($rows)) { - if ($this->_getExpirationTime($row = $rows->current()) > time()) { - $return = $row->{$this->_dataColumn}; - } else { - $this->destroy($id); - } - } - - return $return; - } - - /** - * Write session data - * - * @param string $id - * @param string $data - * @return boolean - */ - public function write($id, $data) - { - $return = false; - - $data = array($this->_modifiedColumn => time(), - $this->_dataColumn => (string) $data); - - $rows = call_user_func_array(array(&$this, 'find'), $this->_getPrimary($id)); - - if (count($rows)) { - $data[$this->_lifetimeColumn] = $this->_getLifetime($rows->current()); - - if ($this->update($data, $this->_getPrimary($id, self::PRIMARY_TYPE_WHERECLAUSE))) { - $return = true; - } - } else { - $data[$this->_lifetimeColumn] = $this->_lifetime; - - if ($this->insert(array_merge($this->_getPrimary($id, self::PRIMARY_TYPE_ASSOC), $data))) { - $return = true; - } - } - - return $return; - } - - /** - * Destroy session - * - * @param string $id - * @return boolean - */ - public function destroy($id) - { - $return = false; - - if ($this->delete($this->_getPrimary($id, self::PRIMARY_TYPE_WHERECLAUSE))) { - $return = true; - } - - return $return; - } - - /** - * Garbage Collection - * - * @param int $maxlifetime - * @return true - */ - public function gc($maxlifetime) - { - $this->delete($this->getAdapter()->quoteIdentifier($this->_modifiedColumn, true) . ' + ' - . $this->getAdapter()->quoteIdentifier($this->_lifetimeColumn, true) . ' < ' - . $this->getAdapter()->quote(time())); - - return true; - } - - /** - * Calls other protected methods for individual setup tasks and requirement checks - * - * @return void - */ - protected function _setup() - { - parent::_setup(); - - $this->_setupPrimaryAssignment(); - $this->setLifetime($this->_lifetime); - - $this->_checkRequiredColumns(); - } - - /** - * Initialize table and schema names - * - * @return void - * @throws Zend_Session_SaveHandler_Exception - */ - protected function _setupTableName() - { - if (empty($this->_name) && basename(($this->_name = session_save_path())) != $this->_name) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception('session.save_path is a path and not a table name.'); - } - - if (strpos($this->_name, '.')) { - list($this->_schema, $this->_name) = explode('.', $this->_name); - } - } - - /** - * Initialize session table primary key value assignment - * - * @return void - * @throws Zend_Session_SaveHandler_Exception - */ - protected function _setupPrimaryAssignment() - { - if ($this->_primaryAssignment === null) { - $this->_primaryAssignment = array(1 => self::PRIMARY_ASSIGNMENT_SESSION_ID); - } else if (!is_array($this->_primaryAssignment)) { - $this->_primaryAssignment = array(1 => (string) $this->_primaryAssignment); - } else if (isset($this->_primaryAssignment[0])) { - array_unshift($this->_primaryAssignment, null); - - unset($this->_primaryAssignment[0]); - } - - if (count($this->_primaryAssignment) !== count($this->_primary)) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - "Value for configuration option '" . self::PRIMARY_ASSIGNMENT . "' must have an assignment " - . "for each session table primary key."); - } else if (!in_array(self::PRIMARY_ASSIGNMENT_SESSION_ID, $this->_primaryAssignment)) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - "Value for configuration option '" . self::PRIMARY_ASSIGNMENT . "' must have an assignment " - . "for the session id ('" . self::PRIMARY_ASSIGNMENT_SESSION_ID . "')."); - } - } - - /** - * Check for required session table columns - * - * @return void - * @throws Zend_Session_SaveHandler_Exception - */ - protected function _checkRequiredColumns() - { - if ($this->_modifiedColumn === null) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - "Configuration must define '" . self::MODIFIED_COLUMN . "' which names the " - . "session table last modification time column."); - } else if ($this->_lifetimeColumn === null) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - "Configuration must define '" . self::LIFETIME_COLUMN . "' which names the " - . "session table lifetime column."); - } else if ($this->_dataColumn === null) { - /** - * @see Zend_Session_SaveHandler_Exception - */ - #require_once 'Zend/Session/SaveHandler/Exception.php'; - - throw new Zend_Session_SaveHandler_Exception( - "Configuration must define '" . self::DATA_COLUMN . "' which names the " - . "session table data column."); - } - } - - /** - * Retrieve session table primary key values - * - * @param string $id - * @param string $type (optional; default: self::PRIMARY_TYPE_NUM) - * @return array - */ - protected function _getPrimary($id, $type = null) - { - $this->_setupPrimaryKey(); - - if ($type === null) { - $type = self::PRIMARY_TYPE_NUM; - } - - $primaryArray = array(); - - foreach ($this->_primary as $index => $primary) { - switch ($this->_primaryAssignment[$index]) { - case self::PRIMARY_ASSIGNMENT_SESSION_SAVE_PATH: - $value = $this->_sessionSavePath; - break; - case self::PRIMARY_ASSIGNMENT_SESSION_NAME: - $value = $this->_sessionName; - break; - case self::PRIMARY_ASSIGNMENT_SESSION_ID: - $value = (string) $id; - break; - default: - $value = (string) $this->_primaryAssignment[$index]; - break; - } - - switch ((string) $type) { - case self::PRIMARY_TYPE_PRIMARYNUM: - $primaryArray[$index] = $value; - break; - case self::PRIMARY_TYPE_ASSOC: - $primaryArray[$primary] = $value; - break; - case self::PRIMARY_TYPE_WHERECLAUSE: - $primaryArray[] = $this->getAdapter()->quoteIdentifier($primary, true) . ' = ' - . $this->getAdapter()->quote($value); - break; - case self::PRIMARY_TYPE_NUM: - default: - $primaryArray[] = $value; - break; - } - } - - return $primaryArray; - } - - /** - * Retrieve session lifetime considering Zend_Session_SaveHandler_DbTable::OVERRIDE_LIFETIME - * - * @param Zend_Db_Table_Row_Abstract $row - * @return int - */ - protected function _getLifetime(Zend_Db_Table_Row_Abstract $row) - { - $return = $this->_lifetime; - - if (!$this->_overrideLifetime) { - $return = (int) $row->{$this->_lifetimeColumn}; - } - - return $return; - } - - /** - * Retrieve session expiration time - * - * @param Zend_Db_Table_Row_Abstract $row - * @return int - */ - protected function _getExpirationTime(Zend_Db_Table_Row_Abstract $row) - { - return (int) $row->{$this->_modifiedColumn} + $this->_getLifetime($row); - } -} diff --git a/lib/Zend/Session/SaveHandler/Exception.php b/lib/Zend/Session/SaveHandler/Exception.php deleted file mode 100644 index e66c2a57e2d..00000000000 --- a/lib/Zend/Session/SaveHandler/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Session_Exception - */ -#require_once 'Zend/Session/Exception.php'; - -/** - * Zend_Session_SaveHandler_Exception - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_SaveHandler_Exception extends Zend_Session_Exception -{} diff --git a/lib/Zend/Session/SaveHandler/Interface.php b/lib/Zend/Session/SaveHandler/Interface.php deleted file mode 100644 index 18ed5fe5244..00000000000 --- a/lib/Zend/Session/SaveHandler/Interface.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - -/** - * Zend_Session_SaveHandler_Interface - * - * @category Zend - * @package Zend_Session - * @subpackage SaveHandler - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @see http://php.net/session_set_save_handler - */ -interface Zend_Session_SaveHandler_Interface -{ - - /** - * Open Session - retrieve resources - * - * @param string $save_path - * @param string $name - */ - public function open($save_path, $name); - - /** - * Close Session - free resources - * - */ - public function close(); - - /** - * Read session data - * - * @param string $id - */ - public function read($id); - - /** - * Write Session - commit data to resource - * - * @param string $id - * @param mixed $data - */ - public function write($id, $data); - - /** - * Destroy Session - remove data from resource for - * given session id - * - * @param string $id - */ - public function destroy($id); - - /** - * Garbage Collection - remove old session data older - * than $maxlifetime (in seconds) - * - * @param int $maxlifetime - */ - public function gc($maxlifetime); - -} diff --git a/lib/Zend/Session/Validator/Abstract.php b/lib/Zend/Session/Validator/Abstract.php deleted file mode 100644 index 7606aa8e734..00000000000 --- a/lib/Zend/Session/Validator/Abstract.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - -/** - * @see Zend_Session_Validator_Interface - */ -#require_once 'Zend/Session/Validator/Interface.php'; - -/** - * Zend_Session_Validator_Abstract - * - * @category Zend - * @package Zend_Session - * @subpackage Validator - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Session_Validator_Abstract implements Zend_Session_Validator_Interface -{ - - /** - * SetValidData() - This method should be used to store the environment variables that - * will be needed in order to validate the session later in the validate() method. - * These values are stored in the session in the __ZF namespace, in an array named VALID - * - * @param mixed $data - * @return void - */ - protected function setValidData($data) - { - $validatorName = get_class($this); - - $_SESSION['__ZF']['VALID'][$validatorName] = $data; - } - - - /** - * GetValidData() - This method should be used to retrieve the environment variables that - * will be needed to 'validate' a session. - * - * @return mixed - */ - protected function getValidData() - { - $validatorName = get_class($this); - if (isset($_SESSION['__ZF']['VALID'][$validatorName])) { - return $_SESSION['__ZF']['VALID'][$validatorName]; - } - return null; - } - -} diff --git a/lib/Zend/Session/Validator/Exception.php b/lib/Zend/Session/Validator/Exception.php deleted file mode 100644 index 49c8e3dd25c..00000000000 --- a/lib/Zend/Session/Validator/Exception.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - - -/** - * @see Zend_Session_Exception - */ -#require_once 'Zend/Session/Exception.php'; - - -/** - * Zend_Session_Validator_Exception - * - * @category Zend - * @package Zend_Session - * @subpackage Validator - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_Validator_Exception extends Zend_Session_Exception -{ - -} - diff --git a/lib/Zend/Session/Validator/HttpUserAgent.php b/lib/Zend/Session/Validator/HttpUserAgent.php deleted file mode 100644 index c458abbfac1..00000000000 --- a/lib/Zend/Session/Validator/HttpUserAgent.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - -/** - * @see Zend_Session_Validator_Abstract - */ -#require_once 'Zend/Session/Validator/Abstract.php'; - -/** - * Zend_Session_Validator_HttpUserAgent - * - * @category Zend - * @package Zend_Session - * @subpackage Validator - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Session_Validator_HttpUserAgent extends Zend_Session_Validator_Abstract -{ - - /** - * Setup() - this method will get the current user agent and store it in the session - * as 'valid data' - * - * @return void - */ - public function setup() - { - $this->setValidData( (isset($_SERVER['HTTP_USER_AGENT']) - ? $_SERVER['HTTP_USER_AGENT'] : null) ); - } - - /** - * Validate() - this method will determine if the current user agent matches the - * user agent we stored when we initialized this variable. - * - * @return bool - */ - public function validate() - { - $currentBrowser = (isset($_SERVER['HTTP_USER_AGENT']) - ? $_SERVER['HTTP_USER_AGENT'] : null); - - return $currentBrowser === $this->getValidData(); - } - -} diff --git a/lib/Zend/Session/Validator/Interface.php b/lib/Zend/Session/Validator/Interface.php deleted file mode 100644 index ab4eb3ec9d1..00000000000 --- a/lib/Zend/Session/Validator/Interface.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Session - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - * @since Preview Release 0.2 - */ - -/** - * Zend_Session_Validator_Interface - * - * @category Zend - * @package Zend_Session - * @subpackage Validator - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Session_Validator_Interface -{ - - /** - * Setup() - this method will store the environment variables - * necessary to be able to validate against in future requests. - * - * @return void - */ - public function setup(); - - /** - * Validate() - this method will be called at the beginning of - * every session to determine if the current environment matches - * that which was store in the setup() procedure. - * - * @return boolean - */ - public function validate(); - -} diff --git a/lib/Zend/Soap/AutoDiscover.php b/lib/Zend/Soap/AutoDiscover.php deleted file mode 100644 index 1b423bf54b1..00000000000 --- a/lib/Zend/Soap/AutoDiscover.php +++ /dev/null @@ -1,611 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage AutoDiscover - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Server_Interface - */ -#require_once 'Zend/Server/Interface.php'; -/** - * @see Zend_Soap_Wsdl - */ -#require_once 'Zend/Soap/Wsdl.php'; -/** - * @see Zend_Server_Reflection - */ -#require_once 'Zend/Server/Reflection.php'; -/** - * @see Zend_Server_Abstract - */ -#require_once 'Zend/Server/Abstract.php'; -/** - * @see Zend_Uri - */ -#require_once 'Zend/Uri.php'; - -/** - * Zend_Soap_AutoDiscover - * - * @category Zend - * @package Zend_Soap - * @subpackage AutoDiscover - */ -class Zend_Soap_AutoDiscover implements Zend_Server_Interface -{ - /** - * @var Zend_Soap_Wsdl - */ - protected $_wsdl = null; - - /** - * @var Zend_Server_Reflection - */ - protected $_reflection = null; - - /** - * @var array - */ - protected $_functions = array(); - - /** - * @var boolean - */ - protected $_strategy; - - /** - * Url where the WSDL file will be available at. - * - * @var WSDL Uri - */ - protected $_uri; - - /** - * soap:body operation style options - * - * @var array - */ - protected $_operationBodyStyle = array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"); - - /** - * soap:operation style - * - * @var array - */ - protected $_bindingStyle = array('style' => 'rpc', 'transport' => 'http://schemas.xmlsoap.org/soap/http'); - - /** - * Name of the class to handle the WSDL creation. - * - * @var string - */ - protected $_wsdlClass = 'Zend_Soap_Wsdl'; - - /** - * Constructor - * - * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy - * @param string|Zend_Uri $uri - * @param string $wsdlClass - */ - public function __construct($strategy = true, $uri=null, $wsdlClass=null) - { - $this->_reflection = new Zend_Server_Reflection(); - $this->setComplexTypeStrategy($strategy); - - if($uri !== null) { - $this->setUri($uri); - } - - if($wsdlClass !== null) { - $this->setWsdlClass($wsdlClass); - } - } - - /** - * Set the location at which the WSDL file will be availabe. - * - * @see Zend_Soap_Exception - * @param Zend_Uri|string $uri - * @return Zend_Soap_AutoDiscover - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function setUri($uri) - { - if (!is_string($uri) && !($uri instanceof Zend_Uri)) { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("No uri given to Zend_Soap_AutoDiscover::setUri as string or Zend_Uri instance."); - } - $this->_uri = $uri; - - // change uri in WSDL file also if existant - if ($this->_wsdl instanceof Zend_Soap_Wsdl) { - $this->_wsdl->setUri($uri); - } - - return $this; - } - - /** - * Return the current Uri that the SOAP WSDL Service will be located at. - * - * @return Zend_Uri - */ - public function getUri() - { - if($this->_uri !== null) { - $uri = $this->_uri; - } else { - $schema = $this->getSchema(); - $host = $this->getHostName(); - $scriptName = $this->getRequestUriWithoutParameters(); - $uri = Zend_Uri::factory($schema . '://' . $host . $scriptName); - $this->setUri($uri); - } - return $uri; - } - - /** - * Set the name of the WSDL handling class. - * - * @see Zend_Soap_Exception - * @see Zend_Soap_Exception - * @param string $wsdlClass - * @return Zend_Soap_AutoDiscover - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function setWsdlClass($wsdlClass) - { - if (!is_string($wsdlClass) && !is_subclass_of($wsdlClass, 'Zend_Soap_Wsdl')) { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("No Zend_Soap_Wsdl subclass given to Zend_Soap_AutoDiscover::setWsdlClass as string."); - } - $this->_wsdlClass = $wsdlClass; - - return $this; - } - - /** - * Return the name of the WSDL handling class. - * - * @return string - */ - public function getWsdlClass() - { - return $this->_wsdlClass; - } - - /** - * Set options for all the binding operations soap:body elements. - * - * By default the options are set to 'use' => 'encoded' and - * 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/". - * - * @see Zend_Soap_AutoDiscover_Exception - * @param array $operationStyle - * @return Zend_Soap_AutoDiscover - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function setOperationBodyStyle(array $operationStyle=array()) - { - if(!isset($operationStyle['use'])) { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Key 'use' is required in Operation soap:body style."); - } - $this->_operationBodyStyle = $operationStyle; - return $this; - } - - /** - * Set Binding soap:binding style. - * - * By default 'style' is 'rpc' and 'transport' is 'http://schemas.xmlsoap.org/soap/http'. - * - * @param array $bindingStyle - * @return Zend_Soap_AutoDiscover - */ - public function setBindingStyle(array $bindingStyle=array()) - { - if(isset($bindingStyle['style'])) { - $this->_bindingStyle['style'] = $bindingStyle['style']; - } - if(isset($bindingStyle['transport'])) { - $this->_bindingStyle['transport'] = $bindingStyle['transport']; - } - return $this; - } - - /** - * Detect and returns the current HTTP/HTTPS Schema - * - * @return string - */ - protected function getSchema() - { - $schema = "http"; - if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { - $schema = 'https'; - } - return $schema; - } - - /** - * Detect and return the current hostname - * - * @return string - */ - protected function getHostName() - { - if(isset($_SERVER['HTTP_HOST'])) { - $host = $_SERVER['HTTP_HOST']; - } else { - $host = $_SERVER['SERVER_NAME']; - } - return $host; - } - - /** - * Detect and return the current script name without parameters - * - * @return string - */ - protected function getRequestUriWithoutParameters() - { - if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { // IIS with Microsoft Rewrite Module - $requestUri = $_SERVER['HTTP_X_ORIGINAL_URL']; - } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch - $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; - } elseif (isset($_SERVER['REQUEST_URI'])) { - $requestUri = $_SERVER['REQUEST_URI']; - } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI - $requestUri = $_SERVER['ORIG_PATH_INFO']; - } else { - $requestUri = $_SERVER['SCRIPT_NAME']; - } - if( ($pos = strpos($requestUri, "?")) !== false) { - $requestUri = substr($requestUri, 0, $pos); - } - - return $requestUri; - } - - /** - * Set the strategy that handles functions and classes that are added AFTER this call. - * - * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy - * @return Zend_Soap_AutoDiscover - */ - public function setComplexTypeStrategy($strategy) - { - $this->_strategy = $strategy; - if($this->_wsdl instanceof Zend_Soap_Wsdl) { - $this->_wsdl->setComplexTypeStrategy($strategy); - } - - return $this; - } - - /** - * Set the Class the SOAP server will use - * - * @param string $class Class Name - * @param string $namespace Class Namspace - Not Used - * @param array $argv Arguments to instantiate the class - Not Used - * @return Zend_Soap_AutoDiscover - */ - public function setClass($class, $namespace = '', $argv = null) - { - $uri = $this->getUri(); - - $wsdl = new $this->_wsdlClass($class, $uri, $this->_strategy); - - // The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023) - $wsdl->addSchemaTypeSection(); - - $port = $wsdl->addPortType($class . 'Port'); - $binding = $wsdl->addBinding($class . 'Binding', 'tns:' .$class. 'Port'); - - $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); - $wsdl->addService($class . 'Service', $class . 'Port', 'tns:' . $class . 'Binding', $uri); - foreach ($this->_reflection->reflectClass($class)->getMethods() as $method) { - $this->_addFunctionToWsdl($method, $wsdl, $port, $binding); - } - $this->_wsdl = $wsdl; - - return $this; - } - - /** - * Add a Single or Multiple Functions to the WSDL - * - * @param string $function Function Name - * @param string $namespace Function namespace - Not Used - * @return Zend_Soap_AutoDiscover - */ - public function addFunction($function, $namespace = '') - { - static $port; - static $operation; - static $binding; - - if (!is_array($function)) { - $function = (array) $function; - } - - $uri = $this->getUri(); - - if (!($this->_wsdl instanceof Zend_Soap_Wsdl)) { - $parts = explode('.', basename($_SERVER['SCRIPT_NAME'])); - $name = $parts[0]; - $wsdl = new Zend_Soap_Wsdl($name, $uri, $this->_strategy); - - // The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023) - $wsdl->addSchemaTypeSection(); - - $port = $wsdl->addPortType($name . 'Port'); - $binding = $wsdl->addBinding($name . 'Binding', 'tns:' .$name. 'Port'); - - $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); - $wsdl->addService($name . 'Service', $name . 'Port', 'tns:' . $name . 'Binding', $uri); - } else { - $wsdl = $this->_wsdl; - } - - foreach ($function as $func) { - $method = $this->_reflection->reflectFunction($func); - $this->_addFunctionToWsdl($method, $wsdl, $port, $binding); - } - $this->_wsdl = $wsdl; - - return $this; - } - - /** - * Add a function to the WSDL document. - * - * @param Zend_Server_Reflection_Function_Abstract $function function to add - * @param Zend_Soap_Wsdl $wsdl WSDL document - * @param object $port wsdl:portType - * @param object $binding wsdl:binding - * @return void - */ - protected function _addFunctionToWsdl($function, $wsdl, $port, $binding) - { - $uri = $this->getUri(); - - // We only support one prototype: the one with the maximum number of arguments - $prototype = null; - $maxNumArgumentsOfPrototype = -1; - foreach ($function->getPrototypes() as $tmpPrototype) { - $numParams = count($tmpPrototype->getParameters()); - if ($numParams > $maxNumArgumentsOfPrototype) { - $maxNumArgumentsOfPrototype = $numParams; - $prototype = $tmpPrototype; - } - } - if ($prototype === null) { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("No prototypes could be found for the '" . $function->getName() . "' function"); - } - - // Add the input message (parameters) - $args = array(); - if ($this->_bindingStyle['style'] == 'document') { - // Document style: wrap all parameters in a sequence element - $sequence = array(); - foreach ($prototype->getParameters() as $param) { - $sequenceElement = array( - 'name' => $param->getName(), - 'type' => $wsdl->getType($param->getType()) - ); - if ($param->isOptional()) { - $sequenceElement['nillable'] = 'true'; - } - $sequence[] = $sequenceElement; - } - $element = array( - 'name' => $function->getName(), - 'sequence' => $sequence - ); - // Add the wrapper element part, which must be named 'parameters' - $args['parameters'] = array('element' => $wsdl->addElement($element)); - } else { - // RPC style: add each parameter as a typed part - foreach ($prototype->getParameters() as $param) { - $args[$param->getName()] = array('type' => $wsdl->getType($param->getType())); - } - } - $wsdl->addMessage($function->getName() . 'In', $args); - - $isOneWayMessage = false; - if($prototype->getReturnType() == "void") { - $isOneWayMessage = true; - } - - if($isOneWayMessage == false) { - // Add the output message (return value) - $args = array(); - if ($this->_bindingStyle['style'] == 'document') { - // Document style: wrap the return value in a sequence element - $sequence = array(); - if ($prototype->getReturnType() != "void") { - $sequence[] = array( - 'name' => $function->getName() . 'Result', - 'type' => $wsdl->getType($prototype->getReturnType()) - ); - } - $element = array( - 'name' => $function->getName() . 'Response', - 'sequence' => $sequence - ); - // Add the wrapper element part, which must be named 'parameters' - $args['parameters'] = array('element' => $wsdl->addElement($element)); - } else if ($prototype->getReturnType() != "void") { - // RPC style: add the return value as a typed part - $args['return'] = array('type' => $wsdl->getType($prototype->getReturnType())); - } - $wsdl->addMessage($function->getName() . 'Out', $args); - } - - // Add the portType operation - if($isOneWayMessage == false) { - $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', 'tns:' . $function->getName() . 'Out'); - } else { - $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', false); - } - $desc = $function->getDescription(); - if (strlen($desc) > 0) { - $wsdl->addDocumentation($portOperation, $desc); - } - - // When using the RPC style, make sure the operation style includes a 'namespace' attribute (WS-I Basic Profile 1.1 R2717) - if ($this->_bindingStyle['style'] == 'rpc' && !isset($this->_operationBodyStyle['namespace'])) { - $this->_operationBodyStyle['namespace'] = ''.$uri; - } - - // Add the binding operation - if($isOneWayMessage == false) { - $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); - } else { - $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle); - } - $wsdl->addSoapOperation($operation, $uri . '#' .$function->getName()); - - // Add the function name to the list - $this->_functions[] = $function->getName(); - } - - /** - * Action to take when an error occurs - * - * @param string $fault - * @param string|int $code - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function fault($fault = null, $code = null) - { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); - } - - /** - * Handle the Request - * - * @param string $request A non-standard request - Not Used - */ - public function handle($request = false) - { - if (!headers_sent()) { - header('Content-Type: text/xml'); - } - $this->_wsdl->dump(); - } - - /** - * Proxy to WSDL dump function - * - * @param string $filename - * @return boolean - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function dump($filename) - { - if($this->_wsdl !== null) { - return $this->_wsdl->dump($filename); - } else { - /** - * @see Zend_Soap_AutoDiscover_Exception - */ - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Cannot dump autodiscovered contents, WSDL file has not been generated yet."); - } - } - - /** - * Proxy to WSDL toXml() function - * - * @return string - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function toXml() - { - if($this->_wsdl !== null) { - return $this->_wsdl->toXml(); - } else { - /** - * @see Zend_Soap_AutoDiscover_Exception - */ - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Cannot return autodiscovered contents, WSDL file has not been generated yet."); - } - } - - /** - * Return an array of functions in the WSDL - * - * @return array - */ - public function getFunctions() - { - return $this->_functions; - } - - /** - * Load Functions - * - * @param unknown_type $definition - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function loadFunctions($definition) - { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); - } - - /** - * Set Persistance - * - * @param int $mode - * @throws Zend_Soap_AutoDiscover_Exception - */ - public function setPersistence($mode) - { - #require_once "Zend/Soap/AutoDiscover/Exception.php"; - throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); - } - - /** - * Returns an XSD Type for the given PHP type - * - * @param string $type PHP Type to get the XSD type for - * @return string - */ - public function getType($type) - { - if (!($this->_wsdl instanceof Zend_Soap_Wsdl)) { - /** @todo Exception throwing may be more correct */ - - // WSDL is not defined yet, so we can't recognize type in context of current service - return ''; - } else { - return $this->_wsdl->getType($type); - } - } -} diff --git a/lib/Zend/Soap/AutoDiscover/Exception.php b/lib/Zend/Soap/AutoDiscover/Exception.php deleted file mode 100644 index dc056b9f751..00000000000 --- a/lib/Zend/Soap/AutoDiscover/Exception.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage AutoDiscover - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Exception - */ -#require_once "Zend/Exception.php"; - -/** - * @package Zend_Soap - * @subpackage AutoDiscover - */ -class Zend_Soap_AutoDiscover_Exception extends Zend_Exception -{ -} diff --git a/lib/Zend/Soap/Client.php b/lib/Zend/Soap/Client.php deleted file mode 100644 index 369ebda669a..00000000000 --- a/lib/Zend/Soap/Client.php +++ /dev/null @@ -1,1242 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Server - */ -#require_once 'Zend/Soap/Server.php'; - -/** - * @see Zend_Soap_Client_Local - */ -#require_once 'Zend/Soap/Client/Local.php'; - -/** - * @see Zend_Soap_Client_Common - */ -#require_once 'Zend/Soap/Client/Common.php'; - -/** - * Zend_Soap_Client - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Client -{ - /** - * Encoding - * @var string - */ - protected $_encoding = 'UTF-8'; - - /** - * Array of SOAP type => PHP class pairings for handling return/incoming values - * @var array - */ - protected $_classmap = null; - - /** - * Registered fault exceptions - * @var array - */ - protected $_faultExceptions = array(); - - /** - * SOAP version to use; SOAP_1_2 by default, to allow processing of headers - * @var int - */ - protected $_soapVersion = SOAP_1_2; - - /** Set of other SoapClient options */ - protected $_uri = null; - protected $_location = null; - protected $_style = null; - protected $_use = null; - protected $_login = null; - protected $_password = null; - protected $_proxy_host = null; - protected $_proxy_port = null; - protected $_proxy_login = null; - protected $_proxy_password = null; - protected $_local_cert = null; - protected $_passphrase = null; - protected $_compression = null; - protected $_connection_timeout = null; - protected $_stream_context = null; - protected $_features = null; - protected $_cache_wsdl = null; - protected $_user_agent = null; - protected $_exceptions = null; - - /** - * WSDL used to access server - * It also defines Zend_Soap_Client working mode (WSDL vs non-WSDL) - * - * @var string - */ - protected $_wsdl = null; - - /** - * SoapClient object - * - * @var SoapClient - */ - protected $_soapClient; - - /** - * Last invoked method - * - * @var string - */ - protected $_lastMethod = ''; - - /** - * SOAP request headers. - * - * Array of SoapHeader objects - * - * @var array - */ - protected $_soapInputHeaders = array(); - - /** - * Permanent SOAP request headers (shared between requests). - * - * Array of SoapHeader objects - * - * @var array - */ - protected $_permanentSoapInputHeaders = array(); - - /** - * Output SOAP headers. - * - * Array of SoapHeader objects - * - * @var array - */ - protected $_soapOutputHeaders = array(); - - /** - * Constructor - * - * @param string $wsdl - * @param array $options - */ - public function __construct($wsdl = null, $options = null) - { - if (!extension_loaded('soap')) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('SOAP extension is not loaded.'); - } - - if ($wsdl !== null) { - $this->setWsdl($wsdl); - } - if ($options !== null) { - $this->setOptions($options); - } - } - - /** - * Set wsdl - * - * @param string $wsdl - * @return Zend_Soap_Client - */ - public function setWsdl($wsdl) - { - $this->_wsdl = $wsdl; - $this->_soapClient = null; - - return $this; - } - - /** - * Get wsdl - * - * @return string - */ - public function getWsdl() - { - return $this->_wsdl; - } - - /** - * Set Options - * - * Allows setting options as an associative array of option => value pairs. - * - * @param array|Zend_Config $options - * @return Zend_Soap_Client - * @throws Zend_SoapClient_Exception - */ - public function setOptions($options) - { - if($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - foreach ($options as $key => $value) { - switch ($key) { - case 'classmap': - case 'classMap': - $this->setClassmap($value); - break; - case 'encoding': - $this->setEncoding($value); - break; - case 'soapVersion': - case 'soap_version': - $this->setSoapVersion($value); - break; - case 'wsdl': - $this->setWsdl($value); - break; - case 'uri': - $this->setUri($value); - break; - case 'location': - $this->setLocation($value); - break; - case 'style': - $this->setStyle($value); - break; - case 'use': - $this->setEncodingMethod($value); - break; - case 'login': - $this->setHttpLogin($value); - break; - case 'password': - $this->setHttpPassword($value); - break; - case 'proxy_host': - $this->setProxyHost($value); - break; - case 'proxy_port': - $this->setProxyPort($value); - break; - case 'proxy_login': - $this->setProxyLogin($value); - break; - case 'proxy_password': - $this->setProxyPassword($value); - break; - case 'local_cert': - $this->setHttpsCertificate($value); - break; - case 'passphrase': - $this->setHttpsCertPassphrase($value); - break; - case 'compression': - $this->setCompressionOptions($value); - break; - case 'stream_context': - $this->setStreamContext($value); - break; - case 'features': - $this->setSoapFeatures($value); - break; - case 'cache_wsdl': - $this->setWsdlCache($value); - break; - case 'useragent': - case 'userAgent': - case 'user_agent': - $this->setUserAgent($value); - break; - case 'exceptions': - $this->setExceptions($value); - break; - - // Not used now - // case 'connection_timeout': - // $this->_connection_timeout = $value; - // break; - - default: - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Unknown SOAP client option'); - break; - } - } - - return $this; - } - - /** - * Return array of options suitable for using with SoapClient constructor - * - * @return array - */ - public function getOptions() - { - $options = array(); - - $options['classmap'] = $this->getClassmap(); - $options['encoding'] = $this->getEncoding(); - $options['soap_version'] = $this->getSoapVersion(); - $options['wsdl'] = $this->getWsdl(); - $options['uri'] = $this->getUri(); - $options['location'] = $this->getLocation(); - $options['style'] = $this->getStyle(); - $options['use'] = $this->getEncodingMethod(); - $options['login'] = $this->getHttpLogin(); - $options['password'] = $this->getHttpPassword(); - $options['proxy_host'] = $this->getProxyHost(); - $options['proxy_port'] = $this->getProxyPort(); - $options['proxy_login'] = $this->getProxyLogin(); - $options['proxy_password'] = $this->getProxyPassword(); - $options['local_cert'] = $this->getHttpsCertificate(); - $options['passphrase'] = $this->getHttpsCertPassphrase(); - $options['compression'] = $this->getCompressionOptions(); - //$options['connection_timeout'] = $this->_connection_timeout; - $options['stream_context'] = $this->getStreamContext(); - $options['cache_wsdl'] = $this->getWsdlCache(); - $options['features'] = $this->getSoapFeatures(); - $options['user_agent'] = $this->getUserAgent(); - $options['exceptions'] = $this->getExceptions(); - - foreach ($options as $key => $value) { - /* - * ugly hack as I don't know if checking for '=== null' - * breaks some other option - */ - if (in_array($key, array('user_agent', 'cache_wsdl', 'compression', 'exceptions'))) { - if ($value === null) { - unset($options[$key]); - } - } else { - if ($value == null) { - unset($options[$key]); - } - } - } - - return $options; - } - - /** - * Set SOAP version - * - * @param int $version One of the SOAP_1_1 or SOAP_1_2 constants - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid soap version argument - */ - public function setSoapVersion($version) - { - if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid soap version specified. Use SOAP_1_1 or SOAP_1_2 constants.'); - } - $this->_soapVersion = $version; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get SOAP version - * - * @return int - */ - public function getSoapVersion() - { - return $this->_soapVersion; - } - - /** - * Set classmap - * - * @param array $classmap - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception for any invalid class in the class map - */ - public function setClassmap(array $classmap) - { - foreach ($classmap as $type => $class) { - if (!class_exists($class)) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid class in class map'); - } - } - - $this->_classmap = $classmap; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve classmap - * - * @return mixed - */ - public function getClassmap() - { - return $this->_classmap; - } - - /** - * Set encoding - * - * @param string $encoding - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid encoding argument - */ - public function setEncoding($encoding) - { - if (!is_string($encoding)) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid encoding specified'); - } - - $this->_encoding = $encoding; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Check for valid URN - * - * @param string $urn - * @return true - * @throws Zend_Soap_Client_Exception on invalid URN - */ - public function validateUrn($urn) - { - $scheme = parse_url($urn, PHP_URL_SCHEME); - if ($scheme === false || $scheme === null) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid URN'); - } - - return true; - - } - - /** - * Set URI - * - * URI in Web Service the target namespace - * - * @param string $uri - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid uri argument - */ - public function setUri($uri) - { - $this->validateUrn($uri); - $this->_uri = $uri; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve URI - * - * @return string - */ - public function getUri() - { - return $this->_uri; - } - - /** - * Set Location - * - * URI in Web Service the target namespace - * - * @param string $location - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid uri argument - */ - public function setLocation($location) - { - $this->validateUrn($location); - $this->_location = $location; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve URI - * - * @return string - */ - public function getLocation() - { - return $this->_location; - } - - /** - * Set request style - * - * @param int $style One of the SOAP_RPC or SOAP_DOCUMENT constants - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid style argument - */ - public function setStyle($style) - { - if (!in_array($style, array(SOAP_RPC, SOAP_DOCUMENT))) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid request style specified. Use SOAP_RPC or SOAP_DOCUMENT constants.'); - } - - $this->_style = $style; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get request style - * - * @return int - */ - public function getStyle() - { - return $this->_style; - } - - /** - * Set message encoding method - * - * @param int $use One of the SOAP_ENCODED or SOAP_LITERAL constants - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid message encoding method argument - */ - public function setEncodingMethod($use) - { - if (!in_array($use, array(SOAP_ENCODED, SOAP_LITERAL))) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid message encoding method. Use SOAP_ENCODED or SOAP_LITERAL constants.'); - } - - $this->_use = $use; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get message encoding method - * - * @return int - */ - public function getEncodingMethod() - { - return $this->_use; - } - - /** - * Set HTTP login - * - * @param string $login - * @return Zend_Soap_Client - */ - public function setHttpLogin($login) - { - $this->_login = $login; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve HTTP Login - * - * @return string - */ - public function getHttpLogin() - { - return $this->_login; - } - - /** - * Set HTTP password - * - * @param string $password - * @return Zend_Soap_Client - */ - public function setHttpPassword($password) - { - $this->_password = $password; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve HTTP Password - * - * @return string - */ - public function getHttpPassword() - { - return $this->_password; - } - - /** - * Set proxy host - * - * @param string $proxyHost - * @return Zend_Soap_Client - */ - public function setProxyHost($proxyHost) - { - $this->_proxy_host = $proxyHost; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve proxy host - * - * @return string - */ - public function getProxyHost() - { - return $this->_proxy_host; - } - - /** - * Set proxy port - * - * @param int $proxyPort - * @return Zend_Soap_Client - */ - public function setProxyPort($proxyPort) - { - $this->_proxy_port = (int)$proxyPort; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve proxy port - * - * @return int - */ - public function getProxyPort() - { - return $this->_proxy_port; - } - - /** - * Set proxy login - * - * @param string $proxyLogin - * @return Zend_Soap_Client - */ - public function setProxyLogin($proxyLogin) - { - $this->_proxy_login = $proxyLogin; - - $this->_soapClient = null; - - return $this; - } - - /** - * Retrieve proxy login - * - * @return string - */ - public function getProxyLogin() - { - return $this->_proxy_login; - } - - /** - * Set proxy password - * - * @param string $proxyLogin - * @return Zend_Soap_Client - */ - public function setProxyPassword($proxyPassword) - { - $this->_proxy_password = $proxyPassword; - - $this->_soapClient = null; - - return $this; - } - - /** - * Set HTTPS client certificate path - * - * @param string $localCert local certificate path - * @return Zend_Soap_Client - * @throws Zend_Soap_Client_Exception with invalid local certificate path argument - */ - public function setHttpsCertificate($localCert) - { - if (!is_readable($localCert)) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('Invalid HTTPS client certificate path.'); - } - - $this->_local_cert = $localCert; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get HTTPS client certificate path - * - * @return string - */ - public function getHttpsCertificate() - { - return $this->_local_cert; - } - - /** - * Set HTTPS client certificate passphrase - * - * @param string $passphrase - * @return Zend_Soap_Client - */ - public function setHttpsCertPassphrase($passphrase) - { - $this->_passphrase = $passphrase; - - $this->_soapClient = null; - - return $this; - } - - /** - * Get HTTPS client certificate passphrase - * - * @return string - */ - public function getHttpsCertPassphrase() - { - return $this->_passphrase; - } - - /** - * Set compression options - * - * @param int|null $compressionOptions - * @return Zend_Soap_Client - */ - public function setCompressionOptions($compressionOptions) - { - if ($compressionOptions === null) { - $this->_compression = null; - } else { - $this->_compression = (int)$compressionOptions; - } - $this->_soapClient = null; - return $this; - } - - /** - * Get Compression options - * - * @return int - */ - public function getCompressionOptions() - { - return $this->_compression; - } - - /** - * Retrieve proxy password - * - * @return string - */ - public function getProxyPassword() - { - return $this->_proxy_password; - } - - /** - * Set Stream Context - * - * @return Zend_Soap_Client - */ - public function setStreamContext($context) - { - if(!is_resource($context) || get_resource_type($context) !== "stream-context") { - /** - * @see Zend_Soap_Client_Exception - */ - #require_once "Zend/Soap/Client/Exception.php"; - throw new Zend_Soap_Client_Exception( - "Invalid stream context resource given." - ); - } - - $this->_stream_context = $context; - return $this; - } - - /** - * Get Stream Context - * - * @return resource - */ - public function getStreamContext() - { - return $this->_stream_context; - } - - /** - * Set the SOAP Feature options. - * - * @param string|int $feature - * @return Zend_Soap_Client - */ - public function setSoapFeatures($feature) - { - $this->_features = $feature; - - $this->_soapClient = null; - return $this; - } - - /** - * Return current SOAP Features options - * - * @return int - */ - public function getSoapFeatures() - { - return $this->_features; - } - - /** - * Set the SOAP Wsdl Caching Options - * - * @param string|int|boolean|null $caching - * @return Zend_Soap_Client - */ - public function setWsdlCache($caching) - { - if ($caching === null) { - $this->_cache_wsdl = null; - } else { - $this->_cache_wsdl = (int)$caching; - } - return $this; - } - - /** - * Get current SOAP Wsdl Caching option - * - * @return int - */ - public function getWsdlCache() - { - return $this->_cache_wsdl; - } - - /** - * Set the string to use in User-Agent header - * - * @param string|null $userAgent - * @return Zend_Soap_Client - */ - public function setUserAgent($userAgent) - { - if ($userAgent === null) { - $this->_user_agent = null; - } else { - $this->_user_agent = (string)$userAgent; - } - return $this; - } - - /** - * Get current string to use in User-Agent header - * - * @return string|null - */ - public function getUserAgent() - { - return $this->_user_agent; - } - - /** - * Set the exceptions option - * - * The exceptions option is a boolean value defining whether soap errors - * throw exceptions. - * - * @see http://php.net/manual/soapclient.soapclient.php#refsect1-soapclient.soapclient-parameters - * - * @param bool $exceptions - * @return $this - */ - public function setExceptions($exceptions) - { - $this->_exceptions = (bool) $exceptions; - - return $this; - } - - /** - * Get the exceptions option - * - * The exceptions option is a boolean value defining whether soap errors - * throw exceptions. - * - * @see http://php.net/manual/soapclient.soapclient.php#refsect1-soapclient.soapclient-parameters - * - * @return bool|null - */ - public function getExceptions() - { - return $this->_exceptions; - } - - /** - * Retrieve request XML - * - * @return string - */ - public function getLastRequest() - { - if ($this->_soapClient !== null) { - return $this->_soapClient->__getLastRequest(); - } - - return ''; - } - - /** - * Get response XML - * - * @return string - */ - public function getLastResponse() - { - if ($this->_soapClient !== null) { - return $this->_soapClient->__getLastResponse(); - } - - return ''; - } - - /** - * Retrieve request headers - * - * @return string - */ - public function getLastRequestHeaders() - { - if ($this->_soapClient !== null) { - return $this->_soapClient->__getLastRequestHeaders(); - } - - return ''; - } - - /** - * Retrieve response headers (as string) - * - * @return string - */ - public function getLastResponseHeaders() - { - if ($this->_soapClient !== null) { - return $this->_soapClient->__getLastResponseHeaders(); - } - - return ''; - } - - /** - * Retrieve last invoked method - * - * @return string - */ - public function getLastMethod() - { - return $this->_lastMethod; - } - - /** - * Do request proxy method. - * - * May be overridden in subclasses - * - * @internal - * @param Zend_Soap_Client_Common $client - * @param string $request - * @param string $location - * @param string $action - * @param int $version - * @param int $one_way - * @return mixed - */ - public function _doRequest(Zend_Soap_Client_Common $client, $request, $location, $action, $version, $one_way = null) - { - // Perform request as is - if ($one_way == null) { - return call_user_func(array($client,'SoapClient::__doRequest'), $request, $location, $action, $version); - } else { - return call_user_func(array($client,'SoapClient::__doRequest'), $request, $location, $action, $version, $one_way); - } - } - - /** - * Initialize SOAP Client object - * - * @throws Zend_Soap_Client_Exception - */ - protected function _initSoapClientObject() - { - $wsdl = $this->getWsdl(); - $options = array_merge($this->getOptions(), array('trace' => true)); - - if ($wsdl == null) { - if (!isset($options['location'])) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'location\' parameter is required in non-WSDL mode.'); - } - if (!isset($options['uri'])) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'uri\' parameter is required in non-WSDL mode.'); - } - } else { - if (isset($options['use'])) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'use\' parameter only works in non-WSDL mode.'); - } - if (isset($options['style'])) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'style\' parameter only works in non-WSDL mode.'); - } - } - unset($options['wsdl']); - - $this->_soapClient = new Zend_Soap_Client_Common(array($this, '_doRequest'), $wsdl, $options); - } - - - /** - * Perform arguments pre-processing - * - * My be overridden in descendant classes - * - * @param array $arguments - */ - protected function _preProcessArguments($arguments) - { - // Do nothing - return $arguments; - } - - /** - * Perform result pre-processing - * - * My be overridden in descendant classes - * - * @param array $arguments - */ - protected function _preProcessResult($result) - { - // Do nothing - return $result; - } - - /** - * Add SOAP input header - * - * @param SoapHeader $header - * @param boolean $permanent - * @return Zend_Soap_Client - */ - public function addSoapInputHeader(SoapHeader $header, $permanent = false) - { - if ($permanent) { - $this->_permanentSoapInputHeaders[] = $header; - } else { - $this->_soapInputHeaders[] = $header; - } - - return $this; - } - - /** - * Reset SOAP input headers - * - * @return Zend_Soap_Client - */ - public function resetSoapInputHeaders() - { - $this->_permanentSoapInputHeaders = array(); - $this->_soapInputHeaders = array(); - - return $this; - } - - /** - * Get last SOAP output headers - * - * @return array - */ - public function getLastSoapOutputHeaderObjects() - { - return $this->_soapOutputHeaders; - } - - /** - * Perform a SOAP call - * - * @param string $name - * @param array $arguments - * @return mixed - */ - public function __call($name, $arguments) - { - $soapClient = $this->getSoapClient(); - - $this->_lastMethod = $name; - - $soapHeaders = array_merge($this->_permanentSoapInputHeaders, $this->_soapInputHeaders); - $result = $soapClient->__soapCall($name, - $this->_preProcessArguments($arguments), - null, /* Options are already set to the SOAP client object */ - (count($soapHeaders) > 0)? $soapHeaders : null, - $this->_soapOutputHeaders); - - // Reset non-permanent input headers - $this->_soapInputHeaders = array(); - - return $this->_preProcessResult($result); - } - - - /** - * Return a list of available functions - * - * @return array - * @throws Zend_Soap_Client_Exception - */ - public function getFunctions() - { - if ($this->getWsdl() == null) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'getFunctions\' method is available only in WSDL mode.'); - } - - $soapClient = $this->getSoapClient(); - return $soapClient->__getFunctions(); - } - - - /** - * Get used types. - * - * @return array - */ - - /** - * Return a list of SOAP types - * - * @return array - * @throws Zend_Soap_Client_Exception - */ - public function getTypes() - { - if ($this->getWsdl() == null) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('\'getTypes\' method is available only in WSDL mode.'); - } - - $soapClient = $this->getSoapClient(); - - return $soapClient->__getTypes(); - } - - /** - * @param SoapClient $soapClient - * @return Zend_Soap_Client - */ - public function setSoapClient(SoapClient $soapClient) - { - $this->_soapClient = $soapClient; - return $this; - } - - /** - * @return SoapClient - */ - public function getSoapClient() - { - if ($this->_soapClient == null) { - $this->_initSoapClientObject(); - } - return $this->_soapClient; - } - - /** - * @param string $name - * @param string $value - * @return Zend_Soap_Client - */ - public function setCookie($cookieName, $cookieValue=null) - { - $soapClient = $this->getSoapClient(); - $soapClient->__setCookie($cookieName, $cookieValue); - return $this; - } -} diff --git a/lib/Zend/Soap/Client/Common.php b/lib/Zend/Soap/Client/Common.php deleted file mode 100644 index 7880115ce73..00000000000 --- a/lib/Zend/Soap/Client/Common.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - - -if (extension_loaded('soap')) { - -/** - * @category Zend - * @package Zend_Soap - * @subpackage Client - */ -class Zend_Soap_Client_Common extends SoapClient -{ - /** - * doRequest() pre-processing method - * - * @var callback - */ - protected $_doRequestCallback; - - /** - * Common Soap Client constructor - * - * @param callback $doRequestMethod - * @param string $wsdl - * @param array $options - */ - function __construct($doRequestCallback, $wsdl, $options) - { - $this->_doRequestCallback = $doRequestCallback; - - parent::__construct($wsdl, $options); - } - - /** - * Performs SOAP request over HTTP. - * Overridden to implement different transport layers, perform additional XML processing or other purpose. - * - * @param string $request - * @param string $location - * @param string $action - * @param int $version - * @param int $one_way - * @return mixed - */ - function __doRequest($request, $location, $action, $version, $one_way = null) - { - if ($one_way === null) { - return call_user_func($this->_doRequestCallback, $this, $request, $location, $action, $version); - } else { - return call_user_func($this->_doRequestCallback, $this, $request, $location, $action, $version, $one_way); - } - } - -} - -} // end if (extension_loaded('soap') diff --git a/lib/Zend/Soap/Client/DotNet.php b/lib/Zend/Soap/Client/DotNet.php deleted file mode 100644 index b89b41320e0..00000000000 --- a/lib/Zend/Soap/Client/DotNet.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** Zend_Soap_Client */ -#require_once 'Zend/Soap/Client.php'; - -if (extension_loaded('soap')) { - -/** - * Zend_Soap_Client_Local - * - * Class is intended to be used with .Net Web Services. - * - * Important! Class is at experimental stage now. - * Please leave your notes, compatiblity issues reports or - * suggestions in fw-webservices@lists.zend.com or fw-general@lists.com - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - */ -class Zend_Soap_Client_DotNet extends Zend_Soap_Client -{ - /** - * Constructor - * - * @param string $wsdl - * @param array $options - */ - public function __construct($wsdl = null, $options = null) - { - // Use SOAP 1.1 as default - $this->setSoapVersion(SOAP_1_1); - - parent::__construct($wsdl, $options); - } - - - /** - * Perform arguments pre-processing - * - * My be overridden in descendant classes - * - * @param array $arguments - * @throws Zend_Soap_Client_Exception - */ - protected function _preProcessArguments($arguments) - { - if (count($arguments) > 1 || - (count($arguments) == 1 && !is_array(reset($arguments))) - ) { - #require_once 'Zend/Soap/Client/Exception.php'; - throw new Zend_Soap_Client_Exception('.Net webservice arguments have to be grouped into array: array(\'a\' => $a, \'b\' => $b, ...).'); - } - - // Do nothing - return $arguments; - } - - /** - * Perform result pre-processing - * - * My be overridden in descendant classes - * - * @param array $arguments - */ - protected function _preProcessResult($result) - { - $resultProperty = $this->getLastMethod() . 'Result'; - - return $result->$resultProperty; - } - -} - -} // end if (extension_loaded('soap') diff --git a/lib/Zend/Soap/Client/Exception.php b/lib/Zend/Soap/Client/Exception.php deleted file mode 100644 index 999e6edb02e..00000000000 --- a/lib/Zend/Soap/Client/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** Zend_Exception */ -#require_once 'Zend/Exception.php'; - -/** - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Soap_Client_Exception extends Zend_Exception -{} - diff --git a/lib/Zend/Soap/Client/Local.php b/lib/Zend/Soap/Client/Local.php deleted file mode 100644 index a25c35b10a2..00000000000 --- a/lib/Zend/Soap/Client/Local.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** Zend_Soap_Server */ -#require_once 'Zend/Soap/Server.php'; - -/** Zend_Soap_Client */ -#require_once 'Zend/Soap/Client.php'; - -if (extension_loaded('soap')) { - -/** - * Zend_Soap_Client_Local - * - * Class is intended to be used as local SOAP client which works - * with a provided Server object. - * - * Could be used for development or testing purposes. - * - * @category Zend - * @package Zend_Soap - * @subpackage Client - */ -class Zend_Soap_Client_Local extends Zend_Soap_Client -{ - /** - * Server object - * - * @var Zend_Soap_Server - */ - protected $_server; - - /** - * Local client constructor - * - * @param Zend_Soap_Server $server - * @param string $wsdl - * @param array $options - */ - function __construct(Zend_Soap_Server $server, $wsdl, $options = null) - { - $this->_server = $server; - - // Use Server specified SOAP version as default - $this->setSoapVersion($server->getSoapVersion()); - - parent::__construct($wsdl, $options); - } - - /** - * Actual "do request" method. - * - * @internal - * @param Zend_Soap_Client_Common $client - * @param string $request - * @param string $location - * @param string $action - * @param int $version - * @param int $one_way - * @return mixed - */ - public function _doRequest(Zend_Soap_Client_Common $client, $request, $location, $action, $version, $one_way = null) - { - // Perform request as is - ob_start(); - $this->_server->handle($request); - $response = ob_get_clean(); - - if ($response === null || $response === '') { - $serverResponse = $this->server->getResponse(); - if ($serverResponse !== null) { - $response = $serverResponse; - } - } - - return $response; - } -} - -} // end if (extension_loaded('soap') diff --git a/lib/Zend/Soap/Server.php b/lib/Zend/Soap/Server.php deleted file mode 100644 index 203ffdba602..00000000000 --- a/lib/Zend/Soap/Server.php +++ /dev/null @@ -1,1022 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Server - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** - * @see Zend_Server_Interface - */ -#require_once 'Zend/Server/Interface.php'; - -/** @see Zend_Xml_Security */ -#require_once 'Zend/Xml/Security.php'; - -/** @see Zend_Xml_Exception */ -#require_once 'Zend/Xml/Exception.php'; - -/** - * Zend_Soap_Server - * - * @category Zend - * @package Zend_Soap - * @subpackage Server - * @uses Zend_Server_Interface - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Soap_Server implements Zend_Server_Interface -{ - /** - * Actor URI - * @var string URI - */ - protected $_actor; - - /** - * Class registered with this server - * @var string - */ - protected $_class; - - /** - * Arguments to pass to {@link $_class} constructor - * @var array - */ - protected $_classArgs = array(); - - /** - * Object registered with this server - */ - protected $_object; - - /** - * Array of SOAP type => PHP class pairings for handling return/incoming values - * @var array - */ - protected $_classmap; - - /** - * Encoding - * @var string - */ - protected $_encoding; - - /** - * SOAP Server Features - * - * @var int - */ - protected $_features; - - /** - * WSDL Caching Options of SOAP Server - * - * @var mixed - */ - protected $_wsdlCache; - - /** - * WS-I compliant - * - * @var boolean - */ - protected $_wsiCompliant; - - /** - * Registered fault exceptions - * @var array - */ - protected $_faultExceptions = array(); - - /** - * Functions registered with this server; may be either an array or the SOAP_FUNCTIONS_ALL - * constant - * @var array|int - */ - protected $_functions = array(); - - /** - * Persistence mode; should be one of the SOAP persistence constants - * @var int - */ - protected $_persistence; - - /** - * Request XML - * @var string - */ - protected $_request; - - /** - * Response XML - * @var string - */ - protected $_response; - - /** - * Flag: whether or not {@link handle()} should return a response instead - * of automatically emitting it. - * @var boolean - */ - protected $_returnResponse = false; - - /** - * SOAP version to use; SOAP_1_2 by default, to allow processing of headers - * @var int - */ - protected $_soapVersion = SOAP_1_2; - - /** - * URI or path to WSDL - * @var string - */ - protected $_wsdl; - - /** - * URI namespace for SOAP server - * @var string URI - */ - protected $_uri; - - /** - * Constructor - * - * Sets display_errors INI setting to off (prevent client errors due to bad - * XML in response). Registers {@link handlePhpErrors()} as error handler - * for E_USER_ERROR. - * - * If $wsdl is provided, it is passed on to {@link setWsdl()}; if any - * options are specified, they are passed on to {@link setOptions()}. - * - * @param string $wsdl - * @param array $options - * @return void - */ - public function __construct($wsdl = null, array $options = null) - { - if (!extension_loaded('soap')) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('SOAP extension is not loaded.'); - } - - if (null !== $wsdl) { - $this->setWsdl($wsdl); - } - - if (null !== $options) { - $this->setOptions($options); - } - } - - /** - * Set Options - * - * Allows setting options as an associative array of option => value pairs. - * - * @param array|Zend_Config $options - * @return Zend_Soap_Server - */ - public function setOptions($options) - { - if($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - foreach ($options as $key => $value) { - switch ($key) { - case 'actor': - $this->setActor($value); - break; - case 'classmap': - case 'classMap': - $this->setClassmap($value); - break; - case 'encoding': - $this->setEncoding($value); - break; - case 'soapVersion': - case 'soap_version': - $this->setSoapVersion($value); - break; - case 'uri': - $this->setUri($value); - break; - case 'wsdl': - $this->setWsdl($value); - break; - case 'featues': - trigger_error(__METHOD__ . ': the option "featues" is deprecated as of 1.10.x and will be removed with 2.0.0; use "features" instead', E_USER_NOTICE); - case 'features': - $this->setSoapFeatures($value); - break; - case 'cache_wsdl': - $this->setWsdlCache($value); - break; - case 'wsi_compliant': - $this->setWsiCompliant($value); - break; - default: - break; - } - } - - return $this; - } - - /** - * Return array of options suitable for using with SoapServer constructor - * - * @return array - */ - public function getOptions() - { - $options = array(); - if (null !== $this->_actor) { - $options['actor'] = $this->_actor; - } - - if (null !== $this->_classmap) { - $options['classmap'] = $this->_classmap; - } - - if (null !== $this->_encoding) { - $options['encoding'] = $this->_encoding; - } - - if (null !== $this->_soapVersion) { - $options['soap_version'] = $this->_soapVersion; - } - - if (null !== $this->_uri) { - $options['uri'] = $this->_uri; - } - - if (null !== $this->_features) { - $options['features'] = $this->_features; - } - - if (null !== $this->_wsdlCache) { - $options['cache_wsdl'] = $this->_wsdlCache; - } - - if (null !== $this->_wsiCompliant) { - $options['wsi_compliant'] = $this->_wsiCompliant; - } - - return $options; - } - /** - * Set WS-I compliant - * - * @param boolean $value - * @return Zend_Soap_Server - */ - public function setWsiCompliant($value) - { - if (is_bool($value)) { - $this->_wsiCompliant = $value; - } - return $this; - } - /** - * Gt WS-I compliant - * - * @return boolean - */ - public function getWsiCompliant() - { - return $this->_wsiCompliant; - } - /** - * Set encoding - * - * @param string $encoding - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception with invalid encoding argument - */ - public function setEncoding($encoding) - { - if (!is_string($encoding)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid encoding specified'); - } - - $this->_encoding = $encoding; - return $this; - } - - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Set SOAP version - * - * @param int $version One of the SOAP_1_1 or SOAP_1_2 constants - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception with invalid soap version argument - */ - public function setSoapVersion($version) - { - if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid soap version specified'); - } - - $this->_soapVersion = $version; - return $this; - } - - /** - * Get SOAP version - * - * @return int - */ - public function getSoapVersion() - { - return $this->_soapVersion; - } - - /** - * Check for valid URN - * - * @param string $urn - * @return true - * @throws Zend_Soap_Server_Exception on invalid URN - */ - public function validateUrn($urn) - { - $scheme = parse_url($urn, PHP_URL_SCHEME); - if ($scheme === false || $scheme === null) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid URN'); - } - - return true; - } - - /** - * Set actor - * - * Actor is the actor URI for the server. - * - * @param string $actor - * @return Zend_Soap_Server - */ - public function setActor($actor) - { - $this->validateUrn($actor); - $this->_actor = $actor; - return $this; - } - - /** - * Retrieve actor - * - * @return string - */ - public function getActor() - { - return $this->_actor; - } - - /** - * Set URI - * - * URI in SoapServer is actually the target namespace, not a URI; $uri must begin with 'urn:'. - * - * @param string $uri - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception with invalid uri argument - */ - public function setUri($uri) - { - $this->validateUrn($uri); - $this->_uri = $uri; - return $this; - } - - /** - * Retrieve URI - * - * @return string - */ - public function getUri() - { - return $this->_uri; - } - - /** - * Set classmap - * - * @param array $classmap - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception for any invalid class in the class map - */ - public function setClassmap($classmap) - { - if (!is_array($classmap)) { - /** - * @see Zend_Soap_Server_Exception - */ - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Classmap must be an array'); - } - foreach ($classmap as $type => $class) { - if (!class_exists($class)) { - /** - * @see Zend_Soap_Server_Exception - */ - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid class in class map'); - } - } - - $this->_classmap = $classmap; - return $this; - } - - /** - * Retrieve classmap - * - * @return mixed - */ - public function getClassmap() - { - return $this->_classmap; - } - - /** - * Set wsdl - * - * @param string $wsdl URI or path to a WSDL - * @return Zend_Soap_Server - */ - public function setWsdl($wsdl) - { - $this->_wsdl = $wsdl; - return $this; - } - - /** - * Retrieve wsdl - * - * @return string - */ - public function getWsdl() - { - return $this->_wsdl; - } - - /** - * Set the SOAP Feature options. - * - * @param string|int $feature - * @return Zend_Soap_Server - */ - public function setSoapFeatures($feature) - { - $this->_features = $feature; - return $this; - } - - /** - * Return current SOAP Features options - * - * @return int - */ - public function getSoapFeatures() - { - return $this->_features; - } - - /** - * Set the SOAP Wsdl Caching Options - * - * @param string|int|boolean $caching - * @return Zend_Soap_Server - */ - public function setWsdlCache($options) - { - $this->_wsdlCache = $options; - return $this; - } - - /** - * Get current SOAP Wsdl Caching option - */ - public function getWsdlCache() - { - return $this->_wsdlCache; - } - - /** - * Attach a function as a server method - * - * @param array|string $function Function name, array of function names to attach, - * or SOAP_FUNCTIONS_ALL to attach all functions - * @param string $namespace Ignored - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception on invalid functions - */ - public function addFunction($function, $namespace = '') - { - // Bail early if set to SOAP_FUNCTIONS_ALL - if ($this->_functions == SOAP_FUNCTIONS_ALL) { - return $this; - } - - if (is_array($function)) { - foreach ($function as $func) { - if (is_string($func) && function_exists($func)) { - $this->_functions[] = $func; - } else { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('One or more invalid functions specified in array'); - } - } - $this->_functions = array_merge($this->_functions, $function); - } elseif (is_string($function) && function_exists($function)) { - $this->_functions[] = $function; - } elseif ($function == SOAP_FUNCTIONS_ALL) { - $this->_functions = SOAP_FUNCTIONS_ALL; - } else { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid function specified'); - } - - if (is_array($this->_functions)) { - $this->_functions = array_unique($this->_functions); - } - - return $this; - } - - /** - * Attach a class to a server - * - * Accepts a class name to use when handling requests. Any additional - * arguments will be passed to that class' constructor when instantiated. - * - * See {@link setObject()} to set preconfigured object instances as request handlers. - * - * @param string $class Class Name which executes SOAP Requests at endpoint. - * @return Zend_Soap_Server - * @throws Zend_Soap_Server_Exception if called more than once, or if class - * does not exist - */ - public function setClass($class, $namespace = '', $argv = null) - { - if (isset($this->_class)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('A class has already been registered with this soap server instance'); - } - - if (!is_string($class)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid class argument (' . gettype($class) . ')'); - } - - if (!class_exists($class)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Class "' . $class . '" does not exist'); - } - - $this->_class = $class; - if (1 < func_num_args()) { - $argv = func_get_args(); - array_shift($argv); - $this->_classArgs = $argv; - } - - return $this; - } - - /** - * Attach an object to a server - * - * Accepts an instanciated object to use when handling requests. - * - * @param object $object - * @return Zend_Soap_Server - */ - public function setObject($object) - { - if(!is_object($object)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid object argument ('.gettype($object).')'); - } - - if(isset($this->_object)) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('An object has already been registered with this soap server instance'); - } - - if ($this->_wsiCompliant) { - #require_once 'Zend/Soap/Server/Proxy.php'; - $this->_object = new Zend_Soap_Server_Proxy($object); - } else { - $this->_object = $object; - } - - return $this; - } - - /** - * Return a server definition array - * - * Returns a list of all functions registered with {@link addFunction()}, - * merged with all public methods of the class set with {@link setClass()} - * (if any). - * - * @access public - * @return array - */ - public function getFunctions() - { - $functions = array(); - if (null !== $this->_class) { - $functions = get_class_methods($this->_class); - } elseif (null !== $this->_object) { - $functions = get_class_methods($this->_object); - } - - return array_merge((array) $this->_functions, $functions); - } - - /** - * Unimplemented: Load server definition - * - * @param array $array - * @return void - * @throws Zend_Soap_Server_Exception Unimplemented - */ - public function loadFunctions($definition) - { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Unimplemented'); - } - - /** - * Set server persistence - * - * @param int $mode - * @return Zend_Soap_Server - */ - public function setPersistence($mode) - { - if (!in_array($mode, array(SOAP_PERSISTENCE_SESSION, SOAP_PERSISTENCE_REQUEST))) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid persistence mode specified'); - } - - $this->_persistence = $mode; - return $this; - } - - /** - * Get server persistence - * - * @return Zend_Soap_Server - */ - public function getPersistence() - { - return $this->_persistence; - } - - /** - * Set request - * - * $request may be any of: - * - DOMDocument; if so, then cast to XML - * - DOMNode; if so, then grab owner document and cast to XML - * - SimpleXMLElement; if so, then cast to XML - * - stdClass; if so, calls __toString() and verifies XML - * - string; if so, verifies XML - * - * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request - * @return Zend_Soap_Server - */ - protected function _setRequest($request) - { - if ($request instanceof DOMDocument) { - $xml = $request->saveXML(); - } elseif ($request instanceof DOMNode) { - $xml = $request->ownerDocument->saveXML(); - } elseif ($request instanceof SimpleXMLElement) { - $xml = $request->asXML(); - } elseif (is_object($request) || is_string($request)) { - if (is_object($request)) { - $xml = $request->__toString(); - } else { - $xml = $request; - } - - $dom = new DOMDocument(); - try { - if(strlen($xml) == 0 || (!$dom = Zend_Xml_Security::scan($xml, $dom))) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception('Invalid XML'); - } - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Soap/Server/Exception.php'; - throw new Zend_Soap_Server_Exception( - $e->getMessage() - ); - } - } - $this->_request = $xml; - return $this; - } - - /** - * Retrieve request XML - * - * @return string - */ - public function getLastRequest() - { - return $this->_request; - } - - /** - * Set return response flag - * - * If true, {@link handle()} will return the response instead of - * automatically sending it back to the requesting client. - * - * The response is always available via {@link getResponse()}. - * - * @param boolean $flag - * @return Zend_Soap_Server - */ - public function setReturnResponse($flag) - { - $this->_returnResponse = ($flag) ? true : false; - return $this; - } - - /** - * Retrieve return response flag - * - * @return boolean - */ - public function getReturnResponse() - { - return $this->_returnResponse; - } - - /** - * Get response XML - * - * @return string - */ - public function getLastResponse() - { - return $this->_response; - } - - /** - * Get SoapServer object - * - * Uses {@link $_wsdl} and return value of {@link getOptions()} to instantiate - * SoapServer object, and then registers any functions or class with it, as - * well as peristence. - * - * @return SoapServer - */ - protected function _getSoap() - { - $options = $this->getOptions(); - $server = new SoapServer($this->_wsdl, $options); - - if (!empty($this->_functions)) { - $server->addFunction($this->_functions); - } - - if (!empty($this->_class)) { - $args = $this->_classArgs; - array_unshift($args, $this->_class); - if ($this->_wsiCompliant) { - #require_once 'Zend/Soap/Server/Proxy.php'; - array_unshift($args, 'Zend_Soap_Server_Proxy'); - } - call_user_func_array(array($server, 'setClass'), $args); - } - - if (!empty($this->_object)) { - $server->setObject($this->_object); - } - - if (null !== $this->_persistence) { - $server->setPersistence($this->_persistence); - } - - return $server; - } - - /** - * Handle a request - * - * Instantiates SoapServer object with options set in object, and - * dispatches its handle() method. - * - * $request may be any of: - * - DOMDocument; if so, then cast to XML - * - DOMNode; if so, then grab owner document and cast to XML - * - SimpleXMLElement; if so, then cast to XML - * - stdClass; if so, calls __toString() and verifies XML - * - string; if so, verifies XML - * - * If no request is passed, pulls request using php:://input (for - * cross-platform compatability purposes). - * - * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request Optional request - * @return void|string - */ - public function handle($request = null) - { - if (null === $request) { - $request = file_get_contents('php://input'); - } - - // Set Zend_Soap_Server error handler - $displayErrorsOriginalState = $this->_initializeSoapErrorContext(); - - $setRequestException = null; - /** - * @see Zend_Soap_Server_Exception - */ - #require_once 'Zend/Soap/Server/Exception.php'; - try { - $this->_setRequest($request); - } catch (Zend_Soap_Server_Exception $e) { - $setRequestException = $e; - } - - $soap = $this->_getSoap(); - - $fault = false; - ob_start(); - if ($setRequestException instanceof Exception) { - // Create SOAP fault message if we've caught a request exception - $fault = $this->fault($setRequestException->getMessage(), 'Sender'); - } else { - try { - $soap->handle($this->_request); - } catch (Exception $e) { - $fault = $this->fault($e); - } - } - $this->_response = ob_get_clean(); - - // Restore original error handler - restore_error_handler(); - ini_set('display_errors', $displayErrorsOriginalState); - - // Send a fault, if we have one - if ($fault) { - $soap->fault($fault->faultcode, $fault->faultstring); - } - - if (!$this->_returnResponse) { - echo $this->_response; - return; - } - - return $this->_response; - } - - /** - * Method initalizes the error context that the SOAPServer enviroment will run in. - * - * @return boolean display_errors original value - */ - protected function _initializeSoapErrorContext() - { - $displayErrorsOriginalState = ini_get('display_errors'); - ini_set('display_errors', false); - set_error_handler(array($this, 'handlePhpErrors'), E_USER_ERROR); - return $displayErrorsOriginalState; - } - - /** - * Register a valid fault exception - * - * @param string|array $class Exception class or array of exception classes - * @return Zend_Soap_Server - */ - public function registerFaultException($class) - { - $this->_faultExceptions = array_merge($this->_faultExceptions, (array) $class); - return $this; - } - - /** - * Deregister a fault exception from the fault exception stack - * - * @param string $class - * @return boolean - */ - public function deregisterFaultException($class) - { - if (in_array($class, $this->_faultExceptions, true)) { - $index = array_search($class, $this->_faultExceptions); - unset($this->_faultExceptions[$index]); - return true; - } - - return false; - } - - /** - * Return fault exceptions list - * - * @return array - */ - public function getFaultExceptions() - { - return $this->_faultExceptions; - } - - /** - * Generate a server fault - * - * Note that the arguments are reverse to those of SoapFault. - * - * If an exception is passed as the first argument, its message and code - * will be used to create the fault object if it has been registered via - * {@Link registerFaultException()}. - * - * @link http://www.w3.org/TR/soap12-part1/#faultcodes - * @param string|Exception $fault - * @param string $code SOAP Fault Codes - * @return SoapFault - */ - public function fault($fault = null, $code = "Receiver") - { - if ($fault instanceof Exception) { - $class = get_class($fault); - if (in_array($class, $this->_faultExceptions)) { - $message = $fault->getMessage(); - $eCode = $fault->getCode(); - $code = empty($eCode) ? $code : $eCode; - } else { - $message = 'Unknown error'; - } - } elseif(is_string($fault)) { - $message = $fault; - } else { - $message = 'Unknown error'; - } - - $allowedFaultModes = array( - 'VersionMismatch', 'MustUnderstand', 'DataEncodingUnknown', - 'Sender', 'Receiver', 'Server' - ); - if(!in_array($code, $allowedFaultModes)) { - $code = "Receiver"; - } - - return new SoapFault($code, $message); - } - - /** - * Throw PHP errors as SoapFaults - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - * @return void - * @throws SoapFault - */ - public function handlePhpErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null) - { - throw $this->fault($errstr, "Receiver"); - } -} diff --git a/lib/Zend/Soap/Server/Exception.php b/lib/Zend/Soap/Server/Exception.php deleted file mode 100644 index 18dd28449a0..00000000000 --- a/lib/Zend/Soap/Server/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Server - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - - -/** Zend_Exception */ -#require_once 'Zend/Exception.php'; - - -/** - * @category Zend - * @package Zend_Soap - * @subpackage Server - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Soap_Server_Exception extends Zend_Exception -{} - diff --git a/lib/Zend/Soap/Server/Proxy.php b/lib/Zend/Soap/Server/Proxy.php deleted file mode 100644 index 3139cadfc11..00000000000 --- a/lib/Zend/Soap/Server/Proxy.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage AutoDiscover - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id:$ - */ - -class Zend_Soap_Server_Proxy -{ - /** - * @var object - */ - protected $_classInstance; - /** - * @var string - */ - protected $_className; - /** - * Constructor - * - * @param object $service - */ - public function __construct($className, $classArgs = array()) - { - $class = new ReflectionClass($className); - $constructor = $class->getConstructor(); - if ($constructor === null) { - $this->_classInstance = $class->newInstance(); - } else { - $this->_classInstance = $class->newInstanceArgs($classArgs); - } - $this->_className = $className; - } - /** - * Proxy for the WS-I compliant call - * - * @param string $name - * @param string $arguments - * @return array - */ - public function __call($name, $arguments) - { - $result = call_user_func_array(array($this->_classInstance, $name), $this->_preProcessArguments($arguments)); - return array("{$name}Result"=>$result); - } - /** - * Pre process arguments - * - * @param mixed $arguments - * @return array - */ - protected function _preProcessArguments($arguments) - { - if (count($arguments) == 1 && is_object($arguments[0])) { - return get_object_vars($arguments[0]); - } else { - return $arguments; - } - } -} diff --git a/lib/Zend/Soap/Wsdl.php b/lib/Zend/Soap/Wsdl.php deleted file mode 100644 index 774089bcaff..00000000000 --- a/lib/Zend/Soap/Wsdl.php +++ /dev/null @@ -1,670 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_Interface - */ -#require_once "Zend/Soap/Wsdl/Strategy/Interface.php"; - -/** - * @see Zend_Soap_Wsdl_Strategy_Abstract - */ -#require_once "Zend/Soap/Wsdl/Strategy/Abstract.php"; - -/** @see Zend_Xml_Security */ -#require_once "Zend/Xml/Security.php"; - -/** - * Zend_Soap_Wsdl - * - * @category Zend - * @package Zend_Soap - */ -class Zend_Soap_Wsdl -{ - /** - * @var object DomDocument Instance - */ - private $_dom; - - /** - * @var object WSDL Root XML_Tree_Node - */ - private $_wsdl; - - /** - * @var string URI where the WSDL will be available - */ - private $_uri; - - /** - * @var DOMElement - */ - private $_schema = null; - - /** - * Types defined on schema - * - * @var array - */ - private $_includedTypes = array(); - - /** - * Strategy for detection of complex types - */ - protected $_strategy = null; - - - /** - * Constructor - * - * @param string $name Name of the Web Service being Described - * @param string $uri URI where the WSDL will be available - * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy - */ - public function __construct($name, $uri, $strategy = true) - { - if ($uri instanceof Zend_Uri_Http) { - $uri = $uri->getUri(); - } - $this->_uri = $uri; - - /** - * @todo change DomDocument object creation from cparsing to construxting using API - * It also should authomatically escape $name and $uri values if necessary - */ - $wsdl = "<?xml version='1.0' ?> - <definitions name='$name' targetNamespace='$uri' - xmlns='http://schemas.xmlsoap.org/wsdl/' - xmlns:tns='$uri' - xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' - xmlns:xsd='http://www.w3.org/2001/XMLSchema' - xmlns:soap-enc='http://schemas.xmlsoap.org/soap/encoding/' - xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'></definitions>"; - $this->_dom = new DOMDocument(); - if (!$this->_dom = Zend_Xml_Security::scan($wsdl, $this->_dom)) { - #require_once 'Zend/Server/Exception.php'; - throw new Zend_Server_Exception('Unable to create DomDocument'); - } - $this->_wsdl = $this->_dom->documentElement; - - $this->setComplexTypeStrategy($strategy); - } - - /** - * Set a new uri for this WSDL - * - * @param string|Zend_Uri_Http $uri - * @return Zend_Server_Wsdl - */ - public function setUri($uri) - { - if ($uri instanceof Zend_Uri_Http) { - $uri = $uri->getUri(); - } - $oldUri = $this->_uri; - $this->_uri = $uri; - - if($this->_dom !== null) { - // @todo: This is the worst hack ever, but its needed due to design and non BC issues of WSDL generation - $xml = $this->_dom->saveXML(); - $xml = str_replace($oldUri, $uri, $xml); - $this->_dom = new DOMDocument(); - $this->_dom = Zend_Xml_Security::scan($xml, $this->_dom); - } - - return $this; - } - - /** - * Set a strategy for complex type detection and handling - * - * @todo Boolean is for backwards compability with extractComplexType object var. Remove it in later versions. - * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy - * @return Zend_Soap_Wsdl - */ - public function setComplexTypeStrategy($strategy) - { - if($strategy === true) { - #require_once "Zend/Soap/Wsdl/Strategy/DefaultComplexType.php"; - $strategy = new Zend_Soap_Wsdl_Strategy_DefaultComplexType(); - } else if($strategy === false) { - #require_once "Zend/Soap/Wsdl/Strategy/AnyType.php"; - $strategy = new Zend_Soap_Wsdl_Strategy_AnyType(); - } else if(is_string($strategy)) { - if(class_exists($strategy)) { - $strategy = new $strategy(); - } else { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception( - sprintf("Strategy with name '%s does not exist.", $strategy - )); - } - } - - if(!($strategy instanceof Zend_Soap_Wsdl_Strategy_Interface)) { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception("Set a strategy that is not of type 'Zend_Soap_Wsdl_Strategy_Interface'"); - } - $this->_strategy = $strategy; - return $this; - } - - /** - * Get the current complex type strategy - * - * @return Zend_Soap_Wsdl_Strategy_Interface - */ - public function getComplexTypeStrategy() - { - return $this->_strategy; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_messages message} element to the WSDL - * - * @param string $name Name for the {@link http://www.w3.org/TR/wsdl#_messages message} - * @param array $parts An array of {@link http://www.w3.org/TR/wsdl#_message parts} - * The array is constructed like: 'name of part' => 'part xml schema data type' - * or 'name of part' => array('type' => 'part xml schema type') - * or 'name of part' => array('element' => 'part xml element name') - * @return object The new message's XML_Tree_Node for use in {@link function addDocumentation} - */ - public function addMessage($name, $parts) - { - $message = $this->_dom->createElement('message'); - - $message->setAttribute('name', $name); - - if (sizeof($parts) > 0) { - foreach ($parts as $name => $type) { - $part = $this->_dom->createElement('part'); - $part->setAttribute('name', $name); - if (is_array($type)) { - foreach ($type as $key => $value) { - $part->setAttribute($key, $value); - } - } else { - $part->setAttribute('type', $type); - } - $message->appendChild($part); - } - } - - $this->_wsdl->appendChild($message); - - return $message; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_porttypes portType} element to the WSDL - * - * @param string $name portType element's name - * @return object The new portType's XML_Tree_Node for use in {@link function addPortOperation} and {@link function addDocumentation} - */ - public function addPortType($name) - { - $portType = $this->_dom->createElement('portType'); - $portType->setAttribute('name', $name); - $this->_wsdl->appendChild($portType); - - return $portType; - } - - /** - * Add an {@link http://www.w3.org/TR/wsdl#_request-response operation} element to a portType element - * - * @param object $portType a portType XML_Tree_Node, from {@link function addPortType} - * @param string $name Operation name - * @param string $input Input Message - * @param string $output Output Message - * @param string $fault Fault Message - * @return object The new operation's XML_Tree_Node for use in {@link function addDocumentation} - */ - public function addPortOperation($portType, $name, $input = false, $output = false, $fault = false) - { - $operation = $this->_dom->createElement('operation'); - $operation->setAttribute('name', $name); - - if (is_string($input) && (strlen(trim($input)) >= 1)) { - $node = $this->_dom->createElement('input'); - $node->setAttribute('message', $input); - $operation->appendChild($node); - } - if (is_string($output) && (strlen(trim($output)) >= 1)) { - $node= $this->_dom->createElement('output'); - $node->setAttribute('message', $output); - $operation->appendChild($node); - } - if (is_string($fault) && (strlen(trim($fault)) >= 1)) { - $node = $this->_dom->createElement('fault'); - $node->setAttribute('message', $fault); - $operation->appendChild($node); - } - - $portType->appendChild($operation); - - return $operation; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_bindings binding} element to WSDL - * - * @param string $name Name of the Binding - * @param string $type name of the portType to bind - * @return object The new binding's XML_Tree_Node for use with {@link function addBindingOperation} and {@link function addDocumentation} - */ - public function addBinding($name, $portType) - { - $binding = $this->_dom->createElement('binding'); - $binding->setAttribute('name', $name); - $binding->setAttribute('type', $portType); - - $this->_wsdl->appendChild($binding); - - return $binding; - } - - /** - * Add an operation to a binding element - * - * @param object $binding A binding XML_Tree_Node returned by {@link function addBinding} - * @param array $input An array of attributes for the input element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} - * @param array $output An array of attributes for the output element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} - * @param array $fault An array of attributes for the fault element, allowed keys are: 'name', 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} - * @return object The new Operation's XML_Tree_Node for use with {@link function addSoapOperation} and {@link function addDocumentation} - */ - public function addBindingOperation($binding, $name, $input = false, $output = false, $fault = false) - { - $operation = $this->_dom->createElement('operation'); - $operation->setAttribute('name', $name); - - if (is_array($input)) { - $node = $this->_dom->createElement('input'); - $soap_node = $this->_dom->createElement('soap:body'); - foreach ($input as $name => $value) { - $soap_node->setAttribute($name, $value); - } - $node->appendChild($soap_node); - $operation->appendChild($node); - } - - if (is_array($output)) { - $node = $this->_dom->createElement('output'); - $soap_node = $this->_dom->createElement('soap:body'); - foreach ($output as $name => $value) { - $soap_node->setAttribute($name, $value); - } - $node->appendChild($soap_node); - $operation->appendChild($node); - } - - if (is_array($fault)) { - $node = $this->_dom->createElement('fault'); - /** - * Note. Do we really need name attribute to be also set at wsdl:fault node??? - * W3C standard doesn't mention it (http://www.w3.org/TR/wsdl#_soap:fault) - * But some real world WSDLs use it, so it may be required for compatibility reasons. - */ - if (isset($fault['name'])) { - $node->setAttribute('name', $fault['name']); - } - - $soap_node = $this->_dom->createElement('soap:fault'); - foreach ($fault as $name => $value) { - $soap_node->setAttribute($name, $value); - } - $node->appendChild($soap_node); - $operation->appendChild($node); - } - - $binding->appendChild($operation); - - return $operation; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_soap:binding SOAP binding} element to a Binding element - * - * @param object $binding A binding XML_Tree_Node returned by {@link function addBinding} - * @param string $style binding style, possible values are "rpc" (the default) and "document" - * @param string $transport Transport method (defaults to HTTP) - * @return boolean - */ - public function addSoapBinding($binding, $style = 'document', $transport = 'http://schemas.xmlsoap.org/soap/http') - { - $soap_binding = $this->_dom->createElement('soap:binding'); - $soap_binding->setAttribute('style', $style); - $soap_binding->setAttribute('transport', $transport); - - $binding->appendChild($soap_binding); - - return $soap_binding; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_soap:operation SOAP operation} to an operation element - * - * @param object $operation An operation XML_Tree_Node returned by {@link function addBindingOperation} - * @param string $soap_action SOAP Action - * @return boolean - */ - public function addSoapOperation($binding, $soap_action) - { - if ($soap_action instanceof Zend_Uri_Http) { - $soap_action = $soap_action->getUri(); - } - $soap_operation = $this->_dom->createElement('soap:operation'); - $soap_operation->setAttribute('soapAction', $soap_action); - - $binding->insertBefore($soap_operation, $binding->firstChild); - - return $soap_operation; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_services service} element to the WSDL - * - * @param string $name Service Name - * @param string $port_name Name of the port for the service - * @param string $binding Binding for the port - * @param string $location SOAP Address for the service - * @return object The new service's XML_Tree_Node for use with {@link function addDocumentation} - */ - public function addService($name, $port_name, $binding, $location) - { - if ($location instanceof Zend_Uri_Http) { - $location = $location->getUri(); - } - $service = $this->_dom->createElement('service'); - $service->setAttribute('name', $name); - - $port = $this->_dom->createElement('port'); - $port->setAttribute('name', $port_name); - $port->setAttribute('binding', $binding); - - $soap_address = $this->_dom->createElement('soap:address'); - $soap_address->setAttribute('location', $location); - - $port->appendChild($soap_address); - $service->appendChild($port); - - $this->_wsdl->appendChild($service); - - return $service; - } - - /** - * Add a documentation element to any element in the WSDL. - * - * Note that the WSDL {@link http://www.w3.org/TR/wsdl#_documentation specification} uses 'document', - * but the WSDL {@link http://schemas.xmlsoap.org/wsdl/ schema} uses 'documentation' instead. - * The {@link http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#WSDL_documentation_Element WS-I Basic Profile 1.1} recommends using 'documentation'. - * - * @param object $input_node An XML_Tree_Node returned by another method to add the documentation to - * @param string $documentation Human readable documentation for the node - * @return DOMElement The documentation element - */ - public function addDocumentation($input_node, $documentation) - { - if ($input_node === $this) { - $node = $this->_dom->documentElement; - } else { - $node = $input_node; - } - - $doc = $this->_dom->createElement('documentation'); - $doc_cdata = $this->_dom->createTextNode(str_replace(array("\r\n", "\r"), "\n", $documentation)); - $doc->appendChild($doc_cdata); - - if($node->hasChildNodes()) { - $node->insertBefore($doc, $node->firstChild); - } else { - $node->appendChild($doc); - } - - return $doc; - } - - /** - * Add WSDL Types element - * - * @param object $types A DomDocument|DomNode|DomElement|DomDocumentFragment with all the XML Schema types defined in it - */ - public function addTypes($types) - { - if ($types instanceof DomDocument) { - $dom = $this->_dom->importNode($types->documentElement); - $this->_wsdl->appendChild($types->documentElement); - } elseif ($types instanceof DomNode || $types instanceof DomElement || $types instanceof DomDocumentFragment ) { - $dom = $this->_dom->importNode($types); - $this->_wsdl->appendChild($dom); - } - } - - /** - * Add a complex type name that is part of this WSDL and can be used in signatures. - * - * @param string $type - * @return Zend_Soap_Wsdl - */ - public function addType($type) - { - if(!in_array($type, $this->_includedTypes)) { - $this->_includedTypes[] = $type; - } - return $this; - } - - /** - * Return an array of all currently included complex types - * - * @return array - */ - public function getTypes() - { - return $this->_includedTypes; - } - - /** - * Return the Schema node of the WSDL - * - * @return DOMElement - */ - public function getSchema() - { - if($this->_schema == null) { - $this->addSchemaTypeSection(); - } - - return $this->_schema; - } - - /** - * Return the WSDL as XML - * - * @return string WSDL as XML - */ - public function toXML() - { - return $this->_dom->saveXML(); - } - - /** - * Return DOM Document - * - * @return object DomDocum ent - */ - public function toDomDocument() - { - return $this->_dom; - } - - /** - * Echo the WSDL as XML - * - * @return boolean - */ - public function dump($filename = false) - { - if (!$filename) { - echo $this->toXML(); - return true; - } else { - return file_put_contents($filename, $this->toXML()); - } - } - - /** - * Returns an XSD Type for the given PHP type - * - * @param string $type PHP Type to get the XSD type for - * @return string - */ - public function getType($type) - { - switch (strtolower($type)) { - case 'string': - case 'str': - return 'xsd:string'; - case 'long': - return 'xsd:long'; - case 'int': - case 'integer': - return 'xsd:int'; - case 'float': - return 'xsd:float'; - case 'double': - return 'xsd:double'; - case 'boolean': - case 'bool': - return 'xsd:boolean'; - case 'array': - return 'soap-enc:Array'; - case 'object': - return 'xsd:struct'; - case 'mixed': - return 'xsd:anyType'; - case 'void': - return ''; - default: - // delegate retrieval of complex type to current strategy - return $this->addComplexType($type); - } - } - - /** - * This function makes sure a complex types section and schema additions are set. - * - * @return Zend_Soap_Wsdl - */ - public function addSchemaTypeSection() - { - if ($this->_schema === null) { - $this->_schema = $this->_dom->createElement('xsd:schema'); - $this->_schema->setAttribute('targetNamespace', $this->_uri); - $types = $this->_dom->createElement('types'); - $types->appendChild($this->_schema); - $this->_wsdl->appendChild($types); - } - return $this; - } - - /** - * Add a {@link http://www.w3.org/TR/wsdl#_types types} data type definition - * - * @param string $type Name of the class to be specified - * @return string XSD Type for the given PHP type - */ - public function addComplexType($type) - { - if (in_array($type, $this->getTypes())) { - return "tns:$type"; - } - $this->addSchemaTypeSection(); - - $strategy = $this->getComplexTypeStrategy(); - $strategy->setContext($this); - // delegates the detection of a complex type to the current strategy - return $strategy->addComplexType($type); - } - - /** - * Parse an xsd:element represented as an array into a DOMElement. - * - * @param array $element an xsd:element represented as an array - * @return DOMElement parsed element - */ - private function _parseElement($element) - { - if (!is_array($element)) { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception("The 'element' parameter needs to be an associative array."); - } - - $elementXml = $this->_dom->createElement('xsd:element'); - foreach ($element as $key => $value) { - if (in_array($key, array('sequence', 'all', 'choice'))) { - if (is_array($value)) { - $complexType = $this->_dom->createElement('xsd:complexType'); - if (count($value) > 0) { - $container = $this->_dom->createElement('xsd:' . $key); - foreach ($value as $subelement) { - $subelementXml = $this->_parseElement($subelement); - $container->appendChild($subelementXml); - } - $complexType->appendChild($container); - } - $elementXml->appendChild($complexType); - } - } else { - $elementXml->setAttribute($key, $value); - } - } - return $elementXml; - } - - /** - * Add an xsd:element represented as an array to the schema. - * - * Array keys represent attribute names and values their respective value. - * The 'sequence', 'all' and 'choice' keys must have an array of elements as their value, - * to add them to a nested complexType. - * - * Example: array( 'name' => 'MyElement', - * 'sequence' => array( array('name' => 'myString', 'type' => 'string'), - * array('name' => 'myInteger', 'type' => 'int') ) ); - * Resulting XML: <xsd:element name="MyElement"><xsd:complexType><xsd:sequence> - * <xsd:element name="myString" type="string"/> - * <xsd:element name="myInteger" type="int"/> - * </xsd:sequence></xsd:complexType></xsd:element> - * - * @param array $element an xsd:element represented as an array - * @return string xsd:element for the given element array - */ - public function addElement($element) - { - $schema = $this->getSchema(); - $elementXml = $this->_parseElement($element); - $schema->appendChild($elementXml); - return 'tns:' . $element['name']; - } -} diff --git a/lib/Zend/Soap/Wsdl/Exception.php b/lib/Zend/Soap/Wsdl/Exception.php deleted file mode 100644 index 811c645e372..00000000000 --- a/lib/Zend/Soap/Wsdl/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Exception - */ -#require_once "Zend/Exception.php"; - -/** - * Zend_Soap_Wsdl_Exception - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Exception extends Zend_Exception { } diff --git a/lib/Zend/Soap/Wsdl/Strategy/Abstract.php b/lib/Zend/Soap/Wsdl/Strategy/Abstract.php deleted file mode 100644 index 3f2d6176dd6..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/Abstract.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_Interface - */ -#require_once "Zend/Soap/Wsdl/Strategy/Interface.php"; - -/** - * Abstract class for Zend_Soap_Wsdl_Strategy. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Soap_Wsdl_Strategy_Abstract implements Zend_Soap_Wsdl_Strategy_Interface -{ - /** - * Context object - * - * @var Zend_Soap_Wsdl - */ - protected $_context; - - /** - * Set the Zend_Soap_Wsdl Context object this strategy resides in. - * - * @param Zend_Soap_Wsdl $context - * @return void - */ - public function setContext(Zend_Soap_Wsdl $context) - { - $this->_context = $context; - } - - /** - * Return the current Zend_Soap_Wsdl context object - * - * @return Zend_Soap_Wsdl - */ - public function getContext() - { - return $this->_context; - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/AnyType.php b/lib/Zend/Soap/Wsdl/Strategy/AnyType.php deleted file mode 100644 index 890dc0a08ac..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/AnyType.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_Interface - */ -#require_once "Zend/Soap/Wsdl/Strategy/Interface.php"; - -/** - * Zend_Soap_Wsdl_Strategy_AnyType - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Strategy_AnyType implements Zend_Soap_Wsdl_Strategy_Interface -{ - /** - * Not needed in this strategy. - * - * @param Zend_Soap_Wsdl $context - */ - public function setContext(Zend_Soap_Wsdl $context) - { - - } - - /** - * Returns xsd:anyType regardless of the input. - * - * @param string $type - * @return string - */ - public function addComplexType($type) - { - return 'xsd:anyType'; - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php b/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php deleted file mode 100644 index f669af097b4..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_DefaultComplexType - */ -#require_once "Zend/Soap/Wsdl/Strategy/DefaultComplexType.php"; - -/** - * Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex extends Zend_Soap_Wsdl_Strategy_DefaultComplexType -{ - protected $_inProcess = array(); - - /** - * Add an ArrayOfType based on the xsd:complexType syntax if type[] is detected in return value doc comment. - * - * @param string $type - * @return string tns:xsd-type - */ - public function addComplexType($type) - { - if (in_array($type, $this->_inProcess)) { - return "tns:" . $type; - } - $this->_inProcess[$type] = $type; - - $nestingLevel = $this->_getNestedCount($type); - - if($nestingLevel > 1) { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception( - "ArrayOfTypeComplex cannot return nested ArrayOfObject deeper than ". - "one level. Use array object properties to return deep nested data. - "); - } - - $singularType = $this->_getSingularPhpType($type); - - if(!class_exists($singularType)) { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception(sprintf( - "Cannot add a complex type %s that is not an object or where ". - "class could not be found in 'DefaultComplexType' strategy.", $type - )); - } - - if($nestingLevel == 1) { - // The following blocks define the Array of Object structure - $xsdComplexTypeName = $this->_addArrayOfComplexType($singularType, $type); - } else { - $xsdComplexTypeName = $singularType; - } - - // The array for the objects has been created, now build the object definition: - if(!in_array($singularType, $this->getContext()->getTypes())) { - parent::addComplexType($singularType); - } - - unset($this->_inProcess[$type]); - return "tns:".$xsdComplexTypeName; - } - - protected function _addArrayOfComplexType($singularType, $type) - { - $dom = $this->getContext()->toDomDocument(); - - $xsdComplexTypeName = $this->_getXsdComplexTypeName($singularType); - - if(!in_array($xsdComplexTypeName, $this->getContext()->getTypes())) { - $complexType = $dom->createElement('xsd:complexType'); - $complexType->setAttribute('name', $xsdComplexTypeName); - - $complexContent = $dom->createElement("xsd:complexContent"); - $complexType->appendChild($complexContent); - - $xsdRestriction = $dom->createElement("xsd:restriction"); - $xsdRestriction->setAttribute('base', 'soap-enc:Array'); - $complexContent->appendChild($xsdRestriction); - - $xsdAttribute = $dom->createElement("xsd:attribute"); - $xsdAttribute->setAttribute("ref", "soap-enc:arrayType"); - $xsdAttribute->setAttribute("wsdl:arrayType", sprintf("tns:%s[]", $singularType)); - $xsdRestriction->appendChild($xsdAttribute); - - $this->getContext()->getSchema()->appendChild($complexType); - $this->getContext()->addType($xsdComplexTypeName); - } - - return $xsdComplexTypeName; - } - - protected function _getXsdComplexTypeName($type) - { - return sprintf('ArrayOf%s', $type); - } - - /** - * From a nested definition with type[], get the singular PHP Type - * - * @param string $type - * @return string - */ - protected function _getSingularPhpType($type) - { - return str_replace("[]", "", $type); - } - - /** - * Return the array nesting level based on the type name - * - * @param string $type - * @return integer - */ - protected function _getNestedCount($type) - { - return substr_count($type, "[]"); - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeSequence.php b/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeSequence.php deleted file mode 100644 index d64df8978c2..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/ArrayOfTypeSequence.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_DefaultComplexType - */ -#require_once "Zend/Soap/Wsdl/Strategy/DefaultComplexType.php"; - -/** - * Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence extends Zend_Soap_Wsdl_Strategy_DefaultComplexType -{ - /** - * Add an unbounded ArrayOfType based on the xsd:sequence syntax if type[] is detected in return value doc comment. - * - * @param string $type - * @return string tns:xsd-type - */ - public function addComplexType($type) - { - $nestedCounter = $this->_getNestedCount($type); - - if($nestedCounter > 0) { - $singularType = $this->_getSingularType($type); - - for($i = 1; $i <= $nestedCounter; $i++) { - $complexTypeName = substr($this->_getTypeNameBasedOnNestingLevel($singularType, $i), 4); - $childTypeName = $this->_getTypeNameBasedOnNestingLevel($singularType, $i-1); - - $this->_addElementFromWsdlAndChildTypes($complexTypeName, $childTypeName); - } - // adding the PHP type which is resolved to a nested XSD type. therefore add only once. - $this->getContext()->addType($complexTypeName); - - return "tns:$complexTypeName"; - } else if (!in_array($type, $this->getContext()->getTypes())) { - // New singular complex type - return parent::addComplexType($type); - } else { - // Existing complex type - return $this->getContext()->getType($type); - } - } - - /** - * Return the ArrayOf or simple type name based on the singular xsdtype and the nesting level - * - * @param string $singularType - * @param int $level - * @return string - */ - protected function _getTypeNameBasedOnNestingLevel($singularType, $level) - { - if($level == 0) { - // This is not an Array anymore, return the xsd simple type - return $singularType; - } else { - $prefix = str_repeat("ArrayOf", $level); - $xsdType = $this->_getStrippedXsdType($singularType); - $arrayType = $prefix.$xsdType; - return "tns:$arrayType"; - } - } - - /** - * Strip the xsd: from a singularType and Format it nice for ArrayOf<Type> naming - * - * @param string $singularType - * @return string - */ - protected function _getStrippedXsdType($singularType) - { - return ucfirst(substr(strtolower($singularType), 4)); - } - - /** - * From a nested defintion with type[], get the singular xsd:type - * - * @throws Zend_Soap_Wsdl_Exception When no xsd:simpletype can be detected. - * @param string $type - * @return string - */ - protected function _getSingularType($type) - { - $singulartype = $this->getContext()->getType(str_replace("[]", "", $type)); - return $singulartype; - } - - /** - * Return the array nesting level based on the type name - * - * @param string $type - * @return integer - */ - protected function _getNestedCount($type) - { - return substr_count($type, "[]"); - } - - /** - * Append the complex type definition to the WSDL via the context access - * - * @param string $arrayType - * @param string $childTypeName - * @return void - */ - protected function _addElementFromWsdlAndChildTypes($arrayType, $childTypeName) - { - if (!in_array($arrayType, $this->getContext()->getTypes())) { - $dom = $this->getContext()->toDomDocument(); - - $complexType = $dom->createElement('xsd:complexType'); - $complexType->setAttribute('name', $arrayType); - - $sequence = $dom->createElement('xsd:sequence'); - - $element = $dom->createElement('xsd:element'); - $element->setAttribute('name', 'item'); - $element->setAttribute('type', $childTypeName); - $element->setAttribute('minOccurs', 0); - $element->setAttribute('maxOccurs', 'unbounded'); - $sequence->appendChild($element); - - $complexType->appendChild($sequence); - - $this->getContext()->getSchema()->appendChild($complexType); - $this->getContext()->addType($arrayType); - } - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/Composite.php b/lib/Zend/Soap/Wsdl/Strategy/Composite.php deleted file mode 100644 index 3026f9ea5a2..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/Composite.php +++ /dev/null @@ -1,188 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_Interface - */ -#require_once "Zend/Soap/Wsdl/Strategy/Interface.php"; - -/** - * Zend_Soap_Wsdl_Strategy_Composite - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Strategy_Composite implements Zend_Soap_Wsdl_Strategy_Interface -{ - /** - * Typemap of Complex Type => Strategy pairs. - * - * @var array - */ - protected $_typeMap = array(); - - /** - * Default Strategy of this composite - * - * @var string|Zend_Soap_Wsdl_Strategy_Interface - */ - protected $_defaultStrategy; - - /** - * Context WSDL file that this composite serves - * - * @var Zend_Soap_Wsdl|null - */ - protected $_context; - - /** - * Construct Composite WSDL Strategy. - * - * @throws Zend_Soap_Wsdl_Exception - * @param array $typeMap - * @param string|Zend_Soap_Wsdl_Strategy_Interface $defaultStrategy - */ - public function __construct(array $typeMap=array(), $defaultStrategy="Zend_Soap_Wsdl_Strategy_DefaultComplexType") - { - foreach($typeMap AS $type => $strategy) { - $this->connectTypeToStrategy($type, $strategy); - } - $this->_defaultStrategy = $defaultStrategy; - } - - /** - * Connect a complex type to a given strategy. - * - * @throws Zend_Soap_Wsdl_Exception - * @param string $type - * @param string|Zend_Soap_Wsdl_Strategy_Interface $strategy - * @return Zend_Soap_Wsdl_Strategy_Composite - */ - public function connectTypeToStrategy($type, $strategy) - { - if(!is_string($type)) { - /** - * @see Zend_Soap_Wsdl_Exception - */ - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception("Invalid type given to Composite Type Map."); - } - $this->_typeMap[$type] = $strategy; - return $this; - } - - /** - * Return default strategy of this composite - * - * @throws Zend_Soap_Wsdl_Exception - * @param string $type - * @return Zend_Soap_Wsdl_Strategy_Interface - */ - public function getDefaultStrategy() - { - $strategy = $this->_defaultStrategy; - if(is_string($strategy) && class_exists($strategy)) { - $strategy = new $strategy; - } - if( !($strategy instanceof Zend_Soap_Wsdl_Strategy_Interface) ) { - /** - * @see Zend_Soap_Wsdl_Exception - */ - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception( - "Default Strategy for Complex Types is not a valid strategy object." - ); - } - $this->_defaultStrategy = $strategy; - return $strategy; - } - - /** - * Return specific strategy or the default strategy of this type. - * - * @throws Zend_Soap_Wsdl_Exception - * @param string $type - * @return Zend_Soap_Wsdl_Strategy_Interface - */ - public function getStrategyOfType($type) - { - if(isset($this->_typeMap[$type])) { - $strategy = $this->_typeMap[$type]; - - if(is_string($strategy) && class_exists($strategy)) { - $strategy = new $strategy(); - } - - if( !($strategy instanceof Zend_Soap_Wsdl_Strategy_Interface) ) { - /** - * @see Zend_Soap_Wsdl_Exception - */ - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception( - "Strategy for Complex Type '".$type."' is not a valid strategy object." - ); - } - $this->_typeMap[$type] = $strategy; - } else { - $strategy = $this->getDefaultStrategy(); - } - return $strategy; - } - - /** - * Method accepts the current WSDL context file. - * - * @param Zend_Soap_Wsdl $context - */ - public function setContext(Zend_Soap_Wsdl $context) - { - $this->_context = $context; - return $this; - } - - /** - * Create a complex type based on a strategy - * - * @throws Zend_Soap_Wsdl_Exception - * @param string $type - * @return string XSD type - */ - public function addComplexType($type) - { - if(!($this->_context instanceof Zend_Soap_Wsdl) ) { - /** - * @see Zend_Soap_Wsdl_Exception - */ - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception( - "Cannot add complex type '".$type."', no context is set for this composite strategy." - ); - } - - $strategy = $this->getStrategyOfType($type); - $strategy->setContext($this->_context); - return $strategy->addComplexType($type); - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/DefaultComplexType.php b/lib/Zend/Soap/Wsdl/Strategy/DefaultComplexType.php deleted file mode 100644 index edef76fd179..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/DefaultComplexType.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Soap_Wsdl_Strategy_Abstract - */ -#require_once "Zend/Soap/Wsdl/Strategy/Abstract.php"; - -/** - * Zend_Soap_Wsdl_Strategy_DefaultComplexType - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Soap_Wsdl_Strategy_DefaultComplexType extends Zend_Soap_Wsdl_Strategy_Abstract -{ - /** - * Add a complex type by recursivly using all the class properties fetched via Reflection. - * - * @param string $type Name of the class to be specified - * @return string XSD Type for the given PHP type - */ - public function addComplexType($type) - { - if(!class_exists($type)) { - #require_once "Zend/Soap/Wsdl/Exception.php"; - throw new Zend_Soap_Wsdl_Exception(sprintf( - "Cannot add a complex type %s that is not an object or where ". - "class could not be found in 'DefaultComplexType' strategy.", $type - )); - } - - $dom = $this->getContext()->toDomDocument(); - $class = new ReflectionClass($type); - - $defaultProperties = $class->getDefaultProperties(); - - $complexType = $dom->createElement('xsd:complexType'); - $complexType->setAttribute('name', $type); - - $all = $dom->createElement('xsd:all'); - - foreach ($class->getProperties() as $property) { - if ($property->isPublic() && preg_match_all('/@var\s+([^\s]+)/m', $property->getDocComment(), $matches)) { - - /** - * @todo check if 'xsd:element' must be used here (it may not be compatible with using 'complexType' - * node for describing other classes used as attribute types for current class - */ - $element = $dom->createElement('xsd:element'); - $element->setAttribute('name', $propertyName = $property->getName()); - $element->setAttribute('type', $this->getContext()->getType(trim($matches[1][0]))); - - // If the default value is null, then this property is nillable. - if ($defaultProperties[$propertyName] === null) { - $element->setAttribute('nillable', 'true'); - } - - $all->appendChild($element); - } - } - - $complexType->appendChild($all); - $this->getContext()->getSchema()->appendChild($complexType); - $this->getContext()->addType($type); - - return "tns:$type"; - } -} diff --git a/lib/Zend/Soap/Wsdl/Strategy/Interface.php b/lib/Zend/Soap/Wsdl/Strategy/Interface.php deleted file mode 100644 index 9a576055cad..00000000000 --- a/lib/Zend/Soap/Wsdl/Strategy/Interface.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Interface for Zend_Soap_Wsdl_Strategy. - * - * @category Zend - * @package Zend_Soap - * @subpackage Wsdl - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Soap_Wsdl_Strategy_Interface -{ - /** - * Method accepts the current WSDL context file. - * - * @param <type> $context - */ - public function setContext(Zend_Soap_Wsdl $context); - - /** - * Create a complex type based on a strategy - * - * @param string $type - * @return string XSD type - */ - public function addComplexType($type); -} diff --git a/lib/Zend/Stdlib/CallbackHandler.php b/lib/Zend/Stdlib/CallbackHandler.php deleted file mode 100644 index b45892645d3..00000000000 --- a/lib/Zend/Stdlib/CallbackHandler.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** - * CallbackHandler - * - * A handler for a event, event, filterchain, etc. Abstracts PHP callbacks, - * primarily to allow for lazy-loading and ensuring availability of default - * arguments (currying). - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Stdlib_CallbackHandler -{ - /** - * @var string|array PHP callback to invoke - */ - protected $callback; - - /** - * Did an error occur when testing the validity of the callback? - * @var bool - */ - protected $error = false; - - /** - * Callback metadata, if any - * @var array - */ - protected $metadata; - - /** - * Constructor - * - * @param string $event Event to which slot is subscribed - * @param string|array|object $callback PHP callback - * @param array $options Options used by the callback handler (e.g., priority) - * @return void - */ - public function __construct($callback, array $metadata = array()) - { - $this->metadata = $metadata; - $this->registerCallback($callback); - } - - /** - * Error handler - * - * Used by registerCallback() when calling is_callable() to capture engine warnings. - * - * @param int $errno - * @param string $errstr - * @return void - */ - public function errorHandler($errno, $errstr) - { - $this->error = true; - } - - /** - * Registers the callback provided in the constructor - * - * If you have pecl/weakref {@see http://pecl.php.net/weakref} installed, - * this method provides additional behavior. - * - * If a callback is a functor, or an array callback composing an object - * instance, this method will pass the object to a WeakRef instance prior - * to registering the callback. - * - * @param Callable $callback - * @return void - */ - protected function registerCallback($callback) - { - set_error_handler(array($this, 'errorHandler'), E_STRICT); - $callable = is_callable($callback); - restore_error_handler(); - if (!$callable || $this->error) { - #require_once 'Zend/Stdlib/Exception/InvalidCallbackException.php'; - throw new Zend_Stdlib_Exception_InvalidCallbackException('Invalid callback provided; not callable'); - } - - // If pecl/weakref is not installed, simply store the callback and return - set_error_handler(array($this, 'errorHandler'), E_WARNING); - $callable = class_exists('WeakRef'); - restore_error_handler(); - if (!$callable || $this->error) { - $this->callback = $callback; - return; - } - - // If WeakRef exists, we want to use it. - - // If we have a non-closure object, pass it to WeakRef, and then - // register it. - if (is_object($callback) && !$callback instanceof Closure) { - $this->callback = new WeakRef($callback); - return; - } - - // If we have a string or closure, register as-is - if (!is_array($callback)) { - $this->callback = $callback; - return; - } - - list($target, $method) = $callback; - - // If we have an array callback, and the first argument is not an - // object, register as-is - if (!is_object($target)) { - $this->callback = $callback; - return; - } - - // We have an array callback with an object as the first argument; - // pass it to WeakRef, and then register the new callback - $target = new WeakRef($target); - $this->callback = array($target, $method); - } - - /** - * Retrieve registered callback - * - * @return Callable - */ - public function getCallback() - { - $callback = $this->callback; - - // String callbacks -- simply return - if (is_string($callback)) { - return $callback; - } - - // WeakRef callbacks -- pull it out of the object and return it - if ($callback instanceof WeakRef) { - return $callback->get(); - } - - // Non-WeakRef object callback -- return it - if (is_object($callback)) { - return $callback; - } - - // Array callback with WeakRef object -- retrieve the object first, and - // then return - list($target, $method) = $callback; - if ($target instanceof WeakRef) { - return array($target->get(), $method); - } - - // Otherwise, return it - return $callback; - } - - /** - * Invoke handler - * - * @param array $args Arguments to pass to callback - * @return mixed - */ - public function call(array $args = array()) - { - $callback = $this->getCallback(); - - $isPhp54 = version_compare(PHP_VERSION, '5.4.0rc1', '>='); - - if ($isPhp54 && is_string($callback)) { - $this->validateStringCallbackFor54($callback); - } - - // Minor performance tweak; use call_user_func() until > 3 arguments - // reached - switch (count($args)) { - case 0: - if ($isPhp54) { - return $callback(); - } - return call_user_func($callback); - case 1: - if ($isPhp54) { - return $callback(array_shift($args)); - } - return call_user_func($callback, array_shift($args)); - case 2: - $arg1 = array_shift($args); - $arg2 = array_shift($args); - if ($isPhp54) { - return $callback($arg1, $arg2); - } - return call_user_func($callback, $arg1, $arg2); - case 3: - $arg1 = array_shift($args); - $arg2 = array_shift($args); - $arg3 = array_shift($args); - if ($isPhp54) { - return $callback($arg1, $arg2, $arg3); - } - return call_user_func($callback, $arg1, $arg2, $arg3); - default: - return call_user_func_array($callback, $args); - } - } - - /** - * Invoke as functor - * - * @return mixed - */ - public function __invoke() - { - return $this->call(func_get_args()); - } - - /** - * Get all callback metadata - * - * @return array - */ - public function getMetadata() - { - return $this->metadata; - } - - /** - * Retrieve a single metadatum - * - * @param string $name - * @return mixed - */ - public function getMetadatum($name) - { - if (array_key_exists($name, $this->metadata)) { - return $this->metadata[$name]; - } - return null; - } - - /** - * Validate a static method call - * - * Validates that a static method call in PHP 5.4 will actually work - * - * @param string $callback - * @return true - * @throws Zend_Stdlib_Exception_InvalidCallbackException if invalid - */ - protected function validateStringCallbackFor54($callback) - { - if (!strstr($callback, '::')) { - return true; - } - - list($class, $method) = explode('::', $callback, 2); - - if (!class_exists($class)) { - #require_once 'Zend/Stdlib/Exception/InvalidCallbackException.php'; - throw new Zend_Stdlib_Exception_InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a class that does not exist', - $callback - )); - } - - $r = new ReflectionClass($class); - if (!$r->hasMethod($method)) { - #require_once 'Zend/Stdlib/Exception/InvalidCallbackException.php'; - throw new Zend_Stdlib_Exception_InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a method that does not exist', - $callback - )); - } - $m = $r->getMethod($method); - if (!$m->isStatic()) { - #require_once 'Zend/Stdlib/Exception/InvalidCallbackException.php'; - throw new Zend_Stdlib_Exception_InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a method that is not static', - $callback - )); - } - - return true; - } -} diff --git a/lib/Zend/Stdlib/Exception.php b/lib/Zend/Stdlib/Exception.php deleted file mode 100644 index 05cb27533e3..00000000000 --- a/lib/Zend/Stdlib/Exception.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** - * Marker interface for Stdlib exceptions - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Stdlib_Exception -{ -} diff --git a/lib/Zend/Stdlib/Exception/InvalidCallbackException.php b/lib/Zend/Stdlib/Exception/InvalidCallbackException.php deleted file mode 100644 index 5a113f7d6ca..00000000000 --- a/lib/Zend/Stdlib/Exception/InvalidCallbackException.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -#require_once 'Zend/Stdlib/Exception.php'; - -/** - * Invalid callback exception - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Stdlib_Exception_InvalidCallbackException - extends DomainException - implements Zend_Stdlib_Exception -{ -} diff --git a/lib/Zend/Stdlib/PriorityQueue.php b/lib/Zend/Stdlib/PriorityQueue.php deleted file mode 100644 index 380b2766cb0..00000000000 --- a/lib/Zend/Stdlib/PriorityQueue.php +++ /dev/null @@ -1,319 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -#require_once 'Zend/Stdlib/SplPriorityQueue.php'; - -/** - * Re-usable, serializable priority queue implementation - * - * SplPriorityQueue acts as a heap; on iteration, each item is removed from the - * queue. If you wish to re-use such a queue, you need to clone it first. This - * makes for some interesting issues if you wish to delete items from the queue, - * or, as already stated, iterate over it multiple times. - * - * This class aggregates items for the queue itself, but also composes an - * "inner" iterator in the form of an SplPriorityQueue object for performing - * the actual iteration. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Stdlib_PriorityQueue implements Countable, IteratorAggregate, Serializable -{ - const EXTR_DATA = 0x00000001; - const EXTR_PRIORITY = 0x00000002; - const EXTR_BOTH = 0x00000003; - - /** - * Inner queue class to use for iteration - * @var string - */ - protected $queueClass = 'Zend_Stdlib_SplPriorityQueue'; - - /** - * Actual items aggregated in the priority queue. Each item is an array - * with keys "data" and "priority". - * @var array - */ - protected $items = array(); - - /** - * Inner queue object - * @var SplPriorityQueue - */ - protected $queue; - - /** - * Insert an item into the queue - * - * Priority defaults to 1 (low priority) if none provided. - * - * @param mixed $data - * @param int $priority - * @return Zend_Stdlib_PriorityQueue - */ - public function insert($data, $priority = 1) - { - $priority = (int) $priority; - $this->items[] = array( - 'data' => $data, - 'priority' => $priority, - ); - $this->getQueue()->insert($data, $priority); - return $this; - } - - /** - * Remove an item from the queue - * - * This is different than {@link extract()}; its purpose is to dequeue an - * item. - * - * This operation is potentially expensive, as it requires - * re-initialization and re-population of the inner queue. - * - * Note: this removes the first item matching the provided item found. If - * the same item has been added multiple times, it will not remove other - * instances. - * - * @param mixed $datum - * @return boolean False if the item was not found, true otherwise. - */ - public function remove($datum) - { - $found = false; - foreach ($this->items as $key => $item) { - if ($item['data'] === $datum) { - $found = true; - break; - } - } - if ($found) { - unset($this->items[$key]); - $this->queue = null; - $queue = $this->getQueue(); - foreach ($this->items as $item) { - $queue->insert($item['data'], $item['priority']); - } - return true; - } - return false; - } - - /** - * Is the queue empty? - * - * @return bool - */ - public function isEmpty() - { - return (0 === $this->count()); - } - - /** - * How many items are in the queue? - * - * @return int - */ - public function count() - { - return count($this->items); - } - - /** - * Peek at the top node in the queue, based on priority. - * - * @return mixed - */ - public function top() - { - return $this->getIterator()->top(); - } - - /** - * Extract a node from the inner queue and sift up - * - * @return mixed - */ - public function extract() - { - return $this->getQueue()->extract(); - } - - /** - * Retrieve the inner iterator - * - * SplPriorityQueue acts as a heap, which typically implies that as items - * are iterated, they are also removed. This does not work for situations - * where the queue may be iterated multiple times. As such, this class - * aggregates the values, and also injects an SplPriorityQueue. This method - * retrieves the inner queue object, and clones it for purposes of - * iteration. - * - * @return SplPriorityQueue - */ - public function getIterator() - { - $queue = $this->getQueue(); - return clone $queue; - } - - /** - * Serialize the data structure - * - * @return string - */ - public function serialize() - { - return serialize($this->items); - } - - /** - * Unserialize a string into a Zend_Stdlib_PriorityQueue object - * - * Serialization format is compatible with {@link Zend_Stdlib_SplPriorityQueue} - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - foreach (unserialize($data) as $item) { - $this->insert($item['data'], $item['priority']); - } - } - - /** - * Serialize to an array - * - * By default, returns only the item data, and in the order registered (not - * sorted). You may provide one of the EXTR_* flags as an argument, allowing - * the ability to return priorities or both data and priority. - * - * @param int $flag - * @return array - */ - public function toArray($flag = self::EXTR_DATA) - { - switch ($flag) { - case self::EXTR_BOTH: - return $this->items; - case self::EXTR_PRIORITY: - return array_map(array($this, 'returnPriority'), $this->items); - case self::EXTR_DATA: - default: - return array_map(array($this, 'returnData'), $this->items); - } - } - - /** - * Specify the internal queue class - * - * Please see {@link getIterator()} for details on the necessity of an - * internal queue class. The class provided should extend SplPriorityQueue. - * - * @param string $class - * @return Zend_Stdlib_PriorityQueue - */ - public function setInternalQueueClass($class) - { - $this->queueClass = (string) $class; - return $this; - } - - /** - * Does the queue contain the given datum? - * - * @param mixed $datum - * @return bool - */ - public function contains($datum) - { - foreach ($this->items as $item) { - if ($item['data'] === $datum) { - return true; - } - } - return false; - } - - /** - * Does the queue have an item with the given priority? - * - * @param int $priority - * @return bool - */ - public function hasPriority($priority) - { - foreach ($this->items as $item) { - if ($item['priority'] === $priority) { - return true; - } - } - return false; - } - - /** - * Get the inner priority queue instance - * - * @return Zend_Stdlib_SplPriorityQueue - */ - protected function getQueue() - { - if (null === $this->queue) { - $this->queue = new $this->queueClass(); - if (!$this->queue instanceof SplPriorityQueue) { - throw new DomainException(sprintf( - 'Zend_Stdlib_PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"', - get_class($this->queue) - )); - } - } - return $this->queue; - } - - /** - * Return priority from an internal item - * - * Used as a lambda in toArray(). - * - * @param array $item - * @return mixed - */ - public function returnPriority($item) - { - return $item['priority']; - } - - /** - * Return data from an internal item - * - * Used as a lambda in toArray(). - * - * @param array $item - * @return mixed - */ - public function returnData($item) - { - return $item['data']; - } -} diff --git a/lib/Zend/Stdlib/SplPriorityQueue.php b/lib/Zend/Stdlib/SplPriorityQueue.php deleted file mode 100644 index 7694cec85ee..00000000000 --- a/lib/Zend/Stdlib/SplPriorityQueue.php +++ /dev/null @@ -1,499 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -if (version_compare(PHP_VERSION, '5.3.0', '<')) { - /** - * SplPriorityQueue - * - * PHP 5.2.X userland implementation of PHP's SplPriorityQueue - */ - class SplPriorityQueue implements Iterator , Countable - { - /** - * Extract data only - */ - const EXTR_DATA = 0x00000001; - - /** - * Extract priority only - */ - const EXTR_PRIORITY = 0x00000002; - - /** - * Extract an array of ('data' => $value, 'priority' => $priority) - */ - const EXTR_BOTH = 0x00000003; - - /** - * Count of items in the queue - * @var int - */ - protected $count = 0; - - /** - * Flag indicating what should be returned when iterating or extracting - * @var int - */ - protected $extractFlags = self::EXTR_DATA; - - /** - * @var bool|array - */ - protected $preparedQueue = false; - - /** - * All items in the queue - * @var array - */ - protected $queue = array(); - - /** - * Constructor - * - * Creates a new, empty queue - * - * @return void - */ - public function __construct() - { - } - - /** - * Compare two priorities - * - * Returns positive integer if $priority1 is greater than $priority2, 0 - * if equal, negative otherwise. - * - * Unused internally, and only included in order to retain the same - * interface as PHP's SplPriorityQueue. - * - * @param mixed $priority1 - * @param mixed $priority2 - * @return int - */ - public function compare($priority1, $priority2) - { - if ($priority1 > $priority2) { - return 1; - } - if ($priority1 == $priority2) { - return 0; - } - - return -1; - } - - /** - * Countable: return number of items composed in the queue - * - * @return int - */ - public function count() - { - return $this->count; - } - - /** - * Iterator: return current item - * - * @return mixed - */ - public function current() - { - if (!$this->preparedQueue) { - $this->rewind(); - } - if (!$this->count) { - throw new OutOfBoundsException('Cannot iterate SplPriorityQueue; no elements present'); - } - -if (!is_array($this->preparedQueue)) { - throw new DomainException(sprintf( - "Queue was prepared, but is empty?\n PreparedQueue: %s\n Internal Queue: %s\n", - var_export($this->preparedQueue, 1), - var_export($this->queue, 1) - )); -} - - $return = array_shift($this->preparedQueue); - $priority = $return['priority']; - $priorityKey = $return['priorityKey']; - $key = $return['key']; - unset($return['key']); - unset($return['priorityKey']); - unset($this->queue[$priorityKey][$key]); - - switch ($this->extractFlags) { - case self::EXTR_DATA: - return $return['data']; - case self::EXTR_PRIORITY: - return $return['priority']; - case self::EXTR_BOTH: - default: - return $return; - }; - } - - /** - * Extract a node from top of the heap and sift up - * - * Returns either the value, the priority, or both, depending on the extract flag. - * - * @return mixed; - */ - public function extract() - { - if (!$this->count) { - return null; - } - - if (!$this->preparedQueue) { - $this->prepareQueue(); - } - - if (empty($this->preparedQueue)) { - return null; - } - - $return = array_shift($this->preparedQueue); - $priority = $return['priority']; - $priorityKey = $return['priorityKey']; - $key = $return['key']; - unset($return['key']); - unset($return['priorityKey']); - unset($this->queue[$priorityKey][$key]); - $this->count--; - - switch ($this->extractFlags) { - case self::EXTR_DATA: - return $return['data']; - case self::EXTR_PRIORITY: - return $return['priority']; - case self::EXTR_BOTH: - default: - return $return; - }; - } - - /** - * Insert a value into the heap, at the specified priority - * - * @param mixed $value - * @param mixed $priority - * @return void - */ - public function insert($value, $priority) - { - if (!is_scalar($priority)) { - $priority = serialize($priority); - } - if (!isset($this->queue[$priority])) { - $this->queue[$priority] = array(); - } - $this->queue[$priority][] = $value; - $this->count++; - $this->preparedQueue = false; - } - - /** - * Is the queue currently empty? - * - * @return bool - */ - public function isEmpty() - { - return (0 == $this->count); - } - - /** - * Iterator: return current key - * - * @return mixed Usually an int or string - */ - public function key() - { - return $this->count; - } - - /** - * Iterator: Move pointer forward - * - * @return void - */ - public function next() - { - $this->count--; - } - - /** - * Recover from corrupted state and allow further actions on the queue - * - * Unimplemented, and only included in order to retain the same interface as PHP's - * SplPriorityQueue. - * - * @return void - */ - public function recoverFromCorruption() - { - } - - /** - * Iterator: Move pointer to first item - * - * @return void - */ - public function rewind() - { - if (!$this->preparedQueue) { - $this->prepareQueue(); - } - } - - /** - * Set the extract flags - * - * Defines what is extracted by SplPriorityQueue::current(), - * SplPriorityQueue::top() and SplPriorityQueue::extract(). - * - * - SplPriorityQueue::EXTR_DATA (0x00000001): Extract the data - * - SplPriorityQueue::EXTR_PRIORITY (0x00000002): Extract the priority - * - SplPriorityQueue::EXTR_BOTH (0x00000003): Extract an array containing both - * - * The default mode is SplPriorityQueue::EXTR_DATA. - * - * @param int $flags - * @return void - */ - public function setExtractFlags($flags) - { - $expected = array( - self::EXTR_DATA => true, - self::EXTR_PRIORITY => true, - self::EXTR_BOTH => true, - ); - if (!isset($expected[$flags])) { - throw new InvalidArgumentException(sprintf('Expected an EXTR_* flag; received %s', $flags)); - } - $this->extractFlags = $flags; - } - - /** - * Return the value or priority (or both) of the top node, depending on - * the extract flag - * - * @return mixed - */ - public function top() - { - $this->sort(); - $keys = array_keys($this->queue); - $key = array_shift($keys); - if (preg_match('/^(a|O):/', $key)) { - $key = unserialize($key); - } - - if ($this->extractFlags == self::EXTR_PRIORITY) { - return $key; - } - - if ($this->extractFlags == self::EXTR_DATA) { - return $this->queue[$key][0]; - } - - return array( - 'data' => $this->queue[$key][0], - 'priority' => $key, - ); - } - - /** - * Iterator: is the current position valid for the queue - * - * @return bool - */ - public function valid() - { - return (bool) $this->count; - } - - /** - * Sort the queue - * - * @return void - */ - protected function sort() - { - krsort($this->queue); - } - - /** - * Prepare the queue for iteration and/or extraction - * - * @return void - */ - protected function prepareQueue() - { - $this->sort(); - $count = $this->count; - $queue = array(); - foreach ($this->queue as $priority => $values) { - $priorityKey = $priority; - if (preg_match('/^(a|O):/', $priority)) { - $priority = unserialize($priority); - } - foreach ($values as $key => $value) { - $queue[$count] = array( - 'data' => $value, - 'priority' => $priority, - 'priorityKey' => $priorityKey, - 'key' => $key, - ); - $count--; - } - } - $this->preparedQueue = $queue; - } - } -} - -/** - * Serializable version of SplPriorityQueue - * - * Also, provides predictable heap order for datums added with the same priority - * (i.e., they will be emitted in the same order they are enqueued). - * - * @category Zend - * @package Zend_Stdlib - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Stdlib_SplPriorityQueue extends SplPriorityQueue implements Serializable -{ - /** - * @var int Seed used to ensure queue order for items of the same priority - */ - protected $serial = PHP_INT_MAX; - - /** - * @var bool - */ - protected $isPhp53; - - /** - * Constructor - * - * @return void - */ - public function __construct() - { - $this->isPhp53 = version_compare(PHP_VERSION, '5.3', '>='); - } - - /** - * Insert a value with a given priority - * - * Utilizes {@var $serial} to ensure that values of equal priority are - * emitted in the same order in which they are inserted. - * - * @param mixed $datum - * @param mixed $priority - * @return void - */ - public function insert($datum, $priority) - { - // If using the native PHP SplPriorityQueue implementation, we need to - // hack around it to ensure that items registered at the same priority - // return in the order registered. In the userland version, this is not - // necessary. - if ($this->isPhp53) { - if (!is_array($priority)) { - $priority = array($priority, $this->serial--); - } - } - parent::insert($datum, $priority); - } - - /** - * Serialize to an array - * - * Array will be priority => data pairs - * - * @return array - */ - public function toArray() - { - $this->setExtractFlags(self::EXTR_BOTH); - $array = array(); - while ($this->valid()) { - $array[] = $this->current(); - $this->next(); - } - $this->setExtractFlags(self::EXTR_DATA); - - // Iterating through a priority queue removes items - foreach ($array as $item) { - $this->insert($item['data'], $item['priority']); - } - - // Return only the data - $return = array(); - foreach ($array as $item) { - $return[] = $item['data']; - } - - return $return; - } - - /** - * Serialize - * - * @return string - */ - public function serialize() - { - $data = array(); - $this->setExtractFlags(self::EXTR_BOTH); - while ($this->valid()) { - $data[] = $this->current(); - $this->next(); - } - $this->setExtractFlags(self::EXTR_DATA); - - // Iterating through a priority queue removes items - foreach ($data as $item) { - $this->insert($item['data'], $item['priority']); - } - - return serialize($data); - } - - /** - * Deserialize - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - foreach (unserialize($data) as $item) { - $this->insert($item['data'], $item['priority']); - } - } -} diff --git a/lib/Zend/Tag/Cloud.php b/lib/Zend/Tag/Cloud.php deleted file mode 100644 index c765eba59df..00000000000 --- a/lib/Zend/Tag/Cloud.php +++ /dev/null @@ -1,410 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tag_Item - */ -#require_once 'Zend/Tag/Item.php'; - -/** - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Cloud -{ - /** - * Decorator for the cloud - * - * @var Zend_Tag_Cloud_Decorator_Cloud - */ - protected $_cloudDecorator = null; - - /** - * Decorator for the tags - * - * @var Zend_Tag_Cloud_Decorator_Tag - */ - protected $_tagDecorator = null; - - /** - * List of all tags - * - * @var Zend_Tag_ItemList - */ - protected $_tags = null; - - /** - * Plugin loader for decorators - * - * @var Zend_Loader_PluginLoader - */ - protected $_pluginLoader = null; - - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'config', - ); - - /** - * Create a new tag cloud with options - * - * @param mixed $options - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $this->setConfig($options); - } - - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Set options from Zend_Config - * - * @param Zend_Config $config - * @return Zend_Tag_Cloud - */ - public function setConfig(Zend_Config $config) - { - $this->setOptions($config->toArray()); - - return $this; - } - - /** - * Set options from array - * - * @param array $options Configuration for Zend_Tag_Cloud - * @return Zend_Tag_Cloud - */ - public function setOptions(array $options) - { - if (isset($options['prefixPath'])) { - $this->addPrefixPaths($options['prefixPath']); - unset($options['prefixPath']); - } - - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . ucfirst($key); - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Set the tags for the tag cloud. - * - * $tags should be an array containing single tags as array. Each tag - * array should at least contain the keys 'title' and 'weight'. Optionally - * you may supply the key 'url', to which the tag links to. Any additional - * parameter in the array is silently ignored and can be used by custom - * decorators. - * - * @param array $tags - * @return Zend_Tag_Cloud - */ - public function setTags(array $tags) - { - // Validate and cleanup the tags - $itemList = $this->getItemList(); - - foreach ($tags as $tag) { - if ($tag instanceof Zend_Tag_Taggable) { - $itemList[] = $tag; - } else if (is_array($tag)) { - $itemList[] = new Zend_Tag_Item($tag); - } else { - #require_once 'Zend/Tag/Cloud/Exception.php'; - throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array'); - } - } - - return $this; - } - - /** - * Append a single tag to the cloud - * - * @param Zend_Tag_Taggable|array $tag - * @return Zend_Tag_Cloud - */ - public function appendTag($tag) - { - $tags = $this->getItemList(); - if ($tag instanceof Zend_Tag_Taggable) { - $tags[] = $tag; - } else if (is_array($tag)) { - $tags[] = new Zend_Tag_Item($tag); - } else { - #require_once 'Zend/Tag/Cloud/Exception.php'; - throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array'); - } - - return $this; - } - - /** - * Set the item list - * - * @param Zend_Tag_ItemList $itemList - * @return Zend_Tag_Cloud - */ - public function setItemList(Zend_Tag_ItemList $itemList) - { - $this->_tags = $itemList; - return $this; - } - - /** - * Retrieve the item list - * - * If item list is undefined, creates one. - * - * @return Zend_Tag_ItemList - */ - public function getItemList() - { - if (null === $this->_tags) { - #require_once 'Zend/Tag/ItemList.php'; - $this->setItemList(new Zend_Tag_ItemList()); - } - return $this->_tags; - } - - /** - * Set the decorator for the cloud - * - * @param mixed $decorator - * @return Zend_Tag_Cloud - */ - public function setCloudDecorator($decorator) - { - $options = null; - - if (is_array($decorator)) { - if (isset($decorator['options'])) { - $options = $decorator['options']; - } - - if (isset($decorator['decorator'])) { - $decorator = $decorator['decorator']; - } - } - - if (is_string($decorator)) { - $classname = $this->getPluginLoader()->load($decorator); - $decorator = new $classname($options); - } - - if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Cloud)) { - #require_once 'Zend/Tag/Cloud/Exception.php'; - throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Cloud'); - } - - $this->_cloudDecorator = $decorator; - - return $this; - } - - /** - * Get the decorator for the cloud - * - * @return Zend_Tag_Cloud_Decorator_Cloud - */ - public function getCloudDecorator() - { - if (null === $this->_cloudDecorator) { - $this->setCloudDecorator('htmlCloud'); - } - return $this->_cloudDecorator; - } - - /** - * Set the decorator for the tags - * - * @param mixed $decorator - * @return Zend_Tag_Cloud - */ - public function setTagDecorator($decorator) - { - $options = null; - - if (is_array($decorator)) { - if (isset($decorator['options'])) { - $options = $decorator['options']; - } - - if (isset($decorator['decorator'])) { - $decorator = $decorator['decorator']; - } - } - - if (is_string($decorator)) { - $classname = $this->getPluginLoader()->load($decorator); - $decorator = new $classname($options); - } - - if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Tag)) { - #require_once 'Zend/Tag/Cloud/Exception.php'; - throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Tag'); - } - - $this->_tagDecorator = $decorator; - - return $this; - } - - /** - * Get the decorator for the tags - * - * @return Zend_Tag_Cloud_Decorator_Tag - */ - public function getTagDecorator() - { - if (null === $this->_tagDecorator) { - $this->setTagDecorator('htmlTag'); - } - return $this->_tagDecorator; - } - - /** - * Set plugin loaders for use with decorators - * - * @param Zend_Loader_PluginLoader_Interface $loader - * @return Zend_Tag_Cloud - */ - public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader) - { - $this->_pluginLoader = $loader; - return $this; - } - - /** - * Get the plugin loader for decorators - * - * @return Zend_Loader_PluginLoader - */ - public function getPluginLoader() - { - if ($this->_pluginLoader === null) { - $prefix = 'Zend_Tag_Cloud_Decorator_'; - $pathPrefix = 'Zend/Tag/Cloud/Decorator/'; - - #require_once 'Zend/Loader/PluginLoader.php'; - $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix)); - } - - return $this->_pluginLoader; - } - - /** - * Add many prefix paths at once - * - * @param array $paths - * @return Zend_Tag_Cloud - */ - public function addPrefixPaths(array $paths) - { - if (isset($paths['prefix']) && isset($paths['path'])) { - return $this->addPrefixPath($paths['prefix'], $paths['path']); - } - - foreach ($paths as $path) { - if (!isset($path['prefix']) || !isset($path['path'])) { - continue; - } - - $this->addPrefixPath($path['prefix'], $path['path']); - } - - return $this; - } - - /** - * Add prefix path for plugin loader - * - * @param string $prefix - * @param string $path - * @return Zend_Tag_Cloud - */ - public function addPrefixPath($prefix, $path) - { - $loader = $this->getPluginLoader(); - $loader->addPrefixPath($prefix, $path); - - return $this; - } - - /** - * Render the tag cloud - * - * @return string - */ - public function render() - { - $tags = $this->getItemList(); - - if (count($tags) === 0) { - return ''; - } - - $tagsResult = $this->getTagDecorator()->render($tags); - $cloudResult = $this->getCloudDecorator()->render($tagsResult); - - return $cloudResult; - } - - /** - * Render the tag cloud - * - * @return string - */ - public function __toString() - { - try { - $result = $this->render(); - return $result; - } catch (Exception $e) { - $message = "Exception caught by tag cloud: " . $e->getMessage() - . "\nStack Trace:\n" . $e->getTraceAsString(); - trigger_error($message, E_USER_WARNING); - return ''; - } - } -} diff --git a/lib/Zend/Tag/Cloud/Decorator/Cloud.php b/lib/Zend/Tag/Cloud/Decorator/Cloud.php deleted file mode 100644 index e649d54f2bf..00000000000 --- a/lib/Zend/Tag/Cloud/Decorator/Cloud.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Abstract class for cloud decorators - * - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tag_Cloud_Decorator_Cloud -{ - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'config', - ); - - /** - * Create a new cloud decorator with options - * - * @param mixed $options - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for the decorator - * @return Zend_Tag_Cloud - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Render a list of formatted tags - * - * @param array $tags - * @return string - */ - abstract public function render(array $tags); -} diff --git a/lib/Zend/Tag/Cloud/Decorator/Exception.php b/lib/Zend/Tag/Cloud/Decorator/Exception.php deleted file mode 100644 index 216dcde9de7..00000000000 --- a/lib/Zend/Tag/Cloud/Decorator/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Tag_Cloud_Exception - */ -#require_once 'Zend/Tag/Cloud/Exception.php'; - -/** - * Exception class for Zend_Tag_Cloud_Decorator - * - * @category Zend - * @package Zend_Tag - * @uses Zend_Tag_Cloud_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Cloud_Decorator_Exception extends Zend_Tag_Cloud_Exception -{ -} diff --git a/lib/Zend/Tag/Cloud/Decorator/HtmlCloud.php b/lib/Zend/Tag/Cloud/Decorator/HtmlCloud.php deleted file mode 100644 index 6d71bd3de30..00000000000 --- a/lib/Zend/Tag/Cloud/Decorator/HtmlCloud.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tag_Cloud_Decorator_Cloud - */ -#require_once 'Zend/Tag/Cloud/Decorator/Cloud.php'; - -/** - * Simple HTML decorator for clouds - * - * @category Zend - * @package Zend_Tag - * @uses Zend_Tag_Cloud_Decorator_Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Cloud_Decorator_HtmlCloud extends Zend_Tag_Cloud_Decorator_Cloud -{ - /** - * @var string Encoding to use - */ - protected $_encoding = 'UTF-8'; - - /** - * List of HTML tags - * - * @var array - */ - protected $_htmlTags = array( - 'ul' => array('class' => 'Zend_Tag_Cloud') - ); - - /** - * Separator for the single tags - * - * @var string - */ - protected $_separator = ' '; - - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Set encoding - * - * @param string - * @return Zend_Tag_Cloud_Decorator_HtmlCloud - */ - public function setEncoding($value) - { - $this->_encoding = (string) $value; - return $this; - } - - /** - * Set the HTML tags surrounding all tags - * - * @param array $htmlTags - * @return Zend_Tag_Cloud_Decorator_HtmlCloud - */ - public function setHtmlTags(array $htmlTags) - { - $this->_htmlTags = $htmlTags; - return $this; - } - - /** - * Retrieve HTML tag map - * - * @return array - */ - public function getHtmlTags() - { - return $this->_htmlTags; - } - - /** - * Set the separator between the single tags - * - * @param string - * @return Zend_Tag_Cloud_Decorator_HtmlCloud - */ - public function setSeparator($separator) - { - $this->_separator = $separator; - return $this; - } - - /** - * Get tag separator - * - * @return string - */ - public function getSeparator() - { - return $this->_separator; - } - - /** - * Defined by Zend_Tag_Cloud_Decorator_Cloud - * - * @param array $tags - * @return string - */ - public function render(array $tags) - { - $cloudHtml = implode($this->getSeparator(), $tags); - - $enc = $this->getEncoding(); - foreach ($this->getHtmlTags() as $key => $data) { - if (is_array($data)) { - $htmlTag = $key; - $attributes = ''; - - foreach ($data as $param => $value) { - $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"'; - } - } else { - $htmlTag = $data; - $attributes = ''; - } - - $cloudHtml = sprintf('<%1$s%3$s>%2$s</%1$s>', $htmlTag, $cloudHtml, $attributes); - } - - return $cloudHtml; - } -} diff --git a/lib/Zend/Tag/Cloud/Decorator/HtmlTag.php b/lib/Zend/Tag/Cloud/Decorator/HtmlTag.php deleted file mode 100644 index c36a9a558ad..00000000000 --- a/lib/Zend/Tag/Cloud/Decorator/HtmlTag.php +++ /dev/null @@ -1,306 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tag_Cloud_Decorator_Tag - */ -#require_once 'Zend/Tag/Cloud/Decorator/Tag.php'; - -/** - * Simple HTML decorator for tags - * - * @category Zend - * @package Zend_Tag - * @uses Zend_Tag_Cloud_Decorator_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag -{ - /** - * List of tags which get assigned to the inner element instead of - * font-sizes. - * - * @var array - */ - protected $_classList = null; - - /** - * @var string Encoding to utilize - */ - protected $_encoding = 'UTF-8'; - - /** - * Unit for the fontsize - * - * @var string - */ - protected $_fontSizeUnit = 'px'; - - /** - * Allowed fontsize units - * - * @var array - */ - protected $_alloweFontSizeUnits = array('em', 'ex', 'px', 'in', 'cm', 'mm', 'pt', 'pc', '%'); - - /** - * List of HTML tags - * - * @var array - */ - protected $_htmlTags = array( - 'li' - ); - - /** - * Maximum fontsize - * - * @var integer - */ - protected $_maxFontSize = 20; - - /** - * Minimum fontsize - * - * @var integer - */ - protected $_minFontSize = 10; - - /** - * Set a list of classes to use instead of fontsizes - * - * @param array $classList - * @throws Zend_Tag_Cloud_Decorator_Exception When the classlist is empty - * @throws Zend_Tag_Cloud_Decorator_Exception When the classlist contains an invalid classname - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setClassList(array $classList = null) - { - if (is_array($classList)) { - if (count($classList) === 0) { - #require_once 'Zend/Tag/Cloud/Decorator/Exception.php'; - throw new Zend_Tag_Cloud_Decorator_Exception('Classlist is empty'); - } - - foreach ($classList as $class) { - if (!is_string($class)) { - #require_once 'Zend/Tag/Cloud/Decorator/Exception.php'; - throw new Zend_Tag_Cloud_Decorator_Exception('Classlist contains an invalid classname'); - } - } - } - - $this->_classList = $classList; - return $this; - } - - /** - * Get class list - * - * @return array - */ - public function getClassList() - { - return $this->_classList; - } - - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Set encoding - * - * @param string $value - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setEncoding($value) - { - $this->_encoding = (string) $value; - return $this; - } - - /** - * Set the font size unit - * - * Possible values are: em, ex, px, in, cm, mm, pt, pc and % - * - * @param string $fontSizeUnit - * @throws Zend_Tag_Cloud_Decorator_Exception When an invalid fontsize unit is specified - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setFontSizeUnit($fontSizeUnit) - { - if (!in_array($fontSizeUnit, $this->_alloweFontSizeUnits)) { - #require_once 'Zend/Tag/Cloud/Decorator/Exception.php'; - throw new Zend_Tag_Cloud_Decorator_Exception('Invalid fontsize unit specified'); - } - - $this->_fontSizeUnit = (string) $fontSizeUnit; - $this->setClassList(null); - return $this; - } - - /** - * Retrieve font size unit - * - * @return string - */ - public function getFontSizeUnit() - { - return $this->_fontSizeUnit; - } - /** - * Set the HTML tags surrounding the <a> element - * - * @param array $htmlTags - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setHtmlTags(array $htmlTags) - { - $this->_htmlTags = $htmlTags; - return $this; - } - - /** - * Get HTML tags map - * - * @return array - */ - public function getHtmlTags() - { - return $this->_htmlTags; - } - - /** - * Set maximum font size - * - * @param integer $maxFontSize - * @throws Zend_Tag_Cloud_Decorator_Exception When fontsize is not numeric - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setMaxFontSize($maxFontSize) - { - if (!is_numeric($maxFontSize)) { - #require_once 'Zend/Tag/Cloud/Decorator/Exception.php'; - throw new Zend_Tag_Cloud_Decorator_Exception('Fontsize must be numeric'); - } - - $this->_maxFontSize = (int) $maxFontSize; - $this->setClassList(null); - return $this; - } - - /** - * Retrieve maximum font size - * - * @return int - */ - public function getMaxFontSize() - { - return $this->_maxFontSize; - } - - /** - * Set minimum font size - * - * @param int $minFontSize - * @throws Zend_Tag_Cloud_Decorator_Exception When fontsize is not numeric - * @return Zend_Tag_Cloud_Decorator_HtmlTag - */ - public function setMinFontSize($minFontSize) - { - if (!is_numeric($minFontSize)) { - #require_once 'Zend/Tag/Cloud/Decorator/Exception.php'; - throw new Zend_Tag_Cloud_Decorator_Exception('Fontsize must be numeric'); - } - - $this->_minFontSize = (int) $minFontSize; - $this->setClassList(null); - return $this; - } - - /** - * Retrieve minimum font size - * - * @return int - */ - public function getMinFontSize() - { - return $this->_minFontSize; - } - - /** - * Defined by Zend_Tag_Cloud_Decorator_Tag - * - * @param Zend_Tag_ItemList $tags - * @return array - */ - public function render(Zend_Tag_ItemList $tags) - { - if (null === ($weightValues = $this->getClassList())) { - $weightValues = range($this->getMinFontSize(), $this->getMaxFontSize()); - } - - $tags->spreadWeightValues($weightValues); - - $result = array(); - - $enc = $this->getEncoding(); - foreach ($tags as $tag) { - if (null === ($classList = $this->getClassList())) { - $attribute = sprintf('style="font-size: %d%s;"', $tag->getParam('weightValue'), $this->getFontSizeUnit()); - } else { - $attribute = sprintf('class="%s"', htmlspecialchars($tag->getParam('weightValue'), ENT_COMPAT, $enc)); - } - - $tagHtml = sprintf('<a href="%s" %s>%s</a>', htmlSpecialChars($tag->getParam('url'), ENT_COMPAT, $enc), $attribute, $tag->getTitle()); - - foreach ($this->getHtmlTags() as $key => $data) { - if (is_array($data)) { - $htmlTag = $key; - $attributes = ''; - - foreach ($data as $param => $value) { - $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"'; - } - } else { - $htmlTag = $data; - $attributes = ''; - } - - $tagHtml = sprintf('<%1$s%3$s>%2$s</%1$s>', $htmlTag, $tagHtml, $attributes); - } - - $result[] = $tagHtml; - } - - return $result; - } -} diff --git a/lib/Zend/Tag/Cloud/Decorator/Tag.php b/lib/Zend/Tag/Cloud/Decorator/Tag.php deleted file mode 100644 index b2369569134..00000000000 --- a/lib/Zend/Tag/Cloud/Decorator/Tag.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Cloud - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Abstract class for tag decorators - * - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tag_Cloud_Decorator_Tag -{ - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'config', - ); - - /** - * Create a new cloud decorator with options - * - * @param mixed $options - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for the decorator - * @return Zend_Tag_Cloud - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Render a list of tags - * - * @param Zend_Tag_ItemList $tags - * @return array - */ - abstract public function render(Zend_Tag_ItemList $tags); -} diff --git a/lib/Zend/Tag/Cloud/Exception.php b/lib/Zend/Tag/Cloud/Exception.php deleted file mode 100644 index e7f4b694f76..00000000000 --- a/lib/Zend/Tag/Cloud/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Tag_Exception - */ -#require_once 'Zend/Tag/Exception.php'; - -/** - * Exception class for Zend_Tag_Cloud - * - * @category Zend - * @package Zend_Tag - * @uses Zend_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Cloud_Exception extends Zend_Tag_Exception -{ -} diff --git a/lib/Zend/Tag/Exception.php b/lib/Zend/Tag/Exception.php deleted file mode 100644 index 2700b55de30..00000000000 --- a/lib/Zend/Tag/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Exception - */ -#require_once 'Zend/Exception.php'; - -/** - * Exception class for Zend_Tag - * - * @category Zend - * @package Zend_Tag - * @uses Zend_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Exception extends Zend_Exception -{ -} diff --git a/lib/Zend/Tag/Item.php b/lib/Zend/Tag/Item.php deleted file mode 100644 index b65f78b1e79..00000000000 --- a/lib/Zend/Tag/Item.php +++ /dev/null @@ -1,220 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Item - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tag_Taggable - */ -#require_once 'Zend/Tag/Taggable.php'; - -/** - * @category Zend - * @package Zend_Tag - * @uses Zend_Tag_Taggable - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_Item implements Zend_Tag_Taggable -{ - /** - * Title of the tag - * - * @var string - */ - protected $_title = null; - - /** - * Weight of the tag - * - * @var float - */ - protected $_weight = null; - - /** - * Custom parameters - * - * @var string - */ - protected $_params = array(); - - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'param' - ); - - /** - * Create a new tag according to the options - * - * @param array|Zend_Config $options - * @throws Zend_Tag_Exception When invalid options are provided - * @throws Zend_Tag_Exception When title was not set - * @throws Zend_Tag_Exception When weight was not set - * @return void - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - if (!is_array($options)) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Invalid options provided to constructor'); - } - - $this->setOptions($options); - - if ($this->_title === null) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Title was not set'); - } - - if ($this->_weight === null) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Weight was not set'); - } - } - - /** - * Set options of the tag - * - * @param array $options - * @return Zend_Tag_Item - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Defined by Zend_Tag_Taggable - * - * @return string - */ - public function getTitle() - { - return $this->_title; - } - - /** - * Set the title - * - * @param string $title - * @throws Zend_Tag_Exception When title is no string - * @return Zend_Tag_Item - */ - public function setTitle($title) - { - if (!is_string($title)) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Title must be a string'); - } - - $this->_title = (string) $title; - return $this; - } - - /** - * Defined by Zend_Tag_Taggable - * - * @return float - */ - public function getWeight() - { - return $this->_weight; - } - - /** - * Set the weight - * - * @param float $weight - * @throws Zend_Tag_Exception When weight is not numeric - * @return Zend_Tag_Item - */ - public function setWeight($weight) - { - if (!is_numeric($weight)) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Weight must be numeric'); - } - - $this->_weight = (float) $weight; - return $this; - } - - /** - * Set multiple params at once - * - * @param array $params - * @return Zend_Tag_Item - */ - public function setParams(array $params) - { - foreach ($params as $name => $value) { - $this->setParam($name, $value); - } - - return $this; - } - - /** - * Defined by Zend_Tag_Taggable - * - * @param string $name - * @param mixed $value - * @return Zend_Tag_Item - */ - public function setParam($name, $value) - { - $this->_params[$name] = $value; - return $this; - } - - /** - * Defined by Zend_Tag_Taggable - * - * @param string $name - * @return mixed - */ - public function getParam($name) - { - if (isset($this->_params[$name])) { - return $this->_params[$name]; - } - return null; - } -} diff --git a/lib/Zend/Tag/ItemList.php b/lib/Zend/Tag/ItemList.php deleted file mode 100644 index 9887c715270..00000000000 --- a/lib/Zend/Tag/ItemList.php +++ /dev/null @@ -1,238 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage ItemList - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tag_Taggable - */ -#require_once 'Zend/Tag/Taggable.php'; - -/** - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tag_ItemList implements Countable, SeekableIterator, ArrayAccess -{ - /** - * Items in this list - * - * @var array - */ - protected $_items = array(); - - /** - * Count all items - * - * @return integer - */ - public function count() - { - return count($this->_items); - } - - /** - * Spread values in the items relative to their weight - * - * @param array $values - * @throws Zend_Tag_Exception When value list is empty - * @return void - */ - public function spreadWeightValues(array $values) - { - // Don't allow an empty value list - if (count($values) === 0) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Value list may not be empty'); - } - - // Re-index the array - $values = array_values($values); - - // If just a single value is supplied simply assign it to to all tags - if (count($values) === 1) { - foreach ($this->_items as $item) { - $item->setParam('weightValue', $values[0]); - } - } else { - // Calculate min- and max-weight - $minWeight = null; - $maxWeight = null; - - foreach ($this->_items as $item) { - if ($minWeight === null && $maxWeight === null) { - $minWeight = $item->getWeight(); - $maxWeight = $item->getWeight(); - } else { - $minWeight = min($minWeight, $item->getWeight()); - $maxWeight = max($maxWeight, $item->getWeight()); - } - } - - // Calculate the thresholds - $steps = count($values); - $delta = ($maxWeight - $minWeight) / ($steps - 1); - $thresholds = array(); - - for ($i = 0; $i < $steps; $i++) { - $thresholds[$i] = floor(100 * log(($minWeight + $i * $delta) + 2)); - } - - // Then assign the weight values - foreach ($this->_items as $item) { - $threshold = floor(100 * log($item->getWeight() + 2)); - - for ($i = 0; $i < $steps; $i++) { - if ($threshold <= $thresholds[$i]) { - $item->setParam('weightValue', $values[$i]); - break; - } - } - } - } - } - - /** - * Seek to an absolute positio - * - * @param integer $index - * @throws OutOfBoundsException When the seek position is invalid - * @return void - */ - public function seek($index) - { - $this->rewind(); - $position = 0; - - while ($position < $index && $this->valid()) { - $this->next(); - $position++; - } - - if (!$this->valid()) { - throw new OutOfBoundsException('Invalid seek position'); - } - } - - /** - * Return the current element - * - * @return mixed - */ - public function current() - { - return current($this->_items); - } - - /** - * Move forward to next element - * - * @return mixed - */ - public function next() - { - return next($this->_items); - } - - /** - * Return the key of the current element - * - * @return mixed - */ - public function key() - { - return key($this->_items); - } - - /** - * Check if there is a current element after calls to rewind() or next() - * - * @return boolean - */ - public function valid() - { - return ($this->current() !== false); - } - - /** - * Rewind the Iterator to the first element - * - * @return void - */ - public function rewind() - { - reset($this->_items); - } - - /** - * Check if an offset exists - * - * @param mixed $offset - * @return boolean - */ - public function offsetExists($offset) { - return array_key_exists($offset, $this->_items); - } - - /** - * Get the value of an offset - * - * @param mixed $offset - * @return Zend_Tag_Taggable - */ - public function offsetGet($offset) { - return $this->_items[$offset]; - } - - /** - * Append a new item - * - * @param mixed $offset - * @param Zend_Tag_Taggable $item - * @throws OutOfBoundsException When item does not implement Zend_Tag_Taggable - * @return void - */ - public function offsetSet($offset, $item) { - // We need to make that check here, as the method signature must be - // compatible with ArrayAccess::offsetSet() - if (!($item instanceof Zend_Tag_Taggable)) { - #require_once 'Zend/Tag/Exception.php'; - throw new Zend_Tag_Exception('Item must implement Zend_Tag_Taggable'); - } - - if ($offset === null) { - $this->_items[] = $item; - } else { - $this->_items[$offset] = $item; - } - } - - /** - * Unset an item - * - * @param mixed $offset - * @return void - */ - public function offsetUnset($offset) { - unset($this->_items[$offset]); - } -} diff --git a/lib/Zend/Tag/Taggable.php b/lib/Zend/Tag/Taggable.php deleted file mode 100644 index 767b8e5b0cf..00000000000 --- a/lib/Zend/Tag/Taggable.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tag - * @subpackage Item - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tag - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tag_Taggable -{ - /** - * Get the title of the tag - * - * @return string - */ - public function getTitle(); - - /** - * Get the weight of the tag - * - * @return float - */ - public function getWeight(); - - /** - * Set a parameter - * - * @param string $name - * @param string $value - */ - public function setParam($name, $value); - - /** - * Get a parameter - * - * @param string $name - * @return mixed - */ - public function getParam($name); -} diff --git a/lib/Zend/Test/DbAdapter.php b/lib/Zend/Test/DbAdapter.php deleted file mode 100644 index 29d1d4c66d5..00000000000 --- a/lib/Zend/Test/DbAdapter.php +++ /dev/null @@ -1,345 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Db_Adapter_Abstract - */ -#require_once "Zend/Db/Adapter/Abstract.php"; - -/** - * @see Zend_Test_DbStatement - */ -#require_once "Zend/Test/DbStatement.php"; - -/** - * @see Zend_Db_Profiler - */ -#require_once 'Zend/Db/Profiler.php'; - -/** - * Testing Database Adapter which acts as a stack for SQL Results - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_DbAdapter extends Zend_Db_Adapter_Abstract -{ - /** - * @var array - */ - protected $_statementStack = array(); - - /** - * @var boolean - */ - protected $_connected = false; - - /** - * @var array - */ - protected $_listTables = array(); - - /** - * @var array - */ - protected $_lastInsertIdStack = array(); - - /** - * @var array - */ - protected $_describeTables = array(); - - /** - * @var string - */ - protected $_quoteIdentifierSymbol = ''; - - /** - * Empty constructor to make it parameterless. - */ - public function __construct() - { - $profiler = new Zend_Db_Profiler(); - $profiler->setEnabled(true); - $this->setProfiler($profiler); - } - - /** - * Append a new Statement to the SQL Result Stack. - * - * @param Zend_Test_DbStatement $stmt - * @return Zend_Test_DbAdapter - */ - public function appendStatementToStack(Zend_Test_DbStatement $stmt) - { - array_push($this->_statementStack, $stmt); - return $this; - } - - /** - * Append a new Insert Id to the {@see lastInsertId}. - * - * @param int|string $id - * @return Zend_Test_DbAdapter - */ - public function appendLastInsertIdToStack($id) - { - array_push($this->_lastInsertIdStack, $id); - return $this; - } - - /** - * @var string - */ - public function setQuoteIdentifierSymbol($symbol) - { - $this->_quoteIdentifierSymbol = $symbol; - } - - /** - * Returns the symbol the adapter uses for delimited identifiers. - * - * @return string - */ - public function getQuoteIdentifierSymbol() - { - return $this->_quoteIdentifierSymbol; - } - - /** - * Set the result from {@see listTables()}. - * - * @param array $listTables - */ - public function setListTables(array $listTables) - { - $this->_listTables = $listTables; - } - - /** - * Returns a list of the tables in the database. - * - * @return array - */ - public function listTables() - { - return $this->_listTables; - } - - /** - * - * @param string $table - * @param array $tableInfo - * @return Zend_Test_DbAdapter - */ - public function setDescribeTable($table, $tableInfo) - { - $this->_describeTables[$table] = $tableInfo; - return $this; - } - - /** - * Returns the column descriptions for a table. - * - * The return value is an associative array keyed by the column name, - * as returned by the RDBMS. - * - * The value of each array element is an associative array - * with the following keys: - * - * SCHEMA_NAME => string; name of database or schema - * TABLE_NAME => string; - * COLUMN_NAME => string; column name - * COLUMN_POSITION => number; ordinal position of column in table - * DATA_TYPE => string; SQL datatype name of column - * DEFAULT => string; default expression of column, null if none - * NULLABLE => boolean; true if column can have nulls - * LENGTH => number; length of CHAR/VARCHAR - * SCALE => number; scale of NUMERIC/DECIMAL - * PRECISION => number; precision of NUMERIC/DECIMAL - * UNSIGNED => boolean; unsigned property of an integer type - * PRIMARY => boolean; true if column is part of the primary key - * PRIMARY_POSITION => integer; position of column in primary key - * - * @param string $tableName - * @param string $schemaName OPTIONAL - * @return array - */ - public function describeTable($tableName, $schemaName = null) - { - if(isset($this->_describeTables[$tableName])) { - return $this->_describeTables[$tableName]; - } else { - return array(); - } - } - - /** - * Creates a connection to the database. - * - * @return void - */ - protected function _connect() - { - $this->_connected = true; - } - - /** - * Test if a connection is active - * - * @return boolean - */ - public function isConnected() - { - return $this->_connected; - } - - /** - * Force the connection to close. - * - * @return void - */ - public function closeConnection() - { - $this->_connected = false; - } - - /** - * Prepare a statement and return a PDOStatement-like object. - * - * @param string|Zend_Db_Select $sql SQL query - * @return Zend_Db_Statment|PDOStatement - */ - public function prepare($sql) - { - $queryId = $this->getProfiler()->queryStart($sql); - - if(count($this->_statementStack)) { - $stmt = array_pop($this->_statementStack); - } else { - $stmt = new Zend_Test_DbStatement(); - } - - if($this->getProfiler()->getEnabled() == true) { - $qp = $this->getProfiler()->getQueryProfile($queryId); - $stmt->setQueryProfile($qp); - } - - return $stmt; - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * @param string $tableName OPTIONAL Name of table. - * @param string $primaryKey OPTIONAL Name of primary key column. - * @return string - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - if(count($this->_lastInsertIdStack)) { - return array_pop($this->_lastInsertIdStack); - } else { - return false; - } - } - - /** - * Begin a transaction. - */ - protected function _beginTransaction() - { - return; - } - - /** - * Commit a transaction. - */ - protected function _commit() - { - return; - } - - /** - * Roll-back a transaction. - */ - protected function _rollBack() - { - - } - - /** - * Set the fetch mode. - * - * @param integer $mode - * @return void - * @throws Zend_Db_Adapter_Exception - */ - public function setFetchMode($mode) - { - return; - } - - /** - * Adds an adapter-specific LIMIT clause to the SELECT statement. - * - * @param mixed $sql - * @param integer $count - * @param integer $offset - * @return string - */ - public function limit($sql, $count, $offset = 0) - { - return sprintf('%s LIMIT %d,%d', $sql, $offset, $count); - } - - /** - * Check if the adapter supports real SQL parameters. - * - * @param string $type 'positional' or 'named' - * @return bool - */ - public function supportsParameters($type) - { - return true; - } - - /** - * Retrieve server version in PHP style - * - * @return string - */ - function getServerVersion() - { - return "1.0.0"; - } -} diff --git a/lib/Zend/Test/DbStatement.php b/lib/Zend/Test/DbStatement.php deleted file mode 100644 index 739c51e74e2..00000000000 --- a/lib/Zend/Test/DbStatement.php +++ /dev/null @@ -1,404 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Db_Statement_Interface - */ -#require_once "Zend/Db/Statement/Interface.php"; - -/** - * Testing Database Statement that acts as a stack to SQL resultsets. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_DbStatement implements Zend_Db_Statement_Interface -{ - /** - * @var array - */ - protected $_fetchStack = array(); - - /** - * @var int - */ - protected $_columnCount = 0; - - /** - * @var int - */ - protected $_rowCount = 0; - - /** - * @var Zend_Db_Profiler_Query - */ - protected $_queryProfile = null; - - /** - * Create a Select statement which returns the given array of rows. - * - * @param array $rows - * @return Zend_Test_DbStatement - */ - static public function createSelectStatement(array $rows=array()) - { - $stmt = new Zend_Test_DbStatement(); - foreach($rows AS $row) { - $stmt->append($row); - } - return $stmt; - } - - /** - * Create an Insert Statement - * - * @param int $affectedRows - * @return Zend_Test_DbStatement - */ - static public function createInsertStatement($affectedRows=0) - { - return self::_createRowCountStatement($affectedRows); - } - - /** - * Create an Delete Statement - * - * @param int $affectedRows - * @return Zend_Test_DbStatement - */ - static public function createDeleteStatement($affectedRows=0) - { - return self::_createRowCountStatement($affectedRows); - } - - /** - * Create an Update Statement - * - * @param int $affectedRows - * @return Zend_Test_DbStatement - */ - static public function createUpdateStatement($affectedRows=0) - { - return self::_createRowCountStatement($affectedRows); - } - - /** - * Create a Row Count Statement - * - * @param int $affectedRows - * @return Zend_Test_DbStatement - */ - static protected function _createRowCountStatement($affectedRows) - { - $stmt = new Zend_Test_DbStatement(); - $stmt->setRowCount($affectedRows); - return $stmt; - } - - /** - * @param Zend_Db_Profiler_Query $qp - */ - public function setQueryProfile(Zend_Db_Profiler_Query $qp) - { - $this->_queryProfile = $qp; - } - - /** - * @param int $rowCount - */ - public function setRowCount($rowCount) - { - $this->_rowCount = $rowCount; - } - - /** - * Append a new row to the fetch stack. - * - * @param array $row - */ - public function append($row) - { - $this->_columnCount = count($row); - $this->_fetchStack[] = $row; - } - - /** - * Bind a column of the statement result set to a PHP variable. - * - * @param string $column Name the column in the result set, either by - * position or by name. - * @param mixed $param Reference to the PHP variable containing the value. - * @param mixed $type OPTIONAL - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function bindColumn($column, &$param, $type = null) - { - return true; - } - - /** - * Binds a parameter to the specified variable name. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $variable Reference to PHP variable containing the value. - * @param mixed $type OPTIONAL Datatype of SQL parameter. - * @param mixed $length OPTIONAL Length of SQL parameter. - * @param mixed $options OPTIONAL Other options. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function bindParam($parameter, &$variable, $type = null, $length = null, $options = null) - { - if($this->_queryProfile !== null) { - $this->_queryProfile->bindParam($parameter, $variable); - } - return true; - } - - /** - * Binds a value to a parameter. - * - * @param mixed $parameter Name the parameter, either integer or string. - * @param mixed $value Scalar value to bind to the parameter. - * @param mixed $type OPTIONAL Datatype of the parameter. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function bindValue($parameter, $value, $type = null) - { - return true; - } - - /** - * Closes the cursor, allowing the statement to be executed again. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function closeCursor() - { - return true; - } - - /** - * Returns the number of columns in the result set. - * Returns null if the statement has no result set metadata. - * - * @return int The number of columns. - * @throws Zend_Db_Statement_Exception - */ - public function columnCount() - { - return $this->_columnCount; - } - - /** - * Retrieves the error code, if any, associated with the last operation on - * the statement handle. - * - * @return string error code. - * @throws Zend_Db_Statement_Exception - */ - public function errorCode() - { - return false; - } - - /** - * Retrieves an array of error information, if any, associated with the - * last operation on the statement handle. - * - * @return array - * @throws Zend_Db_Statement_Exception - */ - public function errorInfo() - { - return false; - } - - /** - * Executes a prepared statement. - * - * @param array $params OPTIONAL Values to bind to parameter placeholders. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function execute(array $params = array()) - { - if($this->_queryProfile !== null) { - $this->_queryProfile->bindParams($params); - $this->_queryProfile->end(); - } - return true; - } - - /** - * Fetches a row from the result set. - * - * @param int $style OPTIONAL Fetch mode for this fetch operation. - * @param int $cursor OPTIONAL Absolute, relative, or other. - * @param int $offset OPTIONAL Number for absolute or relative cursors. - * @return mixed Array, object, or scalar depending on fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetch($style = null, $cursor = null, $offset = null) - { - if(count($this->_fetchStack)) { - $row = array_shift($this->_fetchStack); - return $row; - } else { - return false; - } - } - - /** - * Returns an array containing all of the result set rows. - * - * @param int $style OPTIONAL Fetch mode. - * @param int $col OPTIONAL Column number, if fetch mode is by column. - * @return array Collection of rows, each in a format by the fetch mode. - * @throws Zend_Db_Statement_Exception - */ - public function fetchAll($style = null, $col = null) - { - $rows = $this->_fetchStack; - $this->_fetchStack = array(); - - return $rows; - } - - /** - * Returns a single column from the next row of a result set. - * - * @param int $col OPTIONAL Position of the column to fetch. - * @return string - * @throws Zend_Db_Statement_Exception - */ - public function fetchColumn($col = 0) - { - $row = $this->fetch(); - - if($row == false) { - return false; - } else { - if(count($row) < $col) { - #require_once "Zend/Db/Statement/Exception.php"; - throw new Zend_Db_Statement_Exception( - "Column Position '".$col."' is out of bounds." - ); - } - - $keys = array_keys($row); - return $row[$keys[$col]]; - } - } - - /** - * Fetches the next row and returns it as an object. - * - * @param string $class OPTIONAL Name of the class to create. - * @param array $config OPTIONAL Constructor arguments for the class. - * @return mixed One object instance of the specified class. - * @throws Zend_Db_Statement_Exception - */ - public function fetchObject($class = 'stdClass', array $config = array()) - { - if(!class_exists($class)) { - throw new Zend_Db_Statement_Exception("Class '".$class."' does not exist!"); - } - - $object = new $class(); - $row = $this->fetch(); - foreach($row AS $k => $v) { - $object->$k = $v; - } - - return $object; - } - - /** - * Retrieve a statement attribute. - * - * @param string $key Attribute name. - * @return mixed Attribute value. - * @throws Zend_Db_Statement_Exception - */ - public function getAttribute($key) - { - return false; - } - - /** - * Retrieves the next rowset (result set) for a SQL statement that has - * multiple result sets. An example is a stored procedure that returns - * the results of multiple queries. - * - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function nextRowset() - { - return false; - } - - /** - * Returns the number of rows affected by the execution of the - * last INSERT, DELETE, or UPDATE statement executed by this - * statement object. - * - * @return int The number of rows affected. - * @throws Zend_Db_Statement_Exception - */ - public function rowCount() - { - return $this->_rowCount; - } - - /** - * Set a statement attribute. - * - * @param string $key Attribute name. - * @param mixed $val Attribute value. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function setAttribute($key, $val) - { - return true; - } - - /** - * Set the default fetch mode for this statement. - * - * @param int $mode The fetch mode. - * @return bool - * @throws Zend_Db_Statement_Exception - */ - public function setFetchMode($mode) - { - return true; - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/DomQuery.php b/lib/Zend/Test/PHPUnit/Constraint/DomQuery.php deleted file mode 100644 index 2aa52794b58..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/DomQuery.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -if (version_compare(PHPUnit_Runner_Version::id(), '4.1', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'DomQuery41.php'); - - class Zend_Test_PHPUnit_Constraint_DomQuery extends Zend_Test_PHPUnit_Constraint_DomQuery41 - {} -} elseif (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'DomQuery37.php'); - - class Zend_Test_PHPUnit_Constraint_DomQuery extends Zend_Test_PHPUnit_Constraint_DomQuery37 - {} -} else { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'DomQuery34.php'); - - class Zend_Test_PHPUnit_Constraint_DomQuery extends Zend_Test_PHPUnit_Constraint_DomQuery34 - {} -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/DomQuery34.php b/lib/Zend/Test/PHPUnit/Constraint/DomQuery34.php deleted file mode 100644 index b200ff7b0f5..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/DomQuery34.php +++ /dev/null @@ -1,422 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** @see Zend_Dom_Query */ -#require_once 'Zend/Dom/Query.php'; - -/** - * Zend_Dom_Query-based PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_DomQuery34 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_QUERY = 'assertQuery'; - const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains'; - const ASSERT_CONTENT_REGEX = 'assertQueryContentRegex'; - const ASSERT_CONTENT_COUNT = 'assertQueryCount'; - const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin'; - const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_QUERY, - self::ASSERT_CONTENT_CONTAINS, - self::ASSERT_CONTENT_REGEX, - self::ASSERT_CONTENT_COUNT, - self::ASSERT_CONTENT_COUNT_MIN, - self::ASSERT_CONTENT_COUNT_MAX, - ); - - /** - * Content being matched - * @var string - */ - protected $_content = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * CSS selector or XPath path to select against - * @var string - */ - protected $_path = null; - - /** - * Whether or not to use XPath when querying - * @var bool - */ - protected $_useXpath = false; - - /** - * XPath namespaces - * @var array - */ - protected $_xpathNamespaces = array(); - - /** - * Constructor; setup constraint state - * - * @param string $path CSS selector path - * @return void - */ - public function __construct($path) - { - $this->_path = $path; - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Whether or not path is a straight XPath expression - * - * @param bool $flag - * @return Zend_Test_PHPUnit_Constraint_DomQuery - */ - public function setUseXpath($flag = true) - { - $this->_useXpath = (bool) $flag; - return $this; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string $other String to examine - * @param null|string Assertion type - * @return bool - */ - public function evaluate($other, $assertType = null) - { - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (strstr($assertType, 'Xpath')) { - $this->setUseXpath(true); - $assertType = str_replace('Xpath', 'Query', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $method = $this->_useXpath ? 'queryXpath' : 'query'; - $domQuery = new Zend_Dom_Query($other); - $domQuery->registerXpathNamespaces($this->_xpathNamespaces); - $result = $domQuery->$method($this->_path); - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_CONTENT_CONTAINS: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match'); - } - $this->_content = $content = $argv[2]; - return ($this->_negate) - ? $this->_notMatchContent($result, $content) - : $this->_matchContent($result, $content); - case self::ASSERT_CONTENT_REGEX: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match'); - } - $this->_content = $content = $argv[2]; - return ($this->_negate) - ? $this->_notRegexContent($result, $content) - : $this->_regexContent($result, $content); - case self::ASSERT_CONTENT_COUNT: - case self::ASSERT_CONTENT_COUNT_MIN: - case self::ASSERT_CONTENT_COUNT_MAX: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare'); - } - $this->_content = $content = $argv[2]; - return $this->_countContent($result, $content, $assertType); - case self::ASSERT_QUERY: - default: - if ($this->_negate) { - return (0 == count($result)); - } else { - return (0 != count($result)); - } - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed $other CSS selector path - * @param string $description - * @param bool $not - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - */ - public function fail($other, $description, $not = false) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_CONTENT_CONTAINS: - $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_REGEX: - $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT: - $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MIN: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MAX: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_QUERY: - default: - $failure = 'Failed asserting node DENOTED BY %s EXISTS'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST'; - } - $failure = sprintf($failure, $other); - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Register XPath namespaces - * - * @param array $xpathNamespaces - * @return void - */ - public function registerXpathNamespaces($xpathNamespaces) - { - $this->_xpathNamespaces = $xpathNamespaces; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match Content to match - * @return bool - */ - protected function _matchContent($result, $match) - { - $match = (string) $match; - - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match - * @return bool - */ - protected function _notMatchContent($result, $match) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return false; - } - } - - return true; - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _regexContent($result, $pattern) - { - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _notRegexContent($result, $pattern) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return false; - } - } - - return true; - } - - /** - * Determine if content count matches criteria - * - * @param Zend_Dom_Query_Result $result - * @param int $test Value against which to test - * @param string $type assertion type - * @return boolean - */ - protected function _countContent($result, $test, $type) - { - $count = count($result); - - switch ($type) { - case self::ASSERT_CONTENT_COUNT: - return ($this->_negate) - ? ($test != $count) - : ($test == $count); - case self::ASSERT_CONTENT_COUNT_MIN: - return ($count >= $test); - case self::ASSERT_CONTENT_COUNT_MAX: - return ($count <= $test); - default: - return false; - } - } - - /** - * Get node content, minus node markup tags - * - * @param DOMNode $node - * @return string - */ - protected function _getNodeContent(DOMNode $node) - { - if ($node instanceof DOMAttr) { - return $node->value; - } else { - $doc = $node->ownerDocument; - $content = $doc->saveXML($node); - $tag = $node->nodeName; - $regex = '|</?' . $tag . '[^>]*>|'; - return preg_replace($regex, '', $content); - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/DomQuery37.php b/lib/Zend/Test/PHPUnit/Constraint/DomQuery37.php deleted file mode 100644 index 2d07f09ded7..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/DomQuery37.php +++ /dev/null @@ -1,434 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** @see Zend_Dom_Query */ -#require_once 'Zend/Dom/Query.php'; - -/** - * Zend_Dom_Query-based PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_DomQuery37 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_QUERY = 'assertQuery'; - const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains'; - const ASSERT_CONTENT_REGEX = 'assertQueryContentRegex'; - const ASSERT_CONTENT_COUNT = 'assertQueryCount'; - const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin'; - const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_QUERY, - self::ASSERT_CONTENT_CONTAINS, - self::ASSERT_CONTENT_REGEX, - self::ASSERT_CONTENT_COUNT, - self::ASSERT_CONTENT_COUNT_MIN, - self::ASSERT_CONTENT_COUNT_MAX, - ); - - /** - * Content being matched - * @var string - */ - protected $_content = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * CSS selector or XPath path to select against - * @var string - */ - protected $_path = null; - - /** - * Whether or not to use XPath when querying - * @var bool - */ - protected $_useXpath = false; - - /** - * XPath namespaces - * @var array - */ - protected $_xpathNamespaces = array(); - - /** - * Constructor; setup constraint state - * - * @param string $path CSS selector path - * @return void - */ - public function __construct($path) - { - $this->_path = $path; - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Whether or not path is a straight XPath expression - * - * @param bool $flag - * @return Zend_Test_PHPUnit_Constraint_DomQuery - */ - public function setUseXpath($flag = true) - { - $this->_useXpath = (bool) $flag; - return $this; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string Response content to be matched against (haystack) - * @param null|string Assertion type - * @param string (optional) String to match (needle), may be required depending on assertion type - * @return bool - * - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($content, $assertType = '', $match = FALSE) - { - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (strstr($assertType, 'Xpath')) { - $this->setUseXpath(true); - $assertType = str_replace('Xpath', 'Query', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $method = $this->_useXpath ? 'queryXpath' : 'query'; - $domQuery = new Zend_Dom_Query($content); - $domQuery->registerXpathNamespaces($this->_xpathNamespaces); - $result = $domQuery->$method($this->_path); - - switch ($assertType) { - case self::ASSERT_CONTENT_CONTAINS: - if (!$match) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match'); - } - $this->_content = $match; - return ($this->_negate) - ? $this->_notMatchContent($result, $match) - : $this->_matchContent($result, $match); - case self::ASSERT_CONTENT_REGEX: - if (!$match) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match'); - } - $this->_content = $match; - return ($this->_negate) - ? $this->_notRegexContent($result, $match) - : $this->_regexContent($result, $match); - case self::ASSERT_CONTENT_COUNT: - case self::ASSERT_CONTENT_COUNT_MIN: - case self::ASSERT_CONTENT_COUNT_MAX: - if ($match === false) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare'); - } - $this->_content = $match; - return $this->_countContent($result, $match, $assertType); - case self::ASSERT_QUERY: - default: - if ($this->_negate) { - return (0 == count($result)); - } else { - return (0 != count($result)); - } - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed CSS selector path - * @param string Failure description - * @param object Cannot be used, null - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - */ - public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_CONTENT_CONTAINS: - $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_REGEX: - $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT: - $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MIN: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MAX: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_QUERY: - default: - $failure = 'Failed asserting node DENOTED BY %s EXISTS'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST'; - } - $failure = sprintf($failure, $other); - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Register XPath namespaces - * - * @param array $xpathNamespaces - * @return void - */ - public function registerXpathNamespaces($xpathNamespaces) - { - $this->_xpathNamespaces = $xpathNamespaces; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match Content to match - * @return bool - */ - protected function _matchContent($result, $match) - { - $match = (string) $match; - - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match - * @return bool - */ - protected function _notMatchContent($result, $match) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return false; - } - } - - return true; - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _regexContent($result, $pattern) - { - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _notRegexContent($result, $pattern) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return false; - } - } - - return true; - } - - /** - * Determine if content count matches criteria - * - * @param Zend_Dom_Query_Result $result - * @param int $test Value against which to test - * @param string $type assertion type - * @return boolean - */ - protected function _countContent($result, $test, $type) - { - $count = count($result); - - switch ($type) { - case self::ASSERT_CONTENT_COUNT: - return ($this->_negate) - ? ($test != $count) - : ($test == $count); - case self::ASSERT_CONTENT_COUNT_MIN: - return ($count >= $test); - case self::ASSERT_CONTENT_COUNT_MAX: - return ($count <= $test); - default: - return false; - } - } - - /** - * Get node content, minus node markup tags - * - * @param DOMNode $node - * @return string - */ - protected function _getNodeContent(DOMNode $node) - { - if ($node instanceof DOMAttr) { - return $node->value; - } else { - $doc = $node->ownerDocument; - $content = $doc->saveXML($node); - $tag = $node->nodeName; - $regex = '|</?' . $tag . '[^>]*>|'; - return preg_replace($regex, '', $content); - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/DomQuery41.php b/lib/Zend/Test/PHPUnit/Constraint/DomQuery41.php deleted file mode 100644 index 631d5587a76..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/DomQuery41.php +++ /dev/null @@ -1,436 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** @see Zend_Dom_Query */ -#require_once 'Zend/Dom/Query.php'; - -/** - * Zend_Dom_Query-based PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_DomQuery41 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_QUERY = 'assertQuery'; - const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains'; - const ASSERT_CONTENT_REGEX = 'assertQueryContentRegex'; - const ASSERT_CONTENT_COUNT = 'assertQueryCount'; - const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin'; - const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_QUERY, - self::ASSERT_CONTENT_CONTAINS, - self::ASSERT_CONTENT_REGEX, - self::ASSERT_CONTENT_COUNT, - self::ASSERT_CONTENT_COUNT_MIN, - self::ASSERT_CONTENT_COUNT_MAX, - ); - - /** - * Content being matched - * @var string - */ - protected $_content = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * CSS selector or XPath path to select against - * @var string - */ - protected $_path = null; - - /** - * Whether or not to use XPath when querying - * @var bool - */ - protected $_useXpath = false; - - /** - * XPath namespaces - * @var array - */ - protected $_xpathNamespaces = array(); - - /** - * Constructor; setup constraint state - * - * @param string $path CSS selector path - * @return void - */ - public function __construct($path) - { - $this->_path = $path; - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Whether or not path is a straight XPath expression - * - * @param bool $flag - * @return Zend_Test_PHPUnit_Constraint_DomQuery - */ - public function setUseXpath($flag = true) - { - $this->_useXpath = (bool) $flag; - return $this; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string Response content to be matched against (haystack) - * @param null|string Assertion type - * @param string (optional) String to match (needle), may be required depending on assertion type - * @return bool - * - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($content, $assertType = '', $match = FALSE) - { - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (strstr($assertType, 'Xpath')) { - $this->setUseXpath(true); - $assertType = str_replace('Xpath', 'Query', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $method = $this->_useXpath ? 'queryXpath' : 'query'; - $domQuery = new Zend_Dom_Query($content); - $domQuery->registerXpathNamespaces($this->_xpathNamespaces); - $result = $domQuery->$method($this->_path); - - switch ($assertType) { - case self::ASSERT_CONTENT_CONTAINS: - if (!$match) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match'); - } - $this->_content = $match; - return ($this->_negate) - ? $this->_notMatchContent($result, $match) - : $this->_matchContent($result, $match); - case self::ASSERT_CONTENT_REGEX: - if (!$match) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match'); - } - $this->_content = $match; - return ($this->_negate) - ? $this->_notRegexContent($result, $match) - : $this->_regexContent($result, $match); - case self::ASSERT_CONTENT_COUNT: - case self::ASSERT_CONTENT_COUNT_MIN: - case self::ASSERT_CONTENT_COUNT_MAX: - if ($match === false) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare'); - } - $this->_content = $match; - return $this->_countContent($result, $match, $assertType); - case self::ASSERT_QUERY: - default: - if ($this->_negate) { - return (0 == count($result)); - } else { - return (0 != count($result)); - } - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed CSS selector path - * @param string Failure description - * @param object Cannot be used, null - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - * NOTE 2: - * Interface changed again in PHPUnit 4.1.0 because of refactoring to SebastianBergmann\Comparator - */ - public function fail($other, $description, \SebastianBergmann\Comparator\ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_CONTENT_CONTAINS: - $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_REGEX: - $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT: - $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times'; - } - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MIN: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_CONTENT_COUNT_MAX: - $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times'; - $failure = sprintf($failure, $other, $this->_content); - break; - case self::ASSERT_QUERY: - default: - $failure = 'Failed asserting node DENOTED BY %s EXISTS'; - if ($this->_negate) { - $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST'; - } - $failure = sprintf($failure, $other); - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Register XPath namespaces - * - * @param array $xpathNamespaces - * @return void - */ - public function registerXpathNamespaces($xpathNamespaces) - { - $this->_xpathNamespaces = $xpathNamespaces; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match Content to match - * @return bool - */ - protected function _matchContent($result, $match) - { - $match = (string) $match; - - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $match - * @return bool - */ - protected function _notMatchContent($result, $match) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (strstr($content, $match)) { - return false; - } - } - - return true; - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _regexContent($result, $pattern) - { - if (0 == count($result)) { - return false; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return true; - } - } - - return false; - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Dom_Query_Result $result - * @param string $pattern - * @return bool - */ - protected function _notRegexContent($result, $pattern) - { - if (0 == count($result)) { - return true; - } - - foreach ($result as $node) { - $content = $this->_getNodeContent($node); - if (preg_match($pattern, $content)) { - return false; - } - } - - return true; - } - - /** - * Determine if content count matches criteria - * - * @param Zend_Dom_Query_Result $result - * @param int $test Value against which to test - * @param string $type assertion type - * @return boolean - */ - protected function _countContent($result, $test, $type) - { - $count = count($result); - - switch ($type) { - case self::ASSERT_CONTENT_COUNT: - return ($this->_negate) - ? ($test != $count) - : ($test == $count); - case self::ASSERT_CONTENT_COUNT_MIN: - return ($count >= $test); - case self::ASSERT_CONTENT_COUNT_MAX: - return ($count <= $test); - default: - return false; - } - } - - /** - * Get node content, minus node markup tags - * - * @param DOMNode $node - * @return string - */ - protected function _getNodeContent(DOMNode $node) - { - if ($node instanceof DOMAttr) { - return $node->value; - } else { - $doc = $node->ownerDocument; - $content = $doc->saveXML($node); - $tag = $node->nodeName; - $regex = '|</?' . $tag . '[^>]*>|'; - return preg_replace($regex, '', $content); - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/Exception.php b/lib/Zend/Test/PHPUnit/Constraint/Exception.php deleted file mode 100644 index 2286fef0764..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Test_PHPUnit_Constraint_Exception - * - * @uses PHPUnit_Framework_ExpectationFailedException - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_Exception extends PHPUnit_Framework_ExpectationFailedException -{ -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/Redirect.php b/lib/Zend/Test/PHPUnit/Constraint/Redirect.php deleted file mode 100644 index 819d8b2b965..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/Redirect.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -if (version_compare(PHPUnit_Runner_Version::id(), '4.1', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Redirect41.php'); - - class Zend_Test_PHPUnit_Constraint_Redirect extends Zend_Test_PHPUnit_Constraint_Redirect41 - {} -} elseif (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Redirect37.php'); - - class Zend_Test_PHPUnit_Constraint_Redirect extends Zend_Test_PHPUnit_Constraint_Redirect37 - {} -} else { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Redirect34.php'); - - class Zend_Test_PHPUnit_Constraint_Redirect extends Zend_Test_PHPUnit_Constraint_Redirect34 - {} -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/Redirect34.php b/lib/Zend/Test/PHPUnit/Constraint/Redirect34.php deleted file mode 100644 index 8f350189bba..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/Redirect34.php +++ /dev/null @@ -1,303 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Redirection constraints - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_Redirect34 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_REDIRECT = 'assertRedirect'; - const ASSERT_REDIRECT_TO = 'assertRedirectTo'; - const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_REDIRECT, - self::ASSERT_REDIRECT_TO, - self::ASSERT_REDIRECT_REGEX, - ); - - /** - * Pattern to match against - * @var string - */ - protected $_match = null; - - /** - * What is actual redirect - */ - protected $_actual = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string $other String to examine - * @param null|string Assertion type - * @return bool - */ - public function evaluate($other, $assertType = null) - { - if (!$other instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $response = $other; - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_REDIRECT_TO: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notMatch($response, $match) - : $this->_match($response, $match); - case self::ASSERT_REDIRECT_REGEX: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notRegex($response, $match) - : $this->_regex($response, $match); - case self::ASSERT_REDIRECT: - default: - $headers = $response->sendHeaders(); - if (isset($headers['location'])) { - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - } - return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect(); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed $other - * @param string $description Additional message to display - * @param bool $not - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - */ - public function fail($other, $description, $not = false) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_REDIRECT_TO: - $failure = 'Failed asserting response redirects to "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to "%s"'; - } - $failure = sprintf($failure, $this->_match); - if (!$this->_negate && $this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT_REGEX: - $failure = 'Failed asserting response redirects to URL MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"'; - } - $failure = sprintf($failure, $this->_match); - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT: - default: - $failure = 'Failed asserting response is a redirect'; - if ($this->_negate) { - $failure = 'Failed asserting response is NOT a redirect'; - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual); - } - } - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match Content to match - * @return bool - */ - protected function _match($response, $match) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect == $match); - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match - * @return bool - */ - protected function _notMatch($response, $match) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect != $match); - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _regex($response, $pattern) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return preg_match($pattern, $redirect); - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _notRegex($response, $pattern) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return !preg_match($pattern, $redirect); - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/Redirect37.php b/lib/Zend/Test/PHPUnit/Constraint/Redirect37.php deleted file mode 100644 index f47c491eeeb..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/Redirect37.php +++ /dev/null @@ -1,315 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Redirection constraints - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_Redirect37 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_REDIRECT = 'assertRedirect'; - const ASSERT_REDIRECT_TO = 'assertRedirectTo'; - const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_REDIRECT, - self::ASSERT_REDIRECT_TO, - self::ASSERT_REDIRECT_REGEX, - ); - - /** - * Pattern to match against - * @var string - */ - protected $_match = null; - - /** - * What is actual redirect - */ - protected $_actual = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string $other String to examine - * @param null|string Assertion type - * @return bool - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($other, $assertType = null, $variable = FALSE) - { - if (!$other instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $response = $other; - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_REDIRECT_TO: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notMatch($response, $match) - : $this->_match($response, $match); - case self::ASSERT_REDIRECT_REGEX: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notRegex($response, $match) - : $this->_regex($response, $match); - case self::ASSERT_REDIRECT: - default: - $headers = $response->sendHeaders(); - if (isset($headers['location'])) { - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - } - return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect(); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed $other - * @param string $description Additional message to display - * @param bool $not - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - */ - public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_REDIRECT_TO: - $failure = 'Failed asserting response redirects to "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to "%s"'; - } - $failure = sprintf($failure, $this->_match); - if (!$this->_negate && $this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT_REGEX: - $failure = 'Failed asserting response redirects to URL MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"'; - } - $failure = sprintf($failure, $this->_match); - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT: - default: - $failure = 'Failed asserting response is a redirect'; - if ($this->_negate) { - $failure = 'Failed asserting response is NOT a redirect'; - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual); - } - } - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match Content to match - * @return bool - */ - protected function _match($response, $match) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect == $match); - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match - * @return bool - */ - protected function _notMatch($response, $match) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect != $match); - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _regex($response, $pattern) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return preg_match($pattern, $redirect); - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _notRegex($response, $pattern) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return !preg_match($pattern, $redirect); - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/Redirect41.php b/lib/Zend/Test/PHPUnit/Constraint/Redirect41.php deleted file mode 100644 index 35423a6a588..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/Redirect41.php +++ /dev/null @@ -1,317 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Redirection constraints - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_Redirect41 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_REDIRECT = 'assertRedirect'; - const ASSERT_REDIRECT_TO = 'assertRedirectTo'; - const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_REDIRECT, - self::ASSERT_REDIRECT_TO, - self::ASSERT_REDIRECT_REGEX, - ); - - /** - * Pattern to match against - * @var string - */ - protected $_match = null; - - /** - * What is actual redirect - */ - protected $_actual = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param string $other String to examine - * @param null|string Assertion type - * @return bool - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($other, $assertType = null, $variable = FALSE) - { - if (!$other instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $response = $other; - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_REDIRECT_TO: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notMatch($response, $match) - : $this->_match($response, $match); - case self::ASSERT_REDIRECT_REGEX: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect'); - } - $this->_match = $match = $argv[2]; - return ($this->_negate) - ? $this->_notRegex($response, $match) - : $this->_regex($response, $match); - case self::ASSERT_REDIRECT: - default: - $headers = $response->sendHeaders(); - if (isset($headers['location'])) { - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - } - return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect(); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed $other - * @param string $description Additional message to display - * @param bool $not - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - * NOTE 2: - * Interface changed again in PHPUnit 4.1.0 because of refactoring to SebastianBergmann\Comparator - */ - public function fail($other, $description, \SebastianBergmann\Comparator\ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_REDIRECT_TO: - $failure = 'Failed asserting response redirects to "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to "%s"'; - } - $failure = sprintf($failure, $this->_match); - if (!$this->_negate && $this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT_REGEX: - $failure = 'Failed asserting response redirects to URL MATCHING "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"'; - } - $failure = sprintf($failure, $this->_match); - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual); - } - break; - case self::ASSERT_REDIRECT: - default: - $failure = 'Failed asserting response is a redirect'; - if ($this->_negate) { - $failure = 'Failed asserting response is NOT a redirect'; - if ($this->_actual) { - $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual); - } - } - break; - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Check to see if content is matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match Content to match - * @return bool - */ - protected function _match($response, $match) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect == $match); - } - - /** - * Check to see if content is NOT matched in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $match - * @return bool - */ - protected function _notMatch($response, $match) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return ($redirect != $match); - } - - /** - * Check to see if content is matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _regex($response, $pattern) - { - if (!$response->isRedirect()) { - return false; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return preg_match($pattern, $redirect); - } - - /** - * Check to see if content is NOT matched by regex in selected nodes - * - * @param Zend_Controller_Response_HttpTestCase $response - * @param string $pattern - * @return bool - */ - protected function _notRegex($response, $pattern) - { - if (!$response->isRedirect()) { - return true; - } - - $headers = $response->sendHeaders(); - $redirect = $headers['location']; - $redirect = str_replace('Location: ', '', $redirect); - $this->_actual = $redirect; - - return !preg_match($pattern, $redirect); - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader.php b/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader.php deleted file mode 100644 index 178de050517..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -if (version_compare(PHPUnit_Runner_Version::id(), '4.1', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ResponseHeader41.php'); - - class Zend_Test_PHPUnit_Constraint_ResponseHeader extends Zend_Test_PHPUnit_Constraint_ResponseHeader41 - {} -} elseif (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ResponseHeader37.php'); - - class Zend_Test_PHPUnit_Constraint_ResponseHeader extends Zend_Test_PHPUnit_Constraint_ResponseHeader37 - {} -} else { - include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ResponseHeader34.php'); - - class Zend_Test_PHPUnit_Constraint_ResponseHeader extends Zend_Test_PHPUnit_Constraint_ResponseHeader34 - {} -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader34.php b/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader34.php deleted file mode 100644 index e866af3888e..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader34.php +++ /dev/null @@ -1,406 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Response header PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_ResponseHeader34 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_RESPONSE_CODE = 'assertResponseCode'; - const ASSERT_HEADER = 'assertHeader'; - const ASSERT_HEADER_CONTAINS = 'assertHeaderContains'; - const ASSERT_HEADER_REGEX = 'assertHeaderRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_RESPONSE_CODE, - self::ASSERT_HEADER, - self::ASSERT_HEADER_CONTAINS, - self::ASSERT_HEADER_REGEX, - ); - - /** - * @var int Response code - */ - protected $_code = 200; - - /** - * @var int Actual response code - */ - protected $_actualCode = null; - - /** - * @var string Header - */ - protected $_header = null; - - /** - * @var string pattern against which to compare header content - */ - protected $_match = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param Zend_Controller_Response_Abstract $other String to examine - * @param null|string Assertion type - * @return bool - */ - public function evaluate($other, $assertType = null) - { - if (!$other instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $response = $other; - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_RESPONSE_CODE: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match'); - } - $this->_code = $code = $argv[2]; - return ($this->_negate) - ? $this->_notCode($response, $code) - : $this->_code($response, $code); - case self::ASSERT_HEADER: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match'); - } - $this->_header = $header = $argv[2]; - return ($this->_negate) - ? $this->_notHeader($response, $header) - : $this->_header($response, $header); - case self::ASSERT_HEADER_CONTAINS: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderContains($response, $header, $match) - : $this->_headerContains($response, $header, $match); - case self::ASSERT_HEADER_REGEX: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderRegex($response, $header, $match) - : $this->_headerRegex($response, $header, $match); - default: - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed $other - * @param string $description Additional message to display - * @param bool $not - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - */ - public function fail($other, $description, $not = false) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_RESPONSE_CODE: - $failure = 'Failed asserting response code "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response code IS NOT "%s"'; - } - $failure = sprintf($failure, $this->_code); - if (!$this->_negate && $this->_actualCode) { - $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode); - } - break; - case self::ASSERT_HEADER: - $failure = 'Failed asserting response header "%s" found'; - if ($this->_negate) { - $failure = 'Failed asserting response response header "%s" WAS NOT found'; - } - $failure = sprintf($failure, $this->_header); - break; - case self::ASSERT_HEADER_CONTAINS: - $failure = 'Failed asserting response header "%s" exists and contains "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - case self::ASSERT_HEADER_REGEX: - $failure = 'Failed asserting response header "%s" exists and matches regex "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - default: - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__); - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Compare response code for positive match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _code(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - $this->_actualCode = $test; - return ($test == $code); - } - - /** - * Compare response code for negative match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _notCode(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - return ($test != $code); - } - - /** - * Retrieve response code - * - * @param Zend_Controller_Response_Abstract $response - * @return int - */ - protected function _getCode(Zend_Controller_Response_Abstract $response) - { - $test = $response->getHttpResponseCode(); - if (null === $test) { - $test = 200; - } - return $test; - } - - /** - * Positive check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _header(Zend_Controller_Response_Abstract $response, $header) - { - return (null !== $this->_getHeader($response, $header)); - } - - /** - * Negative check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _notHeader(Zend_Controller_Response_Abstract $response, $header) - { - return (null === $this->_getHeader($response, $header)); - } - - /** - * Retrieve response header - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return string|null - */ - protected function _getHeader(Zend_Controller_Response_Abstract $response, $header) - { - $headers = $response->sendHeaders(); - $header = strtolower($header); - if (array_key_exists($header, $headers)) { - return $headers[$header]; - } - return null; - } - - /** - * Positive check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) !== false); - } - - /** - * Negative check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) === false); - } - - /** - * Positive check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return preg_match($pattern, $contents); - } - - /** - * Negative check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return !preg_match($pattern, $contents); - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader37.php b/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader37.php deleted file mode 100644 index aea80339d4f..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader37.php +++ /dev/null @@ -1,419 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Response header PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_ResponseHeader37 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_RESPONSE_CODE = 'assertResponseCode'; - const ASSERT_HEADER = 'assertHeader'; - const ASSERT_HEADER_CONTAINS = 'assertHeaderContains'; - const ASSERT_HEADER_REGEX = 'assertHeaderRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_RESPONSE_CODE, - self::ASSERT_HEADER, - self::ASSERT_HEADER_CONTAINS, - self::ASSERT_HEADER_REGEX, - ); - - /** - * @var int Response code - */ - protected $_code = 200; - - /** - * @var int Actual response code - */ - protected $_actualCode = null; - - /** - * @var string Header - */ - protected $_header = null; - - /** - * @var string pattern against which to compare header content - */ - protected $_match = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param object of Zend_Controller_Response_Abstract to be evaluated - * @param null|string Assertion type - * @param int|string HTTP response code to evaluate against | header string (haystack) - * @param string (optional) match (needle), may be required depending on assertion type - * @return bool - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($response, $assertType = '', $variable = FALSE) - { - if (!$response instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_RESPONSE_CODE: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match'); - } - $this->_code = $code = $argv[2]; - return ($this->_negate) - ? $this->_notCode($response, $code) - : $this->_code($response, $code); - case self::ASSERT_HEADER: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match'); - } - $this->_header = $header = $argv[2]; - return ($this->_negate) - ? $this->_notHeader($response, $header) - : $this->_header($response, $header); - case self::ASSERT_HEADER_CONTAINS: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderContains($response, $header, $match) - : $this->_headerContains($response, $header, $match); - case self::ASSERT_HEADER_REGEX: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderRegex($response, $header, $match) - : $this->_headerRegex($response, $header, $match); - default: - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . $assertType); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed CSS selector path - * @param string Failure description - * @param object Cannot be used, null - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - */ - public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_RESPONSE_CODE: - $failure = 'Failed asserting response code "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response code IS NOT "%s"'; - } - $failure = sprintf($failure, $this->_code); - if (!$this->_negate && $this->_actualCode) { - $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode); - } - break; - case self::ASSERT_HEADER: - $failure = 'Failed asserting response header "%s" found'; - if ($this->_negate) { - $failure = 'Failed asserting response response header "%s" WAS NOT found'; - } - $failure = sprintf($failure, $this->_header); - break; - case self::ASSERT_HEADER_CONTAINS: - $failure = 'Failed asserting response header "%s" exists and contains "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - case self::ASSERT_HEADER_REGEX: - $failure = 'Failed asserting response header "%s" exists and matches regex "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - default: - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__); - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Compare response code for positive match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _code(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - $this->_actualCode = $test; - return ($test == $code); - } - - /** - * Compare response code for negative match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _notCode(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - return ($test != $code); - } - - /** - * Retrieve response code - * - * @param Zend_Controller_Response_Abstract $response - * @return int - */ - protected function _getCode(Zend_Controller_Response_Abstract $response) - { - $test = $response->getHttpResponseCode(); - if (null === $test) { - $test = 200; - } - return $test; - } - - /** - * Positive check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _header(Zend_Controller_Response_Abstract $response, $header) - { - return (null !== $this->_getHeader($response, $header)); - } - - /** - * Negative check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _notHeader(Zend_Controller_Response_Abstract $response, $header) - { - return (null === $this->_getHeader($response, $header)); - } - - /** - * Retrieve response header - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return string|null - */ - protected function _getHeader(Zend_Controller_Response_Abstract $response, $header) - { - $headers = $response->sendHeaders(); - $header = strtolower($header); - if (array_key_exists($header, $headers)) { - return $headers[$header]; - } - return null; - } - - /** - * Positive check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) !== false); - } - - /** - * Negative check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) === false); - } - - /** - * Positive check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return preg_match($pattern, $contents); - } - - /** - * Negative check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return !preg_match($pattern, $contents); - } -} diff --git a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader41.php b/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader41.php deleted file mode 100644 index e5da1f965f7..00000000000 --- a/lib/Zend/Test/PHPUnit/Constraint/ResponseHeader41.php +++ /dev/null @@ -1,421 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Response header PHPUnit Constraint - * - * @uses PHPUnit_Framework_Constraint - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Constraint_ResponseHeader41 extends PHPUnit_Framework_Constraint -{ - /**#@+ - * Assertion type constants - */ - const ASSERT_RESPONSE_CODE = 'assertResponseCode'; - const ASSERT_HEADER = 'assertHeader'; - const ASSERT_HEADER_CONTAINS = 'assertHeaderContains'; - const ASSERT_HEADER_REGEX = 'assertHeaderRegex'; - /**#@-*/ - - /** - * Current assertion type - * @var string - */ - protected $_assertType = null; - - /** - * Available assertion types - * @var array - */ - protected $_assertTypes = array( - self::ASSERT_RESPONSE_CODE, - self::ASSERT_HEADER, - self::ASSERT_HEADER_CONTAINS, - self::ASSERT_HEADER_REGEX, - ); - - /** - * @var int Response code - */ - protected $_code = 200; - - /** - * @var int Actual response code - */ - protected $_actualCode = null; - - /** - * @var string Header - */ - protected $_header = null; - - /** - * @var string pattern against which to compare header content - */ - protected $_match = null; - - /** - * Whether or not assertion is negated - * @var bool - */ - protected $_negate = false; - - /** - * Constructor; setup constraint state - * - * @return void - */ - public function __construct() - { - } - - /** - * Indicate negative match - * - * @param bool $flag - * @return void - */ - public function setNegate($flag = true) - { - $this->_negate = $flag; - } - - /** - * Evaluate an object to see if it fits the constraints - * - * @param object of Zend_Controller_Response_Abstract to be evaluated - * @param null|string Assertion type - * @param int|string HTTP response code to evaluate against | header string (haystack) - * @param string (optional) match (needle), may be required depending on assertion type - * @return bool - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function evaluate($other, $assertType = null) - * In PHPUnit 3.6.0 they changed the interface into this: - * public function evaluate($other, $description = '', $returnResult = FALSE) - * We use the new interface for PHP-strict checking, but emulate the old one - */ - public function evaluate($response, $assertType = '', $variable = FALSE) - { - if (!$response instanceof Zend_Controller_Response_Abstract) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object'); - } - - if (strstr($assertType, 'Not')) { - $this->setNegate(true); - $assertType = str_replace('Not', '', $assertType); - } - - if (!in_array($assertType, $this->_assertTypes)) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); - } - - $this->_assertType = $assertType; - - $argv = func_get_args(); - $argc = func_num_args(); - - switch ($assertType) { - case self::ASSERT_RESPONSE_CODE: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match'); - } - $this->_code = $code = $argv[2]; - return ($this->_negate) - ? $this->_notCode($response, $code) - : $this->_code($response, $code); - case self::ASSERT_HEADER: - if (3 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match'); - } - $this->_header = $header = $argv[2]; - return ($this->_negate) - ? $this->_notHeader($response, $header) - : $this->_header($response, $header); - case self::ASSERT_HEADER_CONTAINS: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderContains($response, $header, $match) - : $this->_headerContains($response, $header, $match); - case self::ASSERT_HEADER_REGEX: - if (4 > $argc) { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); - } - $this->_header = $header = $argv[2]; - $this->_match = $match = $argv[3]; - return ($this->_negate) - ? $this->_notHeaderRegex($response, $header, $match) - : $this->_headerRegex($response, $header, $match); - default: - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . $assertType); - } - } - - /** - * Report Failure - * - * @see PHPUnit_Framework_Constraint for implementation details - * @param mixed CSS selector path - * @param string Failure description - * @param object Cannot be used, null - * @return void - * @throws PHPUnit_Framework_ExpectationFailedException - * NOTE: - * Drastic changes up to PHPUnit 3.5.15 this was: - * public function fail($other, $description, $not = false) - * In PHPUnit 3.6.0 they changed the interface into this: - * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) - * We use the new interface for PHP-strict checking - * NOTE 2: - * Interface changed again in PHPUnit 4.1.0 because of refactoring to SebastianBergmann\Comparator - */ - public function fail($other, $description, \SebastianBergmann\Comparator\ComparisonFailure $cannot_be_used = NULL) - { - #require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; - switch ($this->_assertType) { - case self::ASSERT_RESPONSE_CODE: - $failure = 'Failed asserting response code "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response code IS NOT "%s"'; - } - $failure = sprintf($failure, $this->_code); - if (!$this->_negate && $this->_actualCode) { - $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode); - } - break; - case self::ASSERT_HEADER: - $failure = 'Failed asserting response header "%s" found'; - if ($this->_negate) { - $failure = 'Failed asserting response response header "%s" WAS NOT found'; - } - $failure = sprintf($failure, $this->_header); - break; - case self::ASSERT_HEADER_CONTAINS: - $failure = 'Failed asserting response header "%s" exists and contains "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - case self::ASSERT_HEADER_REGEX: - $failure = 'Failed asserting response header "%s" exists and matches regex "%s"'; - if ($this->_negate) { - $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"'; - } - $failure = sprintf($failure, $this->_header, $this->_match); - break; - default: - throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__); - } - - if (!empty($description)) { - $failure = $description . "\n" . $failure; - } - - throw new Zend_Test_PHPUnit_Constraint_Exception($failure); - } - - /** - * Complete implementation - * - * @return string - */ - public function toString() - { - return ''; - } - - /** - * Compare response code for positive match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _code(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - $this->_actualCode = $test; - return ($test == $code); - } - - /** - * Compare response code for negative match - * - * @param Zend_Controller_Response_Abstract $response - * @param int $code - * @return bool - */ - protected function _notCode(Zend_Controller_Response_Abstract $response, $code) - { - $test = $this->_getCode($response); - return ($test != $code); - } - - /** - * Retrieve response code - * - * @param Zend_Controller_Response_Abstract $response - * @return int - */ - protected function _getCode(Zend_Controller_Response_Abstract $response) - { - $test = $response->getHttpResponseCode(); - if (null === $test) { - $test = 200; - } - return $test; - } - - /** - * Positive check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _header(Zend_Controller_Response_Abstract $response, $header) - { - return (null !== $this->_getHeader($response, $header)); - } - - /** - * Negative check for response header presence - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return bool - */ - protected function _notHeader(Zend_Controller_Response_Abstract $response, $header) - { - return (null === $this->_getHeader($response, $header)); - } - - /** - * Retrieve response header - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @return string|null - */ - protected function _getHeader(Zend_Controller_Response_Abstract $response, $header) - { - $headers = $response->sendHeaders(); - $header = strtolower($header); - if (array_key_exists($header, $headers)) { - return $headers[$header]; - } - return null; - } - - /** - * Positive check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) !== false); - } - - /** - * Negative check for header contents matching pattern - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $match - * @return bool - */ - protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return (strstr($contents, $match) === false); - } - - /** - * Positive check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return false; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return preg_match($pattern, $contents); - } - - /** - * Negative check for header contents matching regex - * - * @param Zend_Controller_Response_Abstract $response - * @param string $header - * @param string $pattern - * @return bool - */ - protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) - { - if (null === ($fullHeader = $this->_getHeader($response, $header))) { - return true; - } - - $contents = str_replace($header . ': ', '', $fullHeader); - - return !preg_match($pattern, $contents); - } -} diff --git a/lib/Zend/Test/PHPUnit/ControllerTestCase.php b/lib/Zend/Test/PHPUnit/ControllerTestCase.php deleted file mode 100644 index 8b9972937de..00000000000 --- a/lib/Zend/Test/PHPUnit/ControllerTestCase.php +++ /dev/null @@ -1,1165 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** @see Zend_Controller_Front */ -#require_once 'Zend/Controller/Front.php'; - -/** @see Zend_Controller_Action_HelperBroker */ -#require_once 'Zend/Controller/Action/HelperBroker.php'; - -/** @see Zend_Layout */ -#require_once 'Zend/Layout.php'; - -/** @see Zend_Session */ -#require_once 'Zend/Session.php'; - -/** @see Zend_Registry */ -#require_once 'Zend/Registry.php'; - -/** - * Functional testing scaffold for MVC applications - * - * @uses PHPUnit_Framework_TestCase - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_TestCase -{ - /** - * @var mixed Bootstrap file path or callback - */ - public $bootstrap; - - /** - * @var Zend_Controller_Front - */ - protected $_frontController; - - /** - * @var Zend_Dom_Query - */ - protected $_query; - - /** - * @var Zend_Controller_Request_Abstract - */ - protected $_request; - - /** - * @var Zend_Controller_Response_Abstract - */ - protected $_response; - - /** - * XPath namespaces - * @var array - */ - protected $_xpathNamespaces = array(); - - /** - * Overloading: prevent overloading to special properties - * - * @param string $name - * @param mixed $value - * @throws Zend_Exception - */ - public function __set($name, $value) - { - if (in_array($name, array('request', 'response', 'frontController'))) { - #require_once 'Zend/Exception.php'; - throw new Zend_Exception(sprintf('Setting %s object manually is not allowed', $name)); - } - $this->$name = $value; - } - - /** - * Overloading for common properties - * - * Provides overloading for request, response, and frontController objects. - * - * @param mixed $name - * @return null|Zend_Controller_Front|Zend_Controller_Request_HttpTestCase|Zend_Controller_Response_HttpTestCase - */ - public function __get($name) - { - switch ($name) { - case 'request': - return $this->getRequest(); - case 'response': - return $this->getResponse(); - case 'frontController': - return $this->getFrontController(); - } - - return null; - } - - /** - * Set up MVC app - * - * Calls {@link bootstrap()} by default - */ - protected function setUp() - { - $this->bootstrap(); - } - - /** - * Bootstrap the front controller - * - * Resets the front controller, and then bootstraps it. - * - * If {@link $bootstrap} is a callback, executes it; if it is a file, it include's - * it. When done, sets the test case request and response objects into the - * front controller. - */ - final public function bootstrap() - { - $this->reset(); - if (null !== $this->bootstrap) { - if ($this->bootstrap instanceof Zend_Application) { - $this->bootstrap->bootstrap(); - $this->_frontController = $this->bootstrap->getBootstrap()->getResource('frontcontroller'); - } elseif (is_callable($this->bootstrap)) { - call_user_func($this->bootstrap); - } elseif (is_string($this->bootstrap)) { - #require_once 'Zend/Loader.php'; - if (Zend_Loader::isReadable($this->bootstrap)) { - include $this->bootstrap; - } - } - } - $this->frontController - ->setRequest($this->getRequest()) - ->setResponse($this->getResponse()); - } - - /** - * Dispatch the MVC - * - * If a URL is provided, sets it as the request URI in the request object. - * Then sets test case request and response objects in front controller, - * disables throwing exceptions, and disables returning the response. - * Finally, dispatches the front controller. - * - * @param string|null $url - */ - public function dispatch($url = null) - { - // redirector should not exit - $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); - $redirector->setExit(false); - - // json helper should not exit - $json = Zend_Controller_Action_HelperBroker::getStaticHelper('json'); - $json->suppressExit = true; - - $request = $this->getRequest(); - if (null !== $url) { - $request->setRequestUri($url); - } - $request->setPathInfo(null); - - $controller = $this->getFrontController(); - $this->frontController - ->setRequest($request) - ->setResponse($this->getResponse()) - ->throwExceptions(false) - ->returnResponse(false); - - if ($this->bootstrap instanceof Zend_Application) { - $this->bootstrap->run(); - } else { - $this->frontController->dispatch(); - } - } - - /** - * Reset MVC state - * - * Creates new request/response objects, resets the front controller - * instance, and resets the action helper broker. - * - * @todo Need to update Zend_Layout to add a resetInstance() method - */ - public function reset() - { - $_SESSION = array(); - $_GET = array(); - $_POST = array(); - $_COOKIE = array(); - $this->resetRequest(); - $this->resetResponse(); - Zend_Layout::resetMvcInstance(); - Zend_Controller_Action_HelperBroker::resetHelpers(); - $this->frontController->resetInstance(); - Zend_Session::$_unitTestEnabled = true; - } - - /** - * Rest all view placeholders - */ - protected function _resetPlaceholders() - { - $registry = Zend_Registry::getInstance(); - $remove = array(); - foreach ($registry as $key => $value) { - if (strstr($key, '_View_')) { - $remove[] = $key; - } - } - - foreach ($remove as $key) { - unset($registry[$key]); - } - } - - /** - * Reset the request object - * - * Useful for test cases that need to test multiple trips to the server. - * - * @return Zend_Test_PHPUnit_ControllerTestCase - */ - public function resetRequest() - { - if ($this->_request instanceof Zend_Controller_Request_HttpTestCase) { - $this->_request->clearQuery() - ->clearPost(); - } - $this->_request = null; - return $this; - } - - /** - * Reset the response object - * - * Useful for test cases that need to test multiple trips to the server. - * - * @return Zend_Test_PHPUnit_ControllerTestCase - */ - public function resetResponse() - { - $this->_response = null; - $this->_resetPlaceholders(); - return $this; - } - - /** - * Assert against DOM selection - * - * @param string $path CSS selector path - * @param string $message - */ - public function assertQuery($path, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection - * - * @param string $path CSS selector path - * @param string $message - */ - public function assertNotQuery($path, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; node should contain content - * - * @param string $path CSS selector path - * @param string $match content that should be contained in matched nodes - * @param string $message - */ - public function assertQueryContentContains($path, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $match)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; node should NOT contain content - * - * @param string $path CSS selector path - * @param string $match content that should NOT be contained in matched nodes - * @param string $message - */ - public function assertNotQueryContentContains($path, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $match)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; node should match content - * - * @param string $path CSS selector path - * @param string $pattern Pattern that should be contained in matched nodes - * @param string $message - */ - public function assertQueryContentRegex($path, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $pattern)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; node should NOT match content - * - * @param string $path CSS selector path - * @param string $pattern pattern that should NOT be contained in matched nodes - * @param string $message - */ - public function assertNotQueryContentRegex($path, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $pattern)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; should contain exact number of nodes - * - * @param string $path CSS selector path - * @param string $count Number of nodes that should match - * @param string $message - */ - public function assertQueryCount($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; should NOT contain exact number of nodes - * - * @param string $path CSS selector path - * @param string $count Number of nodes that should NOT match - * @param string $message - */ - public function assertNotQueryCount($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; should contain at least this number of nodes - * - * @param string $path CSS selector path - * @param string $count Minimum number of nodes that should match - * @param string $message - */ - public function assertQueryCountMin($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against DOM selection; should contain no more than this number of nodes - * - * @param string $path CSS selector path - * @param string $count Maximum number of nodes that should match - * @param string $message - */ - public function assertQueryCountMax($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Register XPath namespaces - * - * @param array $xpathNamespaces - */ - public function registerXpathNamespaces($xpathNamespaces) - { - $this->_xpathNamespaces = $xpathNamespaces; - } - - /** - * Assert against XPath selection - * - * @param string $path XPath path - * @param string $message - */ - public function assertXpath($path, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection - * - * @param string $path XPath path - * @param string $message - */ - public function assertNotXpath($path, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; node should contain content - * - * @param string $path XPath path - * @param string $match content that should be contained in matched nodes - * @param string $message - */ - public function assertXpathContentContains($path, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $match)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; node should NOT contain content - * - * @param string $path XPath path - * @param string $match content that should NOT be contained in matched nodes - * @param string $message - */ - public function assertNotXpathContentContains($path, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $match)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; node should match content - * - * @param string $path XPath path - * @param string $pattern Pattern that should be contained in matched nodes - * @param string $message - */ - public function assertXpathContentRegex($path, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $pattern)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; node should NOT match content - * - * @param string $path XPath path - * @param string $pattern pattern that should NOT be contained in matched nodes - * @param string $message - */ - public function assertNotXpathContentRegex($path, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $pattern)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; should contain exact number of nodes - * - * @param string $path XPath path - * @param string $count Number of nodes that should match - * @param string $message - */ - public function assertXpathCount($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; should NOT contain exact number of nodes - * - * @param string $path XPath path - * @param string $count Number of nodes that should NOT match - * @param string $message - */ - public function assertNotXpathCount($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; should contain at least this number of nodes - * - * @param string $path XPath path - * @param string $count Minimum number of nodes that should match - * @param string $message - */ - public function assertXpathCountMin($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert against XPath selection; should contain no more than this number of nodes - * - * @param string $path XPath path - * @param string $count Maximum number of nodes that should match - * @param string $message - */ - public function assertXpathCountMax($path, $count, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/DomQuery.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_DomQuery($path); - $constraint->registerXpathNamespaces($this->_xpathNamespaces); - $content = $this->response->outputBody(); - if (!$constraint->evaluate($content, __FUNCTION__, $count)) { - $constraint->fail($path, $message); - } - } - - /** - * Assert that response is a redirect - * - * @param string $message - */ - public function assertRedirect($message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that response is NOT a redirect - * - * @param string $message - */ - public function assertNotRedirect($message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that response redirects to given URL - * - * @param string $url - * @param string $message - */ - public function assertRedirectTo($url, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $url)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that response does not redirect to given URL - * - * @param string $url - * @param string $message - */ - public function assertNotRedirectTo($url, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $url)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that redirect location matches pattern - * - * @param string $pattern - * @param string $message - */ - public function assertRedirectRegex($pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $pattern)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that redirect location does not match pattern - * - * @param string $pattern - * @param string $message - */ - public function assertNotRedirectRegex($pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/Redirect.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_Redirect(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $pattern)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response code - * - * @param int $code - * @param string $message - */ - public function assertResponseCode($code, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $code)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response code - * - * @param int $code - * @param string $message - */ - public function assertNotResponseCode($code, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $constraint->setNegate(true); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $code)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header exists - * - * @param string $header - * @param string $message - */ - public function assertHeader($header, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header does not exist - * - * @param string $header - * @param string $message - */ - public function assertNotHeader($header, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $constraint->setNegate(true); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header exists and contains the given string - * - * @param string $header - * @param string $match - * @param string $message - */ - public function assertHeaderContains($header, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header, $match)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header does not exist and/or does not contain the given string - * - * @param string $header - * @param string $match - * @param string $message - */ - public function assertNotHeaderContains($header, $match, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $constraint->setNegate(true); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header, $match)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header exists and matches the given pattern - * - * @param string $header - * @param string $pattern - * @param string $message - */ - public function assertHeaderRegex($header, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header, $pattern)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert response header does not exist and/or does not match the given regex - * - * @param string $header - * @param string $pattern - * @param string $message - */ - public function assertNotHeaderRegex($header, $pattern, $message = '') - { - $this->_incrementAssertionCount(); - #require_once 'Zend/Test/PHPUnit/Constraint/ResponseHeader.php'; - $constraint = new Zend_Test_PHPUnit_Constraint_ResponseHeader(); - $constraint->setNegate(true); - $response = $this->response; - if (!$constraint->evaluate($response, __FUNCTION__, $header, $pattern)) { - $constraint->fail($response, $message); - } - } - - /** - * Assert that the last handled request used the given module - * - * @param string $module - * @param string $message - */ - public function assertModule($module, $message = '') - { - $this->_incrementAssertionCount(); - if ($module != $this->request->getModuleName()) { - $msg = sprintf('Failed asserting last module used <"%s"> was "%s"', - $this->request->getModuleName(), - $module - ); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the last handled request did NOT use the given module - * - * @param string $module - * @param string $message - */ - public function assertNotModule($module, $message = '') - { - $this->_incrementAssertionCount(); - if ($module == $this->request->getModuleName()) { - $msg = sprintf('Failed asserting last module used was NOT "%s"', $module); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the last handled request used the given controller - * - * @param string $controller - * @param string $message - */ - public function assertController($controller, $message = '') - { - $this->_incrementAssertionCount(); - if ($controller != $this->request->getControllerName()) { - $msg = sprintf('Failed asserting last controller used <"%s"> was "%s"', - $this->request->getControllerName(), - $controller - ); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the last handled request did NOT use the given controller - * - * @param string $controller - * @param string $message - */ - public function assertNotController($controller, $message = '') - { - $this->_incrementAssertionCount(); - if ($controller == $this->request->getControllerName()) { - $msg = sprintf('Failed asserting last controller used <"%s"> was NOT "%s"', - $this->request->getControllerName(), - $controller - ); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the last handled request used the given action - * - * @param string $action - * @param string $message - */ - public function assertAction($action, $message = '') - { - $this->_incrementAssertionCount(); - if ($action != $this->request->getActionName()) { - $msg = sprintf('Failed asserting last action used <"%s"> was "%s"', $this->request->getActionName(), $action); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the last handled request did NOT use the given action - * - * @param string $action - * @param string $message - */ - public function assertNotAction($action, $message = '') - { - $this->_incrementAssertionCount(); - if ($action == $this->request->getActionName()) { - $msg = sprintf('Failed asserting last action used <"%s"> was NOT "%s"', $this->request->getActionName(), $action); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the specified route was used - * - * @param string $route - * @param string $message - */ - public function assertRoute($route, $message = '') - { - $this->_incrementAssertionCount(); - $router = $this->frontController->getRouter(); - if ($route != $router->getCurrentRouteName()) { - $msg = sprintf('Failed asserting matched route was "%s", actual route is %s', - $route, - $router->getCurrentRouteName() - ); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Assert that the route matched is NOT as specified - * - * @param string $route - * @param string $message - */ - public function assertNotRoute($route, $message = '') - { - $this->_incrementAssertionCount(); - $router = $this->frontController->getRouter(); - if ($route == $router->getCurrentRouteName()) { - $msg = sprintf('Failed asserting route matched was NOT "%s"', $route); - if (!empty($message)) { - $msg = $message . "\n" . $msg; - } - $this->fail($msg); - } - } - - /** - * Retrieve front controller instance - * - * @return Zend_Controller_Front - */ - public function getFrontController() - { - if (null === $this->_frontController) { - $this->_frontController = Zend_Controller_Front::getInstance(); - } - return $this->_frontController; - } - - /** - * Retrieve test case request object - * - * @return Zend_Controller_Request_HttpTestCase - */ - public function getRequest() - { - if (null === $this->_request) { - #require_once 'Zend/Controller/Request/HttpTestCase.php'; - $this->_request = new Zend_Controller_Request_HttpTestCase; - } - return $this->_request; - } - - /** - * Retrieve test case response object - * - * @return Zend_Controller_Response_HttpTestCase - */ - public function getResponse() - { - if (null === $this->_response) { - #require_once 'Zend/Controller/Response/HttpTestCase.php'; - $this->_response = new Zend_Controller_Response_HttpTestCase; - } - return $this->_response; - } - - /** - * Retrieve DOM query object - * - * @return Zend_Dom_Query - */ - public function getQuery() - { - if (null === $this->_query) { - #require_once 'Zend/Dom/Query.php'; - $this->_query = new Zend_Dom_Query; - } - return $this->_query; - } - - /** - * URL Helper - * - * @param array $urlOptions - * @param string $name - * @param bool $reset - * @param bool $encode - * @throws Exception - * @throws Zend_Controller_Router_Exception - * @return string - */ - public function url($urlOptions = array(), $name = null, $reset = false, $encode = true) - { - $frontController = $this->getFrontController(); - $router = $frontController->getRouter(); - if (!$router instanceof Zend_Controller_Router_Rewrite) { - throw new Exception('This url helper utility function only works when the router is of type Zend_Controller_Router_Rewrite'); - } - if (count($router->getRoutes()) == 0) { - $router->addDefaultRoutes(); - } - return $router->assemble($urlOptions, $name, $reset, $encode); - } - - /** - * Urlize options - * - * @param array $urlOptions - * @param bool $actionControllerModuleOnly - * @return mixed - */ - public function urlizeOptions($urlOptions, $actionControllerModuleOnly = true) - { - $ccToDash = new Zend_Filter_Word_CamelCaseToDash(); - foreach ($urlOptions as $n => $v) { - if (in_array($n, array('action', 'controller', 'module'))) { - $urlOptions[$n] = $ccToDash->filter($v); - } - } - return $urlOptions; - } - - /** - * Increment assertion count - */ - protected function _incrementAssertionCount() - { - $stack = debug_backtrace(); - foreach ($stack as $step) { - if (isset($step['object']) - && $step['object'] instanceof PHPUnit_Framework_TestCase - ) { - if (version_compare(PHPUnit_Runner_Version::id(), '3.3.0', 'lt')) { - break; - } elseif (version_compare(PHPUnit_Runner_Version::id(), '3.3.3', 'lt')) { - $step['object']->incrementAssertionCounter(); - } else { - $step['object']->addToAssertionCount(1); - } - break; - } - } - } -} diff --git a/lib/Zend/Test/PHPUnit/DatabaseTestCase.php b/lib/Zend/Test/PHPUnit/DatabaseTestCase.php deleted file mode 100644 index 79b563ca0e7..00000000000 --- a/lib/Zend/Test/PHPUnit/DatabaseTestCase.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_Operation_Truncate - */ -#require_once "Zend/Test/PHPUnit/Db/Operation/Truncate.php"; - -/** - * @see Zend_Test_PHPUnit_Db_Operation_Insert - */ -#require_once "Zend/Test/PHPUnit/Db/Operation/Insert.php"; - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/DbTableDataSet.php"; - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_DbTable - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/DbTable.php"; - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_DbRowset - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/DbRowset.php"; - -/** - * Generic Testcase for Zend Framework related DbUnit Testing with PHPUnit - * - * @uses PHPUnit_Extensions_Database_TestCase - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Test_PHPUnit_DatabaseTestCase extends PHPUnit_Extensions_Database_TestCase -{ - /** - * Creates a new Zend Database Connection using the given Adapter and database schema name. - * - * @param Zend_Db_Adapter_Abstract $connection - * @param string $schema - * @return Zend_Test_PHPUnit_Db_Connection - */ - protected function createZendDbConnection(Zend_Db_Adapter_Abstract $connection, $schema) - { - return new Zend_Test_PHPUnit_Db_Connection($connection, $schema); - } - - /** - * Convenience function to get access to the database connection. - * - * @return Zend_Db_Adapter_Abstract - */ - protected function getAdapter() - { - return $this->getConnection()->getConnection(); - } - - /** - * Returns the database operation executed in test setup. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getSetUpOperation() - { - return new PHPUnit_Extensions_Database_Operation_Composite(array( - new Zend_Test_PHPUnit_Db_Operation_Truncate(), - new Zend_Test_PHPUnit_Db_Operation_Insert(), - )); - } - - /** - * Returns the database operation executed in test cleanup. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getTearDownOperation() - { - return PHPUnit_Extensions_Database_Operation_Factory::NONE(); - } - - /** - * Create a dataset based on multiple Zend_Db_Table instances - * - * @param array $tables - * @return Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet - */ - protected function createDbTableDataSet(array $tables=array()) - { - $dataSet = new Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet(); - foreach($tables AS $table) { - $dataSet->addTable($table); - } - return $dataSet; - } - - /** - * Create a table based on one Zend_Db_Table instance - * - * @param Zend_Db_Table_Abstract $table - * @param string $where - * @param string $order - * @param string $count - * @param string $offset - * @return Zend_Test_PHPUnit_Db_DataSet_DbTable - */ - protected function createDbTable(Zend_Db_Table_Abstract $table, $where=null, $order=null, $count=null, $offset=null) - { - return new Zend_Test_PHPUnit_Db_DataSet_DbTable($table, $where, $order, $count, $offset); - } - - /** - * Create a data table based on a Zend_Db_Table_Rowset instance - * - * @param Zend_Db_Table_Rowset_Abstract $rowset - * @param string - * @return Zend_Test_PHPUnit_Db_DataSet_DbRowset - */ - protected function createDbRowset(Zend_Db_Table_Rowset_Abstract $rowset, $tableName = null) - { - return new Zend_Test_PHPUnit_Db_DataSet_DbRowset($rowset, $tableName); - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/Connection.php b/lib/Zend/Test/PHPUnit/Db/Connection.php deleted file mode 100644 index 95552b9c4d6..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Connection.php +++ /dev/null @@ -1,144 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_QueryTable - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/QueryTable.php"; - -/** - * @see Zend_Test_PHPUnit_Db_Metadata_Generic - */ -#require_once "Zend/Test/PHPUnit/Db/Metadata/Generic.php"; - -/** - * Generic Abstraction of Zend_Db Connections in the PHPUnit Database Extension context. - * - * @uses Zend_Db_Adapter_Abstract - * @uses PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Connection extends PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection -{ - /** - * Zend_Db_Adapter_Abstract - * - * @var Zend_Db_Adapter_Abstract - */ - protected $_connection; - - /** - * Database Schema - * - * @var string $db - */ - protected $_schema; - - /** - * Metadata - * - * @param PHPUnit_Extensions_Database_DB_IMetaData $db - */ - protected $_metaData; - - /** - * Construct Connection based on Zend_Db_Adapter_Abstract - * - * @param Zend_Db_Adapter_Abstract $db - * @param string $schema - */ - public function __construct(Zend_Db_Adapter_Abstract $db, $schema) - { - $this->_connection = $db; - $this->_schema = $schema; - } - - /** - * Close this connection. - * - * @return void - */ - public function close() - { - $this->_connection->closeConnection(); - } - - /** - * Creates a table with the result of the specified SQL statement. - * - * @param string $resultName - * @param string $sql - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function createQueryTable($resultName, $sql) - { - return new Zend_Test_PHPUnit_Db_DataSet_QueryTable($resultName, $sql, $this); - } - - /** - * Returns a Zend_Db Connection - * - * @return Zend_Db_Adapter_Abstract - */ - public function getConnection() - { - return $this->_connection; - } - - /** - * Returns a database metadata object that can be used to retrieve table - * meta data from the database. - * - * @return PHPUnit_Extensions_Database_DB_IMetaData - */ - public function getMetaData() - { - if($this->_metaData === null) { - $this->_metaData = new Zend_Test_PHPUnit_Db_Metadata_Generic($this->getConnection(), $this->getSchema()); - } - return $this->_metaData; - } - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * Returns the command used to truncate a table. - * - * @return string - */ - public function getTruncateCommand() - { - return "DELETE"; - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/DataSet/DbRowset.php b/lib/Zend/Test/PHPUnit/Db/DataSet/DbRowset.php deleted file mode 100644 index d89e0d4db67..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/DataSet/DbRowset.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Db_Table_Rowset_Abstract - */ -#require_once "Zend/Db/Table/Rowset/Abstract.php"; - -/** - * Use a Zend_Db Rowset as a datatable for assertions with other PHPUnit Database extension tables. - * - * @uses PHPUnit_Extensions_Database_DataSet_AbstractTable - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_DataSet_DbRowset extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * Construct Table object from a Zend_Db_Table_Rowset - * - * @param Zend_Db_Table_Rowset_Abstract $rowset - * @param string $tableName - */ - public function __construct(Zend_Db_Table_Rowset_Abstract $rowset, $tableName = null) - { - if($tableName == null) { - $table = $rowset->getTable(); - if($table !== null) { - $tableName = $table->info('name'); - } else { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception( - 'No table name was given to Rowset Table and table name cannot be infered from the table, '. - 'because the rowset is disconnected from database.' - ); - } - } - - $this->data = $rowset->toArray(); - - $columns = array(); - if(isset($this->data[0]) > 0) { - $columns = array_keys($this->data[0]); - } else if($rowset->getTable() != null) { - $columns = $rowset->getTable()->info('cols'); - } - - $this->tableName = $tableName; - $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $columns); - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/DataSet/DbTable.php b/lib/Zend/Test/PHPUnit/Db/DataSet/DbTable.php deleted file mode 100644 index ad37642906c..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/DataSet/DbTable.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Db_Table_Abstract - */ -#require_once "Zend/Db/Table/Abstract.php"; - -/** - * Use a Zend_Db_Table for assertions with other PHPUnit Database Extension table types. - * - * @uses PHPUnit_Extensions_Database_DataSet_QueryTable - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_DataSet_DbTable extends PHPUnit_Extensions_Database_DataSet_QueryTable -{ - /** - * Zend_Db_Table object - * - * @var Zend_Db_Table_Abstract - */ - protected $_table = null; - - /** - * @var array - */ - protected $_columns = array(); - - /** - * @var string - */ - protected $_where = null; - - /** - * @var string - */ - protected $_orderBy = null; - - /** - * @var string - */ - protected $_count = null; - - /** - * @var int - */ - protected $_offset = null; - - /** - * Construct Dataset Table from Zend_Db_Table object - * - * @param Zend_Db_Table_Abstract $table - * @param string|Zend_Db_Select|null $where - * @param string|null $order - * @param int $count - * @param int $offset - */ - public function __construct(Zend_Db_Table_Abstract $table, $where=null, $order=null, $count=null, $offset=null) - { - $this->tableName = $table->info('name'); - $this->_columns = $table->info('cols'); - - $this->_table = $table; - $this->_where = $where; - $this->_order = $order; - $this->_count = $count; - $this->_offset = $offset; - } - - /** - * Lazy load data via table fetchAll() method. - * - * @return void - */ - protected function loadData() - { - if ($this->data === null) { - $this->data = $this->_table->fetchAll( - $this->_where, $this->_order, $this->_count, $this->_offset - ); - if($this->data instanceof Zend_Db_Table_Rowset_Abstract) { - $this->data = $this->data->toArray(); - } - } - } - - /** - * Create Table Metadata object - */ - protected function createTableMetaData() - { - if ($this->tableMetaData === NULL) { - $this->loadData(); - $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $this->_columns); - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/DataSet/DbTableDataSet.php b/lib/Zend/Test/PHPUnit/Db/DataSet/DbTableDataSet.php deleted file mode 100644 index 52cf43e5c5a..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/DataSet/DbTableDataSet.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_DbTable - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/DbTable.php"; - -/** - * Aggregate several Zend_Db_Table instances into a dataset. - * - * @uses Zend_Db_Table - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var array - */ - protected $tables = array(); - - /** - * Add a Table dataset representation by specifiying an arbitrary select query. - * - * By default a select * will be done on the given tablename. - * - * @param Zend_Db_Table_Abstract $table - * @param string $where - * @param string $order - * @param string $count - * @param string $offset - */ - public function addTable(Zend_Db_Table_Abstract $table, $where = null, $order = null, $count = null, $offset = null) - { - $tableName = $table->info('name'); - $this->tables[$tableName] = new Zend_Test_PHPUnit_Db_DataSet_DbTable($table, $where, $order, $count, $offset); - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DB_TableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } - - /** - * Returns a table object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DB_Table - */ - public function getTable($tableName) - { - if (!isset($this->tables[$tableName])) { - throw new InvalidArgumentException("$tableName is not a table in the current database."); - } - - return $this->tables[$tableName]; - } - - /** - * Returns a list of table names for the database - * - * @return Array - */ - public function getTableNames() - { - return array_keys($this->tables); - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/DataSet/QueryDataSet.php b/lib/Zend/Test/PHPUnit/Db/DataSet/QueryDataSet.php deleted file mode 100644 index 3e3251c3e4b..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/DataSet/QueryDataSet.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_DataSet_QueryTable - */ -#require_once "Zend/Test/PHPUnit/Db/DataSet/QueryTable.php"; - -/** - * @see Zend_Db_Select - */ -#require_once "Zend/Db/Select.php"; - -/** - * Uses several query strings or Zend_Db_Select objects to form a dataset of tables for assertion with other datasets. - * - * @uses PHPUnit_Extensions_Database_DataSet_QueryDataSet - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_DataSet_QueryDataSet extends PHPUnit_Extensions_Database_DataSet_QueryDataSet -{ - /** - * Creates a new dataset using the given database connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - if( !($databaseConnection instanceof Zend_Test_PHPUnit_Db_Connection) ) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Zend_Test_PHPUnit_Db_DataSet_QueryDataSet only works with Zend_Test_PHPUnit_Db_Connection connections-"); - } - $this->databaseConnection = $databaseConnection; - } - - /** - * Add a Table dataset representation by specifiying an arbitrary select query. - * - * By default a select * will be done on the given tablename. - * - * @param string $tableName - * @param string|Zend_Db_Select $query - */ - public function addTable($tableName, $query = NULL) - { - if ($query === NULL) { - $query = $this->databaseConnection->getConnection()->select(); - $query->from($tableName, Zend_Db_Select::SQL_WILDCARD); - } - - if($query instanceof Zend_Db_Select) { - $query = $query->__toString(); - } - - $this->tables[$tableName] = new Zend_Test_PHPUnit_Db_DataSet_QueryTable($tableName, $query, $this->databaseConnection); - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/DataSet/QueryTable.php b/lib/Zend/Test/PHPUnit/Db/DataSet/QueryTable.php deleted file mode 100644 index cfa5e600c70..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/DataSet/QueryTable.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Represent a PHPUnit Database Extension table with Queries using a Zend_Db adapter for assertion against other tables. - * - * @uses PHPUnit_Extensions_Database_DataSet_QueryTable - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_DataSet_QueryTable extends PHPUnit_Extensions_Database_DataSet_QueryTable -{ - /** - * Creates a new database query table object. - * - * @param string $tableName - * @param string $query - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - * @throws Zend_Test_PHPUnit_Db_Exception - */ - public function __construct($tableName, $query, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - if( !($databaseConnection instanceof Zend_Test_PHPUnit_Db_Connection) ) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Zend_Test_PHPUnit_Db_DataSet_QueryTable only works with Zend_Test_PHPUnit_Db_Connection connections-"); - } - parent::__construct($tableName, $query, $databaseConnection); - } - - /** - * Load data from the database. - * - * @return void - */ - protected function loadData() - { - if($this->data === null) { - $stmt = $this->databaseConnection->getConnection()->query($this->query); - $this->data = $stmt->fetchAll(Zend_Db::FETCH_ASSOC); - } - } - - /** - * Create Table Metadata - */ - protected function createTableMetaData() - { - if ($this->tableMetaData === NULL) - { - $this->loadData(); - $keys = array(); - if(count($this->data) > 0) { - $keys = array_keys($this->data[0]); - } - $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData( - $this->tableName, $keys - ); - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/Exception.php b/lib/Zend/Test/PHPUnit/Db/Exception.php deleted file mode 100644 index 818fc04ed31..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Exception - */ -#require_once "Zend/Exception.php"; - -/** - * Exception for Zend_Test_PHPUnit_Database package - * - * @uses Zend_Exception - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Exception extends Zend_Exception -{ -} diff --git a/lib/Zend/Test/PHPUnit/Db/Metadata/Generic.php b/lib/Zend/Test/PHPUnit/Db/Metadata/Generic.php deleted file mode 100644 index 3f0a5c4370a..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Metadata/Generic.php +++ /dev/null @@ -1,182 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Db_Adapter_Abstract - */ -#require_once "Zend/Db/Adapter/Abstract.php"; - -/** - * Generic Metadata accessor for the Zend_Db adapters - * - * @uses PHPUnit_Extensions_Database_DB_IMetaData - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Metadata_Generic implements PHPUnit_Extensions_Database_DB_IMetaData -{ - /** - * Zend_Db Connection - * - * @var Zend_Db_Adapter_Abstract - */ - protected $_connection; - - /** - * Schemaname - * - * @var string - */ - protected $_schema; - - /** - * Cached Table metadata - * - * @var array - */ - protected $_tableMetadata = array(); - - /** - * Creates a new database meta data object using the given pdo connection - * and schema name. - * - * @param Zend_Db_Adapter_Abstract $db - * @param string $schema - */ - public final function __construct(Zend_Db_Adapter_Abstract $db, $schema) - { - $this->_connection = $db; - $this->_schema = $schema; - } - - /** - * List Tables - * - * @return array - */ - public function getTableNames() - { - return $this->_connection->listTables(); - } - - /** - * Get Table information - * - * @param string $tableName - * @return array - */ - protected function getTableDescription($tableName) - { - if(!isset($this->_tableMetadata[$tableName])) { - $this->_tableMetadata[$tableName] = $this->_connection->describeTable($tableName); - } - return $this->_tableMetadata[$tableName]; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - $tableMeta = $this->getTableDescription($tableName); - $columns = array_keys($tableMeta); - return $columns; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - $tableMeta = $this->getTableDescription($tableName); - - $primaryColumnNames = array(); - foreach($tableMeta AS $column) { - if($column['PRIMARY'] == true) { - $primaryColumnNames[] = $column['COLUMN_NAME']; - } - } - return $primaryColumnNames; - } - - /** - * Returns the name of the default schema. - * - * @return string - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object) - { - return $this->_connection->quoteIdentifier($object); - } - - /** - * Returns true if the rdbms allows cascading - * - * @return bool - */ - public function allowsCascading() - { - return false; - } - - /** - * Disables primary keys if rdbms does not allow setting them otherwise - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName) - { - // Implemented only to match new DBUnit interface - } - - /** - * Reenables primary keys after they have been disabled - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName) - { - // Implemented only to match new DBUnit interface - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/Operation/DeleteAll.php b/lib/Zend/Test/PHPUnit/Db/Operation/DeleteAll.php deleted file mode 100644 index 9a42c03037a..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Operation/DeleteAll.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_Connection - */ -#require_once "Zend/Test/PHPUnit/Db/Connection.php"; - -/** - * Delete All Operation that can be executed on set up or tear down of a database tester. - * - * @uses PHPUnit_Extensions_Database_Operation_IDatabaseOperation - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Operation_DeleteAll implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - /** - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - if(!($connection instanceof Zend_Test_PHPUnit_Db_Connection)) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Not a valid Zend_Test_PHPUnit_Db_Connection instance, ".get_class($connection)." given!"); - } - - foreach ($dataSet as $table) { - try { - $tableName = $table->getTableMetaData()->getTableName(); - $connection->getConnection()->delete($tableName); - } catch (Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception('DELETEALL', 'DELETE FROM '.$tableName.'', array(), $table, $e->getMessage()); - } - } - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/Operation/Insert.php b/lib/Zend/Test/PHPUnit/Db/Operation/Insert.php deleted file mode 100644 index a6f22b37018..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Operation/Insert.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_Connection - */ -#require_once "Zend/Test/PHPUnit/Db/Connection.php"; - -/** - * Operation for Inserting on setup or teardown of a database tester. - * - * @uses PHPUnit_Extensions_Database_Operation_IDatabaseOperation - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Operation_Insert implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - /** - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - if(!($connection instanceof Zend_Test_PHPUnit_Db_Connection)) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Not a valid Zend_Test_PHPUnit_Db_Connection instance, ".get_class($connection)." given!"); - } - - $databaseDataSet = $connection->createDataSet(); - - $dsIterator = $dataSet->getIterator(); - - foreach($dsIterator as $table) { - $tableName = $table->getTableMetaData()->getTableName(); - - $db = $connection->getConnection(); - for($i = 0; $i < $table->getRowCount(); $i++) { - $values = $this->buildInsertValues($table, $i); - try { - $db->insert($tableName, $values); - } catch (Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception("INSERT", "INSERT INTO ".$tableName." [..]", $values, $table, $e->getMessage()); - } - } - } - } - - /** - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - * @param int $rowNum - * @return array - */ - protected function buildInsertValues(PHPUnit_Extensions_Database_DataSet_ITable $table, $rowNum) - { - $values = array(); - foreach($table->getTableMetaData()->getColumns() as $columnName) { - $values[$columnName] = $table->getValue($rowNum, $columnName); - } - return $values; - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/Operation/Truncate.php b/lib/Zend/Test/PHPUnit/Db/Operation/Truncate.php deleted file mode 100644 index c44e9fb31c6..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/Operation/Truncate.php +++ /dev/null @@ -1,110 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_Connection - */ -#require_once "Zend/Test/PHPUnit/Db/Connection.php"; - -/** - * Operation for Truncating on setup or teardown of a database tester. - * - * @uses PHPUnit_Extensions_Database_Operation_IDatabaseOperation - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - /** - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - * @return void - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - if(!($connection instanceof Zend_Test_PHPUnit_Db_Connection)) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Not a valid Zend_Test_PHPUnit_Db_Connection instance, ".get_class($connection)." given!"); - } - - foreach ($dataSet->getReverseIterator() AS $table) { - try { - $tableName = $table->getTableMetaData()->getTableName(); - $this->_truncate($connection->getConnection(), $tableName); - } catch (Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception('TRUNCATE', 'TRUNCATE '.$tableName.'', array(), $table, $e->getMessage()); - } - } - } - - /** - * Truncate a given table. - * - * @param Zend_Db_Adapter_Abstract $db - * @param string $tableName - * @return void - */ - protected function _truncate(Zend_Db_Adapter_Abstract $db, $tableName) - { - $tableName = $db->quoteIdentifier($tableName, true); - if($db instanceof Zend_Db_Adapter_Pdo_Sqlite) { - $db->query('DELETE FROM '.$tableName); - } else if($db instanceof Zend_Db_Adapter_Db2) { - /*if(strstr(PHP_OS, "WIN")) { - $file = tempnam(sys_get_temp_dir(), "zendtestdbibm_"); - file_put_contents($file, ""); - $db->query('IMPORT FROM '.$file.' OF DEL REPLACE INTO '.$tableName); - unlink($file); - } else { - $db->query('IMPORT FROM /dev/null OF DEL REPLACE INTO '.$tableName); - }*/ - #require_once "Zend/Exception.php"; - throw Zend_Exception("IBM Db2 TRUNCATE not supported."); - } else if($this->_isMssqlOrOracle($db)) { - $db->query('TRUNCATE TABLE '.$tableName); - } else if($db instanceof Zend_Db_Adapter_Pdo_Pgsql) { - $db->query('TRUNCATE '.$tableName.' CASCADE'); - } else { - $db->query('TRUNCATE '.$tableName); - } - } - - /** - * Detect if an adapter is for Mssql or Oracle Databases. - * - * @param Zend_Db_Adapter_Abstract $db - * @return bool - */ - private function _isMssqlOrOracle($db) - { - return ( - $db instanceof Zend_Db_Adapter_Pdo_Mssql || - $db instanceof Zend_Db_Adapter_Sqlsrv || - $db instanceof Zend_Db_Adapter_Pdo_Oci || - $db instanceof Zend_Db_Adapter_Oracle - ); - } -} diff --git a/lib/Zend/Test/PHPUnit/Db/SimpleTester.php b/lib/Zend/Test/PHPUnit/Db/SimpleTester.php deleted file mode 100644 index da9676a7597..00000000000 --- a/lib/Zend/Test/PHPUnit/Db/SimpleTester.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Test_PHPUnit_Db_Operation_Truncate - */ -#require_once "Zend/Test/PHPUnit/Db/Operation/Truncate.php"; - -/** - * @see Zend_Test_PHPUnit_Db_Operation_Insert - */ -#require_once "Zend/Test/PHPUnit/Db/Operation/Insert.php"; - -/** - * Simple Tester for Database Tests when the Abstract Test Case cannot be used. - * - * @uses PHPUnit_Extensions_Database_DefaultTester - * @category Zend - * @package Zend_Test - * @subpackage PHPUnit - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Test_PHPUnit_Db_SimpleTester extends PHPUnit_Extensions_Database_DefaultTester -{ - /** - * Creates a new default database tester using the given connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - if(!($connection instanceof Zend_Test_PHPUnit_Db_Connection)) { - #require_once "Zend/Test/PHPUnit/Db/Exception.php"; - throw new Zend_Test_PHPUnit_Db_Exception("Not a valid Zend_Test_PHPUnit_Db_Connection instance, ".get_class($connection)." given!"); - } - - $this->connection = $connection; - $this->setUpOperation = new PHPUnit_Extensions_Database_Operation_Composite(array( - new Zend_Test_PHPUnit_Db_Operation_Truncate(), - new Zend_Test_PHPUnit_Db_Operation_Insert(), - )); - $this->tearDownOperation = PHPUnit_Extensions_Database_Operation_Factory::NONE(); - } - - /** - * Set Up the database using the given Dataset and the SetUp strategy "Truncate, then Insert" - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function setUpDatabase(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - $this->setDataSet($dataSet); - $this->onSetUp(); - } -} diff --git a/lib/Zend/Text/Exception.php b/lib/Zend/Text/Exception.php deleted file mode 100644 index 1eefdfa7b25..00000000000 --- a/lib/Zend/Text/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Exception - */ -#require_once 'Zend/Exception.php'; - -/** - * Exception class for Zend_Text - * - * @category Zend - * @package Zend_Text - * @uses Zend_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Exception extends Zend_Exception -{ -} diff --git a/lib/Zend/Text/Figlet.php b/lib/Zend/Text/Figlet.php deleted file mode 100644 index b0fd7daa62c..00000000000 --- a/lib/Zend/Text/Figlet.php +++ /dev/null @@ -1,1232 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Figlet - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Text_Figlet is a PHP implementation of FIGlet - * - * @category Zend - * @package Zend_Text_Figlet - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Figlet -{ - /** - * Smush2 layout modes - */ - const SM_EQUAL = 0x01; - const SM_LOWLINE = 0x02; - const SM_HIERARCHY = 0x04; - const SM_PAIR = 0x08; - const SM_BIGX = 0x10; - const SM_HARDBLANK = 0x20; - const SM_KERN = 0x40; - const SM_SMUSH = 0x80; - - /** - * Smush mode override modes - */ - const SMO_NO = 0; - const SMO_YES = 1; - const SMO_FORCE = 2; - - /** - * Justifications - */ - const JUSTIFICATION_LEFT = 0; - const JUSTIFICATION_CENTER = 1; - const JUSTIFICATION_RIGHT = 2; - - /** - * Write directions - */ - const DIRECTION_LEFT_TO_RIGHT = 0; - const DIRECTION_RIGHT_TO_LEFT = 1; - - /** - * Magic fontfile number - */ - const FONTFILE_MAGIC_NUMBER = 'flf2'; - - /** - * Array containing all characters of the current font - * - * @var array - */ - protected $_charList = array(); - - /** - * Indicates if a font was loaded yet - * - * @var boolean - */ - protected $_fontLoaded = false; - - /** - * Latin-1 codes for German letters, respectively: - * - * LATIN CAPITAL LETTER A WITH DIAERESIS = A-umlaut - * LATIN CAPITAL LETTER O WITH DIAERESIS = O-umlaut - * LATIN CAPITAL LETTER U WITH DIAERESIS = U-umlaut - * LATIN SMALL LETTER A WITH DIAERESIS = a-umlaut - * LATIN SMALL LETTER O WITH DIAERESIS = o-umlaut - * LATIN SMALL LETTER U WITH DIAERESIS = u-umlaut - * LATIN SMALL LETTER SHARP S = ess-zed - * - * @var array - */ - protected $_germanChars = array(196, 214, 220, 228, 246, 252, 223); - - /** - * Output width, defaults to 80. - * - * @var integer - */ - protected $_outputWidth = 80; - - /** - * Hard blank character - * - * @var string - */ - protected $_hardBlank; - - /** - * Height of the characters - * - * @var integer - */ - protected $_charHeight; - - /** - * Max length of any character - * - * @var integer - */ - protected $_maxLength; - - /** - * Smush mode - * - * @var integer - */ - protected $_smushMode = 0; - - /** - * Smush defined by the font - * - * @var integer - */ - protected $_fontSmush = 0; - - /** - * Smush defined by the user - * - * @var integer - */ - protected $_userSmush = 0; - - /** - * Wether to handle paragraphs || not - * - * @var boolean - */ - protected $_handleParagraphs = false; - - /** - * Justification for the text, according to $_outputWidth - * - * For using font default, this parameter should be null, else one of - * the values of Zend_Text_Figlet::JUSTIFICATION_* - * - * @var integer - */ - protected $_justification = null; - - /** - * Direction of text-writing, namely right to left - * - * For using font default, this parameter should be null, else one of - * the values of Zend_Text_Figlet::DIRECTION_* - * - * @var integer - */ - protected $_rightToLeft = null; - - /** - * Override font file smush layout - * - * @var integer - */ - protected $_smushOverride = 0; - - /** - * Options of the current font - * - * @var array - */ - protected $_fontOptions = array(); - - /** - * Previous character width - * - * @var integer - */ - protected $_previousCharWidth = 0; - - /** - * Current character width - * - * @var integer - */ - protected $_currentCharWidth = 0; - - /** - * Current outline length - * - * @var integer - */ - protected $_outlineLength = 0; - - /** - * Maxmimum outline length - * - * @var integer - */ - protected $_outlineLengthLimit = 0; - - /** - * In character line - * - * @var string - */ - protected $_inCharLine; - - /** - * In character line length - * - * @var integer - */ - protected $_inCharLineLength = 0; - - /** - * Maximum in character line length - * - * @var integer - */ - protected $_inCharLineLengthLimit = 0; - - /** - * Current char - * - * @var array - */ - protected $_currentChar = null; - - /** - * Current output line - * - * @var array - */ - protected $_outputLine; - - /** - * Current output - * - * @var string - */ - protected $_output; - - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'config', - ); - - /** - * Instantiate the FIGlet with a specific font. If no font is given, the - * standard font is used. You can also supply multiple options via - * the $options variable, which can either be an array or an instance of - * Zend_Config. - * - * @param array|Zend_Config $options Options for the output - */ - public function __construct($options = null) - { - // Set options - if (is_array($options)) { - $this->setOptions($options); - } else if ($options instanceof Zend_Config) { - $this->setConfig($options); - } - - // If no font was defined, load default font - if (!$this->_fontLoaded) { - $this->_loadFont(dirname(__FILE__) . '/Figlet/zend-framework.flf'); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for Zend_Text_Figlet - * @return Zend_Text_Figlet - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . ucfirst($key); - if (method_exists($this, $method)) { - $this->$method($value); - } - } - return $this; - } - - /** - * Set options from config object - * - * @param Zend_Config $config Configuration for Zend_Text_Figlet - * @return Zend_Text_Figlet - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Set a font to use - * - * @param string $font Path to the font - * @return Zend_Text_Figlet - */ - public function setFont($font) - { - $this->_loadFont($font); - return $this; - } - - /** - * Set handling of paragraphs - * - * @param boolean $handleParagraphs Wether to handle paragraphs or not - * @return Zend_Text_Figlet - */ - public function setHandleParagraphs($handleParagraphs) - { - $this->_handleParagraphs = (bool) $handleParagraphs; - return $this; - } - - /** - * Set the justification. 0 stands for left aligned, 1 for centered and 2 - * for right aligned. - * - * @param integer $justification Justification of the output text - * @return Zend_Text_Figlet - */ - public function setJustification($justification) - { - $this->_justification = min(3, max(0, (int) $justification)); - return $this; - } - - /** - * Set the output width - * - * @param integer $outputWidth Output with which should be used for word - * wrapping and justification - * @return Zend_Text_Figlet - */ - public function setOutputWidth($outputWidth) - { - $this->_outputWidth = max(1, (int) $outputWidth); - return $this; - } - - /** - * Set right to left mode. For writing from left to right, use - * Zend_Text_Figlet::DIRECTION_LEFT_TO_RIGHT. For writing from right to left, - * use Zend_Text_Figlet::DIRECTION_RIGHT_TO_LEFT. - * - * @param integer $rightToLeft Right-to-left mode - * @return Zend_Text_Figlet - */ - public function setRightToLeft($rightToLeft) - { - $this->_rightToLeft = min(1, max(0, (int) $rightToLeft)); - return $this; - } - - /** - * Set the smush mode. - * - * Use one of the constants of Zend_Text_Figlet::SM_*, you may combine them. - * - * @param integer $smushMode Smush mode to use for generating text - * @return Zend_Text_Figlet - */ - public function setSmushMode($smushMode) - { - $smushMode = (int) $smushMode; - - if ($smushMode < -1) { - $this->_smushOverride = self::SMO_NO; - } else { - if ($smushMode === 0) { - $this->_userSmush = self::SM_KERN; - } else if ($smushMode === -1) { - $this->_userSmush = 0; - } else { - $this->_userSmush = (($smushMode & 63) | self::SM_SMUSH); - } - - $this->_smushOverride = self::SMO_YES; - } - - $this->_setUsedSmush(); - - return $this; - } - - /** - * Render a FIGlet text - * - * @param string $text Text to convert to a figlet text - * @param string $encoding Encoding of the input string - * @throws InvalidArgumentException When $text is not a string - * @throws Zend_Text_Figlet_Exception When $text it not properly encoded - * @return string - */ - public function render($text, $encoding = 'UTF-8') - { - if (!is_string($text)) { - throw new InvalidArgumentException('$text must be a string'); - } - - if ($encoding !== 'UTF-8') { - $text = iconv($encoding, 'UTF-8', $text); - } - - $this->_output = ''; - $this->_outputLine = array(); - - $this->_clearLine(); - - $this->_outlineLengthLimit = ($this->_outputWidth - 1); - $this->_inCharLineLengthLimit = ($this->_outputWidth * 4 + 100); - - $wordBreakMode = 0; - $lastCharWasEol = false; - $textLength = @iconv_strlen($text, 'UTF-8'); - - if ($textLength === false) { - #require_once 'Zend/Text/Figlet/Exception.php'; - throw new Zend_Text_Figlet_Exception('$text is not encoded with ' . $encoding); - } - - for ($charNum = 0; $charNum < $textLength; $charNum++) { - // Handle paragraphs - $char = iconv_substr($text, $charNum, 1, 'UTF-8'); - - if ($char === "\n" && $this->_handleParagraphs && !$lastCharWasEol) { - $nextChar = iconv_substr($text, ($charNum + 1), 1, 'UTF-8'); - if (!$nextChar) { - $nextChar = null; - } - - $char = (ctype_space($nextChar)) ? "\n" : ' '; - } - - $lastCharWasEol = (ctype_space($char) && $char !== "\t" && $char !== ' '); - - if (ctype_space($char)) { - $char = ($char === "\t" || $char === ' ') ? ' ': "\n"; - } - - // Skip unprintable characters - $ordChar = $this->_uniOrd($char); - if (($ordChar > 0 && $ordChar < 32 && $char !== "\n") || $ordChar === 127) { - continue; - } - - // Build the character - // Note: The following code is complex and thoroughly tested. - // Be careful when modifying! - do { - $charNotAdded = false; - - if ($wordBreakMode === -1) { - if ($char === ' ') { - break; - } else if ($char === "\n") { - $wordBreakMode = 0; - break; - } - - $wordBreakMode = 0; - } - - if ($char === "\n") { - $this->_appendLine(); - $wordBreakMode = false; - } else if ($this->_addChar($char)) { - if ($char !== ' ') { - $wordBreakMode = ($wordBreakMode >= 2) ? 3: 1; - } else { - $wordBreakMode = ($wordBreakMode > 0) ? 2: 0; - } - } else if ($this->_outlineLength === 0) { - for ($i = 0; $i < $this->_charHeight; $i++) { - if ($this->_rightToLeft === 1 && $this->_outputWidth > 1) { - $offset = (strlen($this->_currentChar[$i]) - $this->_outlineLengthLimit); - $this->_putString(substr($this->_currentChar[$i], $offset)); - } else { - $this->_putString($this->_currentChar[$i]); - } - } - - $wordBreakMode = -1; - } else if ($char === ' ') { - if ($wordBreakMode === 2) { - $this->_splitLine(); - } else { - $this->_appendLine(); - } - - $wordBreakMode = -1; - } else { - if ($wordBreakMode >= 2) { - $this->_splitLine(); - } else { - $this->_appendLine(); - } - - $wordBreakMode = ($wordBreakMode === 3) ? 1 : 0; - $charNotAdded = true; - } - } while ($charNotAdded); - } - - if ($this->_outlineLength !== 0) { - $this->_appendLine(); - } - - return $this->_output; - } - - /** - * Puts the given string, substituting blanks for hardblanks. If outputWidth - * is 1, puts the entire string; otherwise puts at most outputWidth - 1 - * characters. Puts a newline at the end of the string. The string is left- - * justified, centered or right-justified (taking outputWidth as the screen - * width) if justification is 0, 1 or 2 respectively. - * - * @param string $string The string to add to the output - * @return void - */ - protected function _putString($string) - { - $length = strlen($string); - - if ($this->_outputWidth > 1) { - if ($length > ($this->_outputWidth - 1)) { - $length = ($this->_outputWidth - 1); - } - - if ($this->_justification > 0) { - for ($i = 1; - ((3 - $this->_justification) * $i + $length + $this->_justification - 2) < $this->_outputWidth; - $i++) { - $this->_output .= ' '; - } - } - } - - $this->_output .= str_replace($this->_hardBlank, ' ', $string) . "\n"; - } - - /** - * Appends the current line to the output - * - * @return void - */ - protected function _appendLine() - { - for ($i = 0; $i < $this->_charHeight; $i++) { - $this->_putString($this->_outputLine[$i]); - } - - $this->_clearLine(); - } - - /** - * Splits inCharLine at the last word break (bunch of consecutive blanks). - * Makes a new line out of the first part and appends it using appendLine(). - * Makes a new line out of the second part and returns. - * - * @return void - */ - protected function _splitLine() - { - $gotSpace = false; - for ($i = ($this->_inCharLineLength - 1); $i >= 0; $i--) { - if (!$gotSpace && $this->_inCharLine[$i] === ' ') { - $gotSpace = true; - $lastSpace = $i; - } - - if ($gotSpace && $this->_inCharLine[$i] !== ' ') { - break; - } - } - - $firstLength = ($i + 1); - $lastLength = ($this->_inCharLineLength - $lastSpace - 1); - - $firstPart = ''; - for ($i = 0; $i < $firstLength; $i++) { - $firstPart[$i] = $this->_inCharLine[$i]; - } - - $lastPart = ''; - for ($i = 0; $i < $lastLength; $i++) { - $lastPart[$i] = $this->_inCharLine[($lastSpace + 1 + $i)]; - } - - $this->_clearLine(); - - for ($i = 0; $i < $firstLength; $i++) { - $this->_addChar($firstPart[$i]); - } - - $this->_appendLine(); - - for ($i = 0; $i < $lastLength; $i++) { - $this->_addChar($lastPart[$i]); - } - } - - /** - * Clears the current line - * - * @return void - */ - protected function _clearLine() - { - for ($i = 0; $i < $this->_charHeight; $i++) { - $this->_outputLine[$i] = ''; - } - - $this->_outlineLength = 0; - $this->_inCharLineLength = 0; - } - - /** - * Attempts to add the given character onto the end of the current line. - * Returns true if this can be done, false otherwise. - * - * @param string $char Character which to add to the output - * @return boolean - */ - protected function _addChar($char) - { - $this->_getLetter($char); - - if ($this->_currentChar === null) { - return true; - } - - $smushAmount = $this->_smushAmount(); - - if (($this->_outlineLength + $this->_currentCharWidth - $smushAmount) > $this->_outlineLengthLimit - || ($this->_inCharLineLength + 1) > $this->_inCharLineLengthLimit) { - return false; - } - - $tempLine = ''; - for ($row = 0; $row < $this->_charHeight; $row++) { - if ($this->_rightToLeft === 1) { - $tempLine = $this->_currentChar[$row]; - - for ($k = 0; $k < $smushAmount; $k++) { - $position = ($this->_currentCharWidth - $smushAmount + $k); - $tempLine[$position] = $this->_smushem($tempLine[$position], $this->_outputLine[$row][$k]); - } - - $this->_outputLine[$row] = $tempLine . substr($this->_outputLine[$row], $smushAmount); - } else { - for ($k = 0; $k < $smushAmount; $k++) { - if (($this->_outlineLength - $smushAmount + $k) < 0) { - continue; - } - - $position = ($this->_outlineLength - $smushAmount + $k); - if (isset($this->_outputLine[$row][$position])) { - $leftChar = $this->_outputLine[$row][$position]; - } else { - $leftChar = null; - } - - $this->_outputLine[$row][$position] = $this->_smushem($leftChar, $this->_currentChar[$row][$k]); - } - - $this->_outputLine[$row] .= substr($this->_currentChar[$row], $smushAmount); - } - } - - $this->_outlineLength = strlen($this->_outputLine[0]); - $this->_inCharLine[$this->_inCharLineLength++] = $char; - - return true; - } - - /** - * Gets the requested character and sets current and previous char width. - * - * @param string $char The character from which to get the letter of - * @return void - */ - protected function _getLetter($char) - { - if (array_key_exists($this->_uniOrd($char), $this->_charList)) { - $this->_currentChar = $this->_charList[$this->_uniOrd($char)]; - $this->_previousCharWidth = $this->_currentCharWidth; - $this->_currentCharWidth = strlen($this->_currentChar[0]); - } else { - $this->_currentChar = null; - } - } - - /** - * Returns the maximum amount that the current character can be smushed into - * the current line. - * - * @return integer - */ - protected function _smushAmount() - { - if (($this->_smushMode & (self::SM_SMUSH | self::SM_KERN)) === 0) { - return 0; - } - - $maxSmush = $this->_currentCharWidth; - $amount = $maxSmush; - - for ($row = 0; $row < $this->_charHeight; $row++) { - if ($this->_rightToLeft === 1) { - $charbd = strlen($this->_currentChar[$row]); - while (true) { - if (!isset($this->_currentChar[$row][$charbd])) { - $leftChar = null; - } else { - $leftChar = $this->_currentChar[$row][$charbd]; - } - - if ($charbd > 0 && ($leftChar === null || $leftChar == ' ')) { - $charbd--; - } else { - break; - } - } - - $linebd = 0; - while (true) { - if (!isset($this->_outputLine[$row][$linebd])) { - $rightChar = null; - } else { - $rightChar = $this->_outputLine[$row][$linebd]; - } - - if ($rightChar === ' ') { - $linebd++; - } else { - break; - } - } - - $amount = ($linebd + $this->_currentCharWidth - 1 - $charbd); - } else { - $linebd = strlen($this->_outputLine[$row]); - while (true) { - if (!isset($this->_outputLine[$row][$linebd])) { - $leftChar = null; - } else { - $leftChar = $this->_outputLine[$row][$linebd]; - } - - if ($linebd > 0 && ($leftChar === null || $leftChar == ' ')) { - $linebd--; - } else { - break; - } - } - - $charbd = 0; - while (true) { - if (!isset($this->_currentChar[$row][$charbd])) { - $rightChar = null; - } else { - $rightChar = $this->_currentChar[$row][$charbd]; - } - - if ($rightChar === ' ') { - $charbd++; - } else { - break; - } - } - - $amount = ($charbd + $this->_outlineLength - 1 - $linebd); - } - - if (empty($leftChar) || $leftChar === ' ') { - $amount++; - } else if (!empty($rightChar)) { - if ($this->_smushem($leftChar, $rightChar) !== null) { - $amount++; - } - } - - $maxSmush = min($amount, $maxSmush); - } - - return $maxSmush; - } - - /** - * Given two characters, attempts to smush them into one, according to the - * current smushmode. Returns smushed character or false if no smushing can - * be done. - * - * Smushmode values are sum of following (all values smush blanks): - * - * 1: Smush equal chars (not hardblanks) - * 2: Smush '_' with any char in hierarchy below - * 4: hierarchy: "|", "/\", "[]", "{}", "()", "<>" - * Each class in hier. can be replaced by later class. - * 8: [ + ] -> |, { + } -> |, ( + ) -> | - * 16: / + \ -> X, > + < -> X (only in that order) - * 32: hardblank + hardblank -> hardblank - * - * @param string $leftChar Left character to smush - * @param string $rightChar Right character to smush - * @return string - */ - protected function _smushem($leftChar, $rightChar) - { - if ($leftChar === ' ') { - return $rightChar; - } - - if ($rightChar === ' ') { - return $leftChar; - } - - if ($this->_previousCharWidth < 2 || $this->_currentCharWidth < 2) { - // Disallows overlapping if the previous character or the current - // character has a width of one or zero. - return null; - } - - if (($this->_smushMode & self::SM_SMUSH) === 0) { - // Kerning - return null; - } - - if (($this->_smushMode & 63) === 0) { - // This is smushing by universal overlapping - if ($leftChar === ' ') { - return $rightChar; - } else if ($rightChar === ' ') { - return $leftChar; - } else if ($leftChar === $this->_hardBlank) { - return $rightChar; - } else if ($rightChar === $this->_hardBlank) { - return $rightChar; - } else if ($this->_rightToLeft === 1) { - return $leftChar; - } else { - // Occurs in the absence of above exceptions - return $rightChar; - } - } - - if (($this->_smushMode & self::SM_HARDBLANK) > 0) { - if ($leftChar === $this->_hardBlank && $rightChar === $this->_hardBlank) { - return $leftChar; - } - } - - if ($leftChar === $this->_hardBlank && $rightChar === $this->_hardBlank) { - return null; - } - - if (($this->_smushMode & self::SM_EQUAL) > 0) { - if ($leftChar === $rightChar) { - return $leftChar; - } - } - - if (($this->_smushMode & self::SM_LOWLINE) > 0) { - if ($leftChar === '_' && strchr('|/\\[]{}()<>', $rightChar) !== false) { - return $rightChar; - } else if ($rightChar === '_' && strchr('|/\\[]{}()<>', $leftChar) !== false) { - return $leftChar; - } - } - - if (($this->_smushMode & self::SM_HIERARCHY) > 0) { - if ($leftChar === '|' && strchr('/\\[]{}()<>', $rightChar) !== false) { - return $rightChar; - } else if ($rightChar === '|' && strchr('/\\[]{}()<>', $leftChar) !== false) { - return $leftChar; - } else if (strchr('/\\', $leftChar) && strchr('[]{}()<>', $rightChar) !== false) { - return $rightChar; - } else if (strchr('/\\', $rightChar) && strchr('[]{}()<>', $leftChar) !== false) { - return $leftChar; - } else if (strchr('[]', $leftChar) && strchr('{}()<>', $rightChar) !== false) { - return $rightChar; - } else if (strchr('[]', $rightChar) && strchr('{}()<>', $leftChar) !== false) { - return $leftChar; - } else if (strchr('{}', $leftChar) && strchr('()<>', $rightChar) !== false) { - return $rightChar; - } else if (strchr('{}', $rightChar) && strchr('()<>', $leftChar) !== false) { - return $leftChar; - } else if (strchr('()', $leftChar) && strchr('<>', $rightChar) !== false) { - return $rightChar; - } else if (strchr('()', $rightChar) && strchr('<>', $leftChar) !== false) { - return $leftChar; - } - } - - if (($this->_smushMode & self::SM_PAIR) > 0) { - if ($leftChar === '[' && $rightChar === ']') { - return '|'; - } else if ($rightChar === '[' && $leftChar === ']') { - return '|'; - } else if ($leftChar === '{' && $rightChar === '}') { - return '|'; - } else if ($rightChar === '{' && $leftChar === '}') { - return '|'; - } else if ($leftChar === '(' && $rightChar === ')') { - return '|'; - } else if ($rightChar === '(' && $leftChar === ')') { - return '|'; - } - } - - if (($this->_smushMode & self::SM_BIGX) > 0) { - if ($leftChar === '/' && $rightChar === '\\') { - return '|'; - } else if ($rightChar === '/' && $leftChar === '\\') { - return 'Y'; - } else if ($leftChar === '>' && $rightChar === '<') { - return 'X'; - } - } - - return null; - } - - /** - * Load the specified font - * - * @param string $fontFile Font file to load - * @throws Zend_Text_Figlet_Exception When font file was not found - * @throws Zend_Text_Figlet_Exception When GZIP library is required but not found - * @throws Zend_Text_Figlet_Exception When font file is not readable - * @return void - */ - protected function _loadFont($fontFile) - { - // Check if the font file exists - if (!file_exists($fontFile)) { - #require_once 'Zend/Text/Figlet/Exception.php'; - throw new Zend_Text_Figlet_Exception($fontFile . ': Font file not found'); - } - - // Check if gzip support is required - if (substr($fontFile, -3) === '.gz') { - if (!function_exists('gzcompress')) { - #require_once 'Zend/Text/Figlet/Exception.php'; - throw new Zend_Text_Figlet_Exception('GZIP library is required for ' - . 'gzip compressed font files'); - } - - $fontFile = 'compress.zlib://' . $fontFile; - $compressed = true; - } else { - $compressed = false; - } - - // Try to open the file - $fp = fopen($fontFile, 'rb'); - if ($fp === false) { - #require_once 'Zend/Text/Figlet/Exception.php'; - throw new Zend_Text_Figlet_Exception($fontFile . ': Could not open file'); - } - - // If the file is not compressed, lock the stream - if (!$compressed) { - flock($fp, LOCK_SH); - } - - // Get magic - $magic = $this->_readMagic($fp); - - // Get the header - $numsRead = sscanf(fgets($fp, 1000), - '%*c%c %d %*d %d %d %d %d %d', - $this->_hardBlank, - $this->_charHeight, - $this->_maxLength, - $smush, - $cmtLines, - $rightToLeft, - $this->_fontSmush); - - if ($magic !== self::FONTFILE_MAGIC_NUMBER || $numsRead < 5) { - #require_once 'Zend/Text/Figlet/Exception.php'; - throw new Zend_Text_Figlet_Exception($fontFile . ': Not a FIGlet 2 font file'); - } - - // Set default right to left - if ($numsRead < 6) { - $rightToLeft = 0; - } - - // If no smush2, decode smush into smush2 - if ($numsRead < 7) { - if ($smush === 2) { - $this->_fontSmush = self::SM_KERN; - } else if ($smush < 0) { - $this->_fontSmush = 0; - } else { - $this->_fontSmush = (($smush & 31) | self::SM_SMUSH); - } - } - - // Correct char height && maxlength - $this->_charHeight = max(1, $this->_charHeight); - $this->_maxLength = max(1, $this->_maxLength); - - // Give ourselves some extra room - $this->_maxLength += 100; - - // See if we have to override smush settings - $this->_setUsedSmush(); - - // Get left to right value - if ($this->_rightToLeft === null) { - $this->_rightToLeft = $rightToLeft; - } - - // Get justification value - if ($this->_justification === null) { - $this->_justification = (2 * $this->_rightToLeft); - } - - // Skip all comment lines - for ($line = 1; $line <= $cmtLines; $line++) { - $this->_skipToEol($fp); - } - - // Fetch all ASCII characters - for ($asciiCode = 32; $asciiCode < 127; $asciiCode++) { - $this->_charList[$asciiCode] = $this->_loadChar($fp); - } - - // Fetch all german characters - foreach ($this->_germanChars as $uniCode) { - $char = $this->_loadChar($fp); - - if ($char === false) { - fclose($fp); - return; - } - - if (trim(implode('', $char)) !== '') { - $this->_charList[$uniCode] = $char; - } - } - - // At the end fetch all extended characters - while (!feof($fp)) { - // Get the Unicode - list($uniCode) = explode(' ', fgets($fp, 2048)); - - if (empty($uniCode)) { - continue; - } - - // Convert it if required - if (substr($uniCode, 0, 2) === '0x') { - $uniCode = hexdec(substr($uniCode, 2)); - } else if (substr($uniCode, 0, 1) === '0' and - $uniCode !== '0' or - substr($uniCode, 0, 2) === '-0') { - $uniCode = octdec($uniCode); - } else { - $uniCode = (int) $uniCode; - } - - // Now fetch the character - $char = $this->_loadChar($fp); - - if ($char === false) { - fclose($fp); - return; - } - - $this->_charList[$uniCode] = $char; - } - - fclose($fp); - - $this->_fontLoaded = true; - } - - /** - * Set the used smush mode, according to smush override, user smsush and - * font smush. - * - * @return void - */ - protected function _setUsedSmush() - { - if ($this->_smushOverride === self::SMO_NO) { - $this->_smushMode = $this->_fontSmush; - } else if ($this->_smushOverride === self::SMO_YES) { - $this->_smushMode = $this->_userSmush; - } else if ($this->_smushOverride === self::SMO_FORCE) { - $this->_smushMode = ($this->_fontSmush | $this->_userSmush); - } - } - - /** - * Reads a four-character magic string from a stream - * - * @param resource $fp File pointer to the font file - * @return string - */ - protected function _readMagic($fp) - { - $magic = ''; - - for ($i = 0; $i < 4; $i++) { - $magic .= fgetc($fp); - } - - return $magic; - } - - /** - * Skip a stream to the end of line - * - * @param resource $fp File pointer to the font file - * @return void - */ - protected function _skipToEol($fp) - { - $dummy = fgetc($fp); - while ($dummy !== false && !feof($fp)) { - if ($dummy === "\n") { - return; - } - - if ($dummy === "\r") { - $dummy = fgetc($fp); - - if (!feof($fp) && $dummy !== "\n") { - fseek($fp, -1, SEEK_SET); - } - - return; - } - - $dummy = fgetc($fp); - } - } - - /** - * Load a single character from the font file - * - * @param resource $fp File pointer to the font file - * @return array - */ - protected function _loadChar($fp) - { - $char = array(); - - for ($i = 0; $i < $this->_charHeight; $i++) { - if (feof($fp)) { - return false; - } - - $line = rtrim(fgets($fp, 2048), "\r\n"); - - if (preg_match('#(.)\\1?$#', $line, $result) === 1) { - $line = str_replace($result[1], '', $line); - } - - $char[] = $line; - } - - return $char; - } - - /** - * Unicode compatible ord() method - * - * @param string $c The char to get the value from - * @return integer - */ - protected function _uniOrd($c) - { - $h = ord($c[0]); - - if ($h <= 0x7F) { - $ord = $h; - } else if ($h < 0xC2) { - $ord = 0; - } else if ($h <= 0xDF) { - $ord = (($h & 0x1F) << 6 | (ord($c[1]) & 0x3F)); - } else if ($h <= 0xEF) { - $ord = (($h & 0x0F) << 12 | (ord($c[1]) & 0x3F) << 6 | (ord($c[2]) & 0x3F)); - } else if ($h <= 0xF4) { - $ord = (($h & 0x0F) << 18 | (ord($c[1]) & 0x3F) << 12 | - (ord($c[2]) & 0x3F) << 6 | (ord($c[3]) & 0x3F)); - } else { - $ord = 0; - } - - return $ord; - } -} diff --git a/lib/Zend/Text/Figlet/Exception.php b/lib/Zend/Text/Figlet/Exception.php deleted file mode 100644 index c6b184aec4c..00000000000 --- a/lib/Zend/Text/Figlet/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Figlet - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Text_Exception - */ -#require_once 'Zend/Text/Exception.php'; - -/** - * Exception class for Zend_Figlet - * - * @category Zend - * @package Zend_Text_Figlet - * @uses Zend_Text_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Figlet_Exception extends Zend_Text_Exception -{ -} diff --git a/lib/Zend/Text/Figlet/zend-framework.flf b/lib/Zend/Text/Figlet/zend-framework.flf deleted file mode 100644 index 8b4ddc8be0f..00000000000 --- a/lib/Zend/Text/Figlet/zend-framework.flf +++ /dev/null @@ -1,753 +0,0 @@ -flf2a$ 7 6 10 51 22 0 7987 -Author : Wil Sinclair -Date : 2008/6/26 20:34:25 -Version: 1.0 - -------------------------------------------------------------------------------- - - Zend Framework - - LICENSE - - This source file is subject to the new BSD license that is bundled - with this package in the file LICENSE.txt. - It is also available through the world-wide-web at this URL: - http://framework.zend.com/license/new-bsd - If you did not receive a copy of the license and are unable to - obtain it through the world-wide-web, please send an email - to license@zend.com so we can send you a copy immediately. - - Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - -------------------------------------------------------------------------------- - -$ # -$ # -$ # -$ # -$ # -$ # -$ ## - __ # - / \\ # - | || # - |$ || # - \// # - []| # - ## - __ __ # - / /// //# - /_///_// # - `-` `-` # - # - # - ## -## - # - # - # - # - # - ## - _ # - | ||_ # - / ___// # - \___ \\ # - / $ // # - /_ // # - `-|_|| ## -%# - # - # - # - # - # - ## -&# - # - # - # - # - # - ## -'# - # - # - # - # - # - ## -(# - # - # - # - # - # - ## -)# - # - # - # - # - # - ## -*# - # - # - # - # - # - ## - # - _ # - _| || # - |_ $ _|| # - `-|_|-` # - - # - ## -,# - # - # - # - # - # - ## - # - # - ,------,,# -'======'' # - # - # - ## -.# - # - # - # - # - # - ## -/# - # - # - # - # - # - ## - ___ # - / _ \\ # - | |$| || # - | |_| || # - \___// # - `---` # - ## - __ # - / || # - | || # - _| ||_ # - |__$__|| # - `-----` # - ## - _____ # - \___ \\ # - / ___// # - | $ \\ # - |_____\\ # - `------` # - ## - _____ # - |___ \\ # - __$\ // # - __$/ \\ # - |_____// # - `-----` # - ## - __ # - / || # - / /|||_ # - /__ $ _||# - |_|| # - `-` # - ## - _____ # - / ___// # - /___ \\ # - / $ // # - /___// # -`----` # - ## - __ # - / // # - / // # - / __ \\ # - \____// # - `---` # - ## - ______ # - |___ // # - / // # - | || # - |_|| # - `-` # - ## - ____ # - / \\ # - \ -- // # - / -- \\ # - \____// # - `----` # - ## - ____ # - / __ \\ # - \__ || # - / // # - /_// # - `-` # - ## - # - # - []| # - # - []| # - # - ## - # - _ # - [_]| # - _ # - | ]] # - |// # - ' ## -<# - # - # - # - # - # - ## - # - ______ # - /_____// # - /_____// # - `-----` # - # - ## -># - # - # - # - # - # - ## -?# - # - # - # - # - # - ## -@# - # - # - # - # - # - ## - ___ # - / _ \\ # - / //\ \\ # -| ___ ||# -|_|| |_||# -`-` `-` # - ## - ______ # -| \\ # -| --$ // # -| -- \\ # -|______// # -`------` # - ## - _____ # - / ____|| # -/ //---`' # -\ \\___ # - \_____|| # - `----` # - ## - _____ # -| __ \\ # -| |$ \ || # -| |__/ || # -|_____// # - -----` # - ## - _____ # - | ___|| # - | ||__ # - | ||__ # - |_____|| # - `-----` # - ## - ______ # - /_____// # - `____ ` # - /___// # - `__ ` # - /_// # - `-` ## - _____ # - / ___|| # -| //$__ # -| \\_\ || # - \____// # - `---` # - ## - __ _ # -| || | || # -| '--' || # -| .--. || # -|_|| |_|| # -`-` `-` # - ## - ______ # - /_ _// # - -| ||- # - _| ||_ # - /_____// # - `-----` # - ## - ______ # - /_ _// # - | || # - _| || # - /__// # - `--` # - ## - _ __ # - | |/ // # - | ' // # - | . \\ # - |_|\_\\ # - `-` --` # - ## - __ # - | || # - | || # - | ||__ # - |____// # - `----` # - ## - _ _ # -| \ / || # -| \/ || # -| . . || # -|_|\/|_|| # -`-` `-` # - ## - _ _ # - | \| || # - | ' || # - | . || # - |_|\_|| # - `-` -` # - ## - ___ # - / _ \\ # - | /$\ || # - | \_/ || # - \___// # - `---` # - ## - ____ # - | _ \\ # - | |_| || # - | .__// # - |_|--` # - `-` # - ## - ___ # - / _ \\ # -| /$\ || # -| \_/ || # - \___ \\ # - `---` # - ## - ____ # - | _ \\ # - | |_| || # - | . // # - |_|\_\\ # - `-` --` # - ## - _____ # - / ___// # - \___ \\ # - / $ // # - /____// # -`-----` # - ## - ______ # - /_ _// # - `-| |,- # - | || # - |_|| # - `-`' # - ## - _ _ # -| || | || # -| || | || # -| \\_/ || # - \____// # - `---` # - ## -__ __ # -\ \\ / // # - \ \/ // # - \ // # - \// # - ` # - ## - _ _ # -| | | || # -| |/\| || # -| /\ || # -|_// \_|| # -`-` `-` # - ## - __ __ # - \ \\/ // # - \ $ // # - / . \\ # - /_//\_\\ # - `-` --` # - ## - __ __ # - \ \\/ // # - \ ` // # - | || # - |_|| # - `-`' # - ## - ______ # -|____ // # - / // # - / // # - / //__ # -/______|| # -`------` ## -[# - # - # - # - # - # - ## -\# - # - # - # - # - # - ## -]# - # - # - # - # - # - ## -^# - # - # - # - # - # - ## -_# - # - # - # - # - # - ## -`# - # - # - # - # - # - ## - ___ # - / _ \\ # - / //\ \\ # -| ___ ||# -|_|| |_||# -`-` `-` # - ## - ______ # -| \\ # -| --$ // # -| -- \\ # -|______// # -`------` # - ## - _____ # - / ____|| # -/ //---`' # -\ \\___ # - \_____|| # - `----` # - ## - _____ # -| __ \\ # -| |$ \ || # -| |__/ || # -|_____// # - -----` # - ## - _____ # - | ___|| # - | ||__ # - | ||__ # - |_____|| # - `-----` # - ## - ______ # - /_____// # - `____ ` # - /___// # - `__ ` # - /_// # - `-` ## - _____ # - / ___|| # -| //$__ # -| \\_\ || # - \____// # - `---` # - ## - __ _ # -| || | || # -| '--' || # -| .--. || # -|_|| |_|| # -`-` `-` # - ## - ______ # - /_ _// # - -| ||- # - _| ||_ # - /_____// # - `-----` # - ## - ______ # - /_ _// # - | || # - _| || # - /__// # - `--` # - ## - _ __ # - | |/ // # - | ' // # - | . \\ # - |_|\_\\ # - `-` --` # - ## - __ # - | || # - | || # - | ||__ # - |____// # - `----` # - ## - _ _ # -| \ / || # -| \/ || # -| . . || # -|_|\/|_|| # -`-` `-` # - ## - _ _ # - | \| || # - | ' || # - | . || # - |_|\_|| # - `-` -` # - ## - ___ # - / _ \\ # - | /$\ || # - | \_/ || # - \___// # - `---` # - ## - # - ____ # - | \\ # - | [] || # - | __// # - |_|`-` # - `-` ## - # - ___ # - / || # - | [] || # - \__ || # - -|_|| # - `-` ## - ____ # - | _ \\ # - | |_| || # - | . // # - |_|\_\\ # - `-` --` # - ## - _____ # - / ___// # - \___ \\ # - / $ // # - /____// # -`-----` # - ## - ______ # - /_ _// # - `-| |,- # - | || # - |_|| # - `-`' # - ## - _ _ # -| || | || # -| || | || # -| \\_/ || # - \____// # - `---` # - ## -__ __ # -\ \\ / // # - \ \/ // # - \ // # - \// # - ` # - ## - _ _ # -| | | || # -| |/\| || # -| /\ || # -|_// \_|| # -`-` `-` # - ## - __ __ # - \ \\/ // # - \ $ // # - / . \\ # - /_//\_\\ # - `-` --` # - ## - __ __ # - \ \\/ // # - \ ` // # - | || # - |_|| # - `-`' # - ## - _____ # - |__ // # - / // # - / //__ # - /_____|| # - `-----` # - ## -{# - # - # - # - # - # - ## -|# - # - # - # - # - # - ## -}# - # - # - # - # - # - ## -~# - # - # - # - # - # - ## - []|_[]| # - / _ \\ # - / //\ \\ # -| $___$ ||# -|_||$ |_||# -`-` `-` # - ## - []|_[]| # - / _ \\ # - | /$\ || # - | \_/ || # - \___// # - ---` # - ## - []| []| # -| ||$| || # -| ||$| || # -| \\_/ || # - \____// # - `---` # - ## - []|_[]| # - / _ \\ # - / //\ \\ # -| $___$ ||# -|_||$ |_||# -`-` `-` # - ## - []|_[]| # - / _ \\ # - | /$\ || # - | \_/ || # - \___// # - ---` # - ## - []| []| # -| ||$| || # -| ||$| || # -| \\_/ || # - \____// # - `---` # - ## - ,--. # - | _$ \\ # - | // # - | |\ \\ # - |$ ___\\ # - |_|----` # - - ## -162 CENT SIGN - _ # - | || # - / __// # -| (__` # - \ \\ # - |_|` # - `-` ## -215 MULTIPLICATION SIGN - # - # - \\// # - \\ # - //\\ # - # - ## diff --git a/lib/Zend/Text/MultiByte.php b/lib/Zend/Text/MultiByte.php deleted file mode 100644 index c5f559421f2..00000000000 --- a/lib/Zend/Text/MultiByte.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Text_MultiByte contains multibyte safe string methods - * - * @category Zend - * @package Zend_Text - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_MultiByte -{ - /** - * Word wrap - * - * @param string $string - * @param integer $width - * @param string $break - * @param boolean $cut - * @param string $charset - * @return string - */ - public static function wordWrap($string, $width = 75, $break = "\n", $cut = false, $charset = 'utf-8') - { - $stringWidth = iconv_strlen($string, $charset); - $breakWidth = iconv_strlen($break, $charset); - - if (strlen($string) === 0) { - return ''; - } elseif ($breakWidth === null) { - throw new Zend_Text_Exception('Break string cannot be empty'); - } elseif ($width === 0 && $cut) { - throw new Zend_Text_Exception('Can\'t force cut when width is zero'); - } - - $result = ''; - $lastStart = $lastSpace = 0; - - for ($current = 0; $current < $stringWidth; $current++) { - $char = iconv_substr($string, $current, 1, $charset); - - if ($breakWidth === 1) { - $possibleBreak = $char; - } else { - $possibleBreak = iconv_substr($string, $current, $breakWidth, $charset); - } - - if ($possibleBreak === $break) { - $result .= iconv_substr($string, $lastStart, $current - $lastStart + $breakWidth, $charset); - $current += $breakWidth - 1; - $lastStart = $lastSpace = $current + 1; - } elseif ($char === ' ') { - if ($current - $lastStart >= $width) { - $result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break; - $lastStart = $current + 1; - } - - $lastSpace = $current; - } elseif ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) { - $result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break; - $lastStart = $lastSpace = $current; - } elseif ($current - $lastStart >= $width && $lastStart < $lastSpace) { - $result .= iconv_substr($string, $lastStart, $lastSpace - $lastStart, $charset) . $break; - $lastStart = $lastSpace = $lastSpace + 1; - } - } - - if ($lastStart !== $current) { - $result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset); - } - - return $result; - } - - /** - * String padding - * - * @param string $input - * @param integer $padLength - * @param string $padString - * @param integer $padType - * @param string $charset - * @return string - */ - public static function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT, $charset = 'utf-8') - { - $return = ''; - $lengthOfPadding = $padLength - iconv_strlen($input, $charset); - $padStringLength = iconv_strlen($padString, $charset); - - if ($padStringLength === 0 || $lengthOfPadding <= 0) { - $return = $input; - } else { - $repeatCount = floor($lengthOfPadding / $padStringLength); - - if ($padType === STR_PAD_BOTH) { - $lastStringLeft = ''; - $lastStringRight = ''; - $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2; - - $lastStringLength = $lengthOfPadding - 2 * $repeatCountLeft * $padStringLength; - $lastStringLeftLength = $lastStringRightLength = floor($lastStringLength / 2); - $lastStringRightLength += $lastStringLength % 2; - - $lastStringLeft = iconv_substr($padString, 0, $lastStringLeftLength, $charset); - $lastStringRight = iconv_substr($padString, 0, $lastStringRightLength, $charset); - - $return = str_repeat($padString, $repeatCountLeft) . $lastStringLeft - . $input - . str_repeat($padString, $repeatCountRight) . $lastStringRight; - } else { - $lastString = iconv_substr($padString, 0, $lengthOfPadding % $padStringLength, $charset); - - if ($padType === STR_PAD_LEFT) { - $return = str_repeat($padString, $repeatCount) . $lastString . $input; - } else { - $return = $input . str_repeat($padString, $repeatCount) . $lastString; - } - } - } - - return $return; - } -} diff --git a/lib/Zend/Text/Table.php b/lib/Zend/Text/Table.php deleted file mode 100644 index 3bde8725a39..00000000000 --- a/lib/Zend/Text/Table.php +++ /dev/null @@ -1,533 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Text_Table enables developers to create tables out of characters - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table -{ - /** - * Auto seperator settings - */ - const AUTO_SEPARATE_NONE = 0x0; - const AUTO_SEPARATE_HEADER = 0x1; - const AUTO_SEPARATE_FOOTER = 0x2; - const AUTO_SEPARATE_ALL = 0x4; - - /** - * Decorator used for the table borders - * - * @var Zend_Text_Table_Decorator_Interface - */ - protected $_decorator = null; - - /** - * List of all column widths - * - * @var array - */ - protected $_columnWidths = null; - - /** - * Rows of the table - * - * @var array - */ - protected $_rows = array(); - - /** - * Auto separation mode - * - * @var integer - */ - protected $_autoSeparate = self::AUTO_SEPARATE_ALL; - - /** - * Padding for columns - * - * @var integer - */ - protected $_padding = 0; - - /** - * Default column aligns for rows created by appendRow(array $data) - * - * @var array - */ - protected $_defaultColumnAligns = array(); - - /** - * Plugin loader for decorators - * - * @var string - */ - protected $_pluginLoader = null; - - /** - * Charset which is used for input by default - * - * @var string - */ - protected static $_inputCharset = 'utf-8'; - - /** - * Charset which is used internally - * - * @var string - */ - protected static $_outputCharset = 'utf-8'; - - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $_skipOptions = array( - 'options', - 'config', - 'defaultColumnAlign', - ); - - /** - * Create a basic table object - * - * @param array $columnsWidths List of all column widths - * @param Zend_Config|array $options Configuration options - * @throws Zend_Text_Table_Exception When no columns widths were set - */ - public function __construct($options = null) - { - // Set options - if (is_array($options)) { - $this->setOptions($options); - } else if ($options instanceof Zend_Config) { - $this->setConfig($options); - } - - // Check if column widths were set - // @todo When column widths were not set, assume auto-sizing - if ($this->_columnWidths === null) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('You must define the column widths'); - } - - // If no decorator was given, use default unicode decorator - if ($this->_decorator === null) { - if (self::getOutputCharset() === 'utf-8') { - $this->setDecorator('unicode'); - } else { - $this->setDecorator('ascii'); - } - } - } - - /** - * Set options from array - * - * @param array $options Configuration for Zend_Text_Table - * @return Zend_Text_Table - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->_skipOptions)) { - continue; - } - - $method = 'set' . ucfirst($key); - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } - - /** - * Set options from config object - * - * @param Zend_Config $config Configuration for Zend_Text_Table - * @return Zend_Text_Table - */ - public function setConfig(Zend_Config $config) - { - return $this->setOptions($config->toArray()); - } - - /** - * Set column widths - * - * @param array $columnWidths Widths of all columns - * @throws Zend_Text_Table_Exception When no columns were supplied - * @throws Zend_Text_Table_Exception When a column has an invalid width - * @return Zend_Text_Table - */ - public function setColumnWidths(array $columnWidths) - { - if (count($columnWidths) === 0) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('You must supply at least one column'); - } - - foreach ($columnWidths as $columnNum => $columnWidth) { - if (is_int($columnWidth) === false || $columnWidth < 1) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('Column ' . $columnNum . ' has an invalid' - . ' column width'); - } - } - - $this->_columnWidths = $columnWidths; - - return $this; - } - - /** - * Set auto separation mode - * - * @param integer $autoSeparate Auto separation mode - * @return Zend_Text_Table - */ - public function setAutoSeparate($autoSeparate) - { - $this->_autoSeparate = (int) $autoSeparate; - return $this; - } - - /** - * Set decorator - * - * @param Zend_Text_Table_Decorator_Interface|string $decorator Decorator to use - * @return Zend_Text_Table - */ - public function setDecorator($decorator) - { - if ($decorator instanceof Zend_Text_Table_Decorator_Interface) { - $this->_decorator = $decorator; - } else { - $classname = $this->getPluginLoader()->load($decorator); - $this->_decorator = new $classname; - } - - return $this; - } - - /** - * Set the column padding - * - * @param integer $padding The padding for the columns - * @return Zend_Text_Table - */ - public function setPadding($padding) - { - $this->_padding = max(0, (int) $padding); - return $this; - } - - /** - * Get the plugin loader for decorators - * - * @return Zend_Loader_PluginLoader - */ - public function getPluginLoader() - { - if ($this->_pluginLoader === null) { - $prefix = 'Zend_Text_Table_Decorator_'; - $pathPrefix = 'Zend/Text/Table/Decorator/'; - - #require_once 'Zend/Loader/PluginLoader.php'; - $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix)); - } - - return $this->_pluginLoader; - } - - /** - * Set default column align for rows created by appendRow(array $data) - * - * @param integer $columnNum - * @param string $align - * @return Zend_Text_Table - */ - public function setDefaultColumnAlign($columnNum, $align) - { - $this->_defaultColumnAligns[$columnNum] = $align; - - return $this; - } - - /** - * Set the input charset for column contents - * - * @param string $charset - */ - public static function setInputCharset($charset) - { - self::$_inputCharset = strtolower($charset); - } - - /** - * Get the input charset for column contents - * - * @param string $charset - */ - public static function getInputCharset() - { - return self::$_inputCharset; - } - - /** - * Set the output charset for column contents - * - * @param string $charset - */ - public static function setOutputCharset($charset) - { - self::$_outputCharset = strtolower($charset); - } - - /** - * Get the output charset for column contents - * - * @param string $charset - */ - public static function getOutputCharset() - { - return self::$_outputCharset; - } - - /** - * Append a row to the table - * - * @param array|Zend_Text_Table_Row $row The row to append to the table - * @throws Zend_Text_Table_Exception When $row is neither an array nor Zend_Zext_Table_Row - * @throws Zend_Text_Table_Exception When a row contains too many columns - * @return Zend_Text_Table - */ - public function appendRow($row) - { - if (!is_array($row) && !($row instanceof Zend_Text_Table_Row)) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('$row must be an array or instance of Zend_Text_Table_Row'); - } - - if (is_array($row)) { - if (count($row) > count($this->_columnWidths)) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('Row contains too many columns'); - } - - #require_once 'Zend/Text/Table/Row.php'; - #require_once 'Zend/Text/Table/Column.php'; - - $data = $row; - $row = new Zend_Text_Table_Row(); - $colNum = 0; - foreach ($data as $columnData) { - if (isset($this->_defaultColumnAligns[$colNum])) { - $align = $this->_defaultColumnAligns[$colNum]; - } else { - $align = null; - } - - $row->appendColumn(new Zend_Text_Table_Column($columnData, $align)); - $colNum++; - } - } - - $this->_rows[] = $row; - - return $this; - } - - /** - * Render the table - * - * @throws Zend_Text_Table_Exception When no rows were added to the table - * @return string - */ - public function render() - { - // There should be at least one row - if (count($this->_rows) === 0) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('No rows were added to the table yet'); - } - - // Initiate the result variable - $result = ''; - - // Count total columns - $totalNumColumns = count($this->_columnWidths); - - // Now render all rows, starting from the first one - $numRows = count($this->_rows); - foreach ($this->_rows as $rowNum => $row) { - // Get all column widths - if (isset($columnWidths) === true) { - $lastColumnWidths = $columnWidths; - } - - $renderedRow = $row->render($this->_columnWidths, $this->_decorator, $this->_padding); - $columnWidths = $row->getColumnWidths(); - $numColumns = count($columnWidths); - - // Check what we have to draw - if ($rowNum === 0) { - // If this is the first row, draw the table top - $result .= $this->_decorator->getTopLeft(); - - foreach ($columnWidths as $columnNum => $columnWidth) { - $result .= str_repeat($this->_decorator->getHorizontal(), - $columnWidth); - - if (($columnNum + 1) === $numColumns) { - $result .= $this->_decorator->getTopRight(); - } else { - $result .= $this->_decorator->getHorizontalDown(); - } - } - - $result .= "\n"; - } else { - // Else check if we have to draw the row separator - if ($this->_autoSeparate & self::AUTO_SEPARATE_ALL) { - $drawSeparator = true; - } else if ($rowNum === 1 && $this->_autoSeparate & self::AUTO_SEPARATE_HEADER) { - $drawSeparator = true; - } else if ($rowNum === ($numRows - 1) && $this->_autoSeparate & self::AUTO_SEPARATE_FOOTER) { - $drawSeparator = true; - } else { - $drawSeparator = false; - } - - if ($drawSeparator) { - $result .= $this->_decorator->getVerticalRight(); - - $currentUpperColumn = 0; - $currentLowerColumn = 0; - $currentUpperWidth = 0; - $currentLowerWidth = 0; - - // Loop through all column widths - foreach ($this->_columnWidths as $columnNum => $columnWidth) { - // Add the horizontal line - $result .= str_repeat($this->_decorator->getHorizontal(), - $columnWidth); - - // If this is the last line, break out - if (($columnNum + 1) === $totalNumColumns) { - break; - } - - // Else check, which connector style has to be used - $connector = 0x0; - $currentUpperWidth += $columnWidth; - $currentLowerWidth += $columnWidth; - - if ($lastColumnWidths[$currentUpperColumn] === $currentUpperWidth) { - $connector |= 0x1; - $currentUpperColumn += 1; - $currentUpperWidth = 0; - } else { - $currentUpperWidth += 1; - } - - if ($columnWidths[$currentLowerColumn] === $currentLowerWidth) { - $connector |= 0x2; - $currentLowerColumn += 1; - $currentLowerWidth = 0; - } else { - $currentLowerWidth += 1; - } - - switch ($connector) { - case 0x0: - $result .= $this->_decorator->getHorizontal(); - break; - - case 0x1: - $result .= $this->_decorator->getHorizontalUp(); - break; - - case 0x2: - $result .= $this->_decorator->getHorizontalDown(); - break; - - case 0x3: - $result .= $this->_decorator->getCross(); - break; - - default: - // This can never happen, but the CS tells I have to have it ... - break; - } - } - - $result .= $this->_decorator->getVerticalLeft() . "\n"; - } - } - - // Add the rendered row to the result - $result .= $renderedRow; - - // If this is the last row, draw the table bottom - if (($rowNum + 1) === $numRows) { - $result .= $this->_decorator->getBottomLeft(); - - foreach ($columnWidths as $columnNum => $columnWidth) { - $result .= str_repeat($this->_decorator->getHorizontal(), - $columnWidth); - - if (($columnNum + 1) === $numColumns) { - $result .= $this->_decorator->getBottomRight(); - } else { - $result .= $this->_decorator->getHorizontalUp(); - } - } - - $result .= "\n"; - } - } - - return $result; - } - - /** - * Magic method which returns the rendered table - * - * @return string - */ - public function __toString() - { - try { - return $this->render(); - } catch (Exception $e) { - trigger_error($e->getMessage(), E_USER_ERROR); - } - - } -} diff --git a/lib/Zend/Text/Table/Column.php b/lib/Zend/Text/Table/Column.php deleted file mode 100644 index 6e4bbbe788c..00000000000 --- a/lib/Zend/Text/Table/Column.php +++ /dev/null @@ -1,243 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Text_Table - */ -#require_once 'Zend/Text/Table.php'; - -/** - * @see Zend_Text_MultiByte - */ -#require_once 'Zend/Text/MultiByte.php'; - -/** - * Column class for Zend_Text_Table_Row - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table_Column -{ - /** - * Aligns for columns - */ - const ALIGN_LEFT = 'left'; - const ALIGN_CENTER = 'center'; - const ALIGN_RIGHT = 'right'; - - /** - * Content of the column - * - * @var string - */ - protected $_content = ''; - - /** - * Align of the column - * - * @var string - */ - protected $_align = self::ALIGN_LEFT; - - /** - * Colspan of the column - * - * @var integer - */ - protected $_colSpan = 1; - - /** - * Allowed align parameters - * - * @var array - */ - protected $_allowedAligns = array(self::ALIGN_LEFT, self::ALIGN_CENTER, self::ALIGN_RIGHT); - - /** - * Create a column for a Zend_Text_Table_Row object. - * - * @param string $content The content of the column - * @param string $align The align of the content - * @param integer $colSpan The colspan of the column - * @param string $charset The encoding of the content - */ - public function __construct($content = null, $align = null, $colSpan = null, $charset = null) - { - if ($content !== null) { - $this->setContent($content, $charset); - } - - if ($align !== null) { - $this->setAlign($align); - } - - if ($colSpan !== null) { - $this->setColSpan($colSpan); - } - } - - /** - * Set the content. - * - * If $charset is not defined, it is assumed that $content is encoded in - * the charset defined via Zend_Text_Table::setInputCharset() (defaults - * to utf-8). - * - * @param string $content Content of the column - * @param string $charset The charset of the content - * @throws Zend_Text_Table_Exception When $content is not a string - * @return Zend_Text_Table_Column - */ - public function setContent($content, $charset = null) - { - if (is_string($content) === false) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('$content must be a string'); - } - - if ($charset === null) { - $inputCharset = Zend_Text_Table::getInputCharset(); - } else { - $inputCharset = strtolower($charset); - } - - $outputCharset = Zend_Text_Table::getOutputCharset(); - - if ($inputCharset !== $outputCharset) { - if (PHP_OS !== 'AIX') { - // AIX does not understand these character sets - $content = iconv($inputCharset, $outputCharset, $content); - } - - } - - $this->_content = $content; - - return $this; - } - - /** - * Set the align - * - * @param string $align Align of the column - * @throws Zend_Text_Table_Exception When supplied align is invalid - * @return Zend_Text_Table_Column - */ - public function setAlign($align) - { - if (in_array($align, $this->_allowedAligns) === false) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('Invalid align supplied'); - } - - $this->_align = $align; - - return $this; - } - - /** - * Set the colspan - * - * @param int $colSpan - * @throws Zend_Text_Table_Exception When $colSpan is smaller than 1 - * @return Zend_Text_Table_Column - */ - public function setColSpan($colSpan) - { - if (is_int($colSpan) === false || $colSpan < 1) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('$colSpan must be an integer and greater than 0'); - } - - $this->_colSpan = $colSpan; - - return $this; - } - - /** - * Get the colspan - * - * @return integer - */ - public function getColSpan() - { - return $this->_colSpan; - } - - /** - * Render the column width the given column width - * - * @param integer $columnWidth The width of the column - * @param integer $padding The padding for the column - * @throws Zend_Text_Table_Exception When $columnWidth is lower than 1 - * @throws Zend_Text_Table_Exception When padding is greater than columnWidth - * @return string - */ - public function render($columnWidth, $padding = 0) - { - if (is_int($columnWidth) === false || $columnWidth < 1) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('$columnWidth must be an integer and greater than 0'); - } - - $columnWidth -= ($padding * 2); - - if ($columnWidth < 1) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('Padding (' . $padding . ') is greater than column width'); - } - - switch ($this->_align) { - case self::ALIGN_LEFT: - $padMode = STR_PAD_RIGHT; - break; - - case self::ALIGN_CENTER: - $padMode = STR_PAD_BOTH; - break; - - case self::ALIGN_RIGHT: - $padMode = STR_PAD_LEFT; - break; - - default: - // This can never happen, but the CS tells I have to have it ... - break; - } - - $outputCharset = Zend_Text_Table::getOutputCharset(); - $lines = explode("\n", Zend_Text_MultiByte::wordWrap($this->_content, $columnWidth, "\n", true, $outputCharset)); - $paddedLines = array(); - - foreach ($lines AS $line) { - $paddedLines[] = str_repeat(' ', $padding) - . Zend_Text_MultiByte::strPad($line, $columnWidth, ' ', $padMode, $outputCharset) - . str_repeat(' ', $padding); - } - - $result = implode("\n", $paddedLines); - - return $result; - } -} diff --git a/lib/Zend/Text/Table/Decorator/Ascii.php b/lib/Zend/Text/Table/Decorator/Ascii.php deleted file mode 100644 index bfb5d82e143..00000000000 --- a/lib/Zend/Text/Table/Decorator/Ascii.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Text_Table_Decorator_Interface - */ -#require_once 'Zend/Text/Table/Decorator/Interface.php'; - -/** - * ASCII Decorator for Zend_Text_Table - * - * @category Zend - * @package Zend_Text_Table - * @uses Zend_Text_Table_Decorator_Interface - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table_Decorator_Ascii implements Zend_Text_Table_Decorator_Interface -{ - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getTopLeft() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getTopRight() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getBottomLeft() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getBottomRight() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVertical() - { - return '|'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontal() - { - return '-'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getCross() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVerticalRight() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVerticalLeft() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontalDown() - { - return '+'; - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontalUp() - { - return '+'; - } -} diff --git a/lib/Zend/Text/Table/Decorator/Interface.php b/lib/Zend/Text/Table/Decorator/Interface.php deleted file mode 100644 index 995d3039960..00000000000 --- a/lib/Zend/Text/Table/Decorator/Interface.php +++ /dev/null @@ -1,108 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Interface for Zend_Text_Table decorators - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Text_Table_Decorator_Interface -{ - /** - * Get a single character for the top left corner - * - * @return string - */ - public function getTopLeft(); - - /** - * Get a single character for the top right corner - * - * @return string - */ - public function getTopRight(); - - /** - * Get a single character for the bottom left corner - * - * @return string - */ - public function getBottomLeft(); - - /** - * Get a single character for the bottom right corner - * - * @return string - */ - public function getBottomRight(); - - /** - * Get a single character for a vertical line - * - * @return string - */ - public function getVertical(); - - /** - * Get a single character for a horizontal line - * - * @return string - */ - public function getHorizontal(); - - /** - * Get a single character for a crossing line - * - * @return string - */ - public function getCross(); - - /** - * Get a single character for a vertical divider right - * - * @return string - */ - public function getVerticalRight(); - - /** - * Get a single character for a vertical divider left - * - * @return string - */ - public function getVerticalLeft(); - - /** - * Get a single character for a horizontal divider down - * - * @return string - */ - public function getHorizontalDown(); - - /** - * Get a single character for a horizontal divider up - * - * @return string - */ - public function getHorizontalUp(); -} diff --git a/lib/Zend/Text/Table/Decorator/Unicode.php b/lib/Zend/Text/Table/Decorator/Unicode.php deleted file mode 100644 index f53168ae8d1..00000000000 --- a/lib/Zend/Text/Table/Decorator/Unicode.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Text_Table_Decorator_Interface - */ -#require_once 'Zend/Text/Table/Decorator/Interface.php'; - -/** - * Unicode Decorator for Zend_Text_Table - * - * @category Zend - * @package Zend_Text_Table - * @uses Zend_Text_Table_Decorator_Interface - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table_Decorator_Unicode implements Zend_Text_Table_Decorator_Interface -{ - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getTopLeft() - { - return $this->_uniChar(0x250C); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getTopRight() - { - return $this->_uniChar(0x2510); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getBottomLeft() - { - return $this->_uniChar(0x2514); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getBottomRight() - { - return $this->_uniChar(0x2518); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVertical() - { - return $this->_uniChar(0x2502); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontal() - { - return $this->_uniChar(0x2500); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getCross() - { - return $this->_uniChar(0x253C); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVerticalRight() - { - return $this->_uniChar(0x251C); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getVerticalLeft() - { - return $this->_uniChar(0x2524); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontalDown() - { - return $this->_uniChar(0x252C); - } - - /** - * Defined by Zend_Text_Table_Decorator_Interface - * - * @return string - */ - public function getHorizontalUp() - { - return $this->_uniChar(0x2534); - } - - /** - * Convert am unicode character code to a character - * - * @param integer $code - * @return string|false - */ - protected function _uniChar($code) - { - if ($code <= 0x7F) { - $char = chr($code); - } else if ($code <= 0x7FF) { - $char = chr(0xC0 | $code >> 6) - . chr(0x80 | $code & 0x3F); - } else if ($code <= 0xFFFF) { - $char = chr(0xE0 | $code >> 12) - . chr(0x80 | $code >> 6 & 0x3F) - . chr(0x80 | $code & 0x3F); - } else if ($code <= 0x10FFFF) { - $char = chr(0xF0 | $code >> 18) - . chr(0x80 | $code >> 12 & 0x3F) - . chr(0x80 | $code >> 6 & 0x3F) - . chr(0x80 | $code & 0x3F); - } else { - return false; - } - - return $char; - } -} diff --git a/lib/Zend/Text/Table/Exception.php b/lib/Zend/Text/Table/Exception.php deleted file mode 100644 index fd3e8922575..00000000000 --- a/lib/Zend/Text/Table/Exception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Text_Exception - */ -#require_once 'Zend/Text/Exception.php'; - -/** - * Exception class for Zend_Text_Table - * - * @category Zend - * @package Zend_Text_Table - * @uses Zend_Text_Exception - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table_Exception extends Zend_Text_Exception -{ -} diff --git a/lib/Zend/Text/Table/Row.php b/lib/Zend/Text/Table/Row.php deleted file mode 100644 index 09140b2d1a3..00000000000 --- a/lib/Zend/Text/Table/Row.php +++ /dev/null @@ -1,215 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Row class for Zend_Text_Table - * - * @category Zend - * @package Zend_Text_Table - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Text_Table_Row -{ - /** - * List of all columns - * - * @var array - */ - protected $_columns = array(); - - /** - * Temporary stored column widths - * - * @var array - */ - protected $_columnWidths = null; - - /** - * Create a new column and append it to the row - * - * @param string $content - * @param array $options - * @return Zend_Text_Table_Row - */ - public function createColumn($content, array $options = null) - { - $align = null; - $colSpan = null; - $encoding = null; - - if ($options !== null) { - extract($options, EXTR_IF_EXISTS); - } - - #require_once 'Zend/Text/Table/Column.php'; - - $column = new Zend_Text_Table_Column($content, $align, $colSpan, $encoding); - - $this->appendColumn($column); - - return $this; - } - - /** - * Append a column to the row - * - * @param Zend_Text_Table_Column $column The column to append to the row - * @return Zend_Text_Table_Row - */ - public function appendColumn(Zend_Text_Table_Column $column) - { - $this->_columns[] = $column; - - return $this; - } - - /** - * Get a column by it's index - * - * Returns null, when the index is out of range - * - * @param integer $index - * @return Zend_Text_Table_Column|null - */ - public function getColumn($index) - { - if (!isset($this->_columns[$index])) { - return null; - } - - return $this->_columns[$index]; - } - - /** - * Get all columns of the row - * - * @return array - */ - public function getColumns() - { - return $this->_columns; - } - - /** - * Get the widths of all columns, which were rendered last - * - * @throws Zend_Text_Table_Exception When no columns were rendered yet - * @return integer - */ - public function getColumnWidths() - { - if ($this->_columnWidths === null) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('No columns were rendered yet'); - } - - return $this->_columnWidths; - } - - /** - * Render the row - * - * @param array $columnWidths Width of all columns - * @param Zend_Text_Table_Decorator_Interface $decorator Decorator for the row borders - * @param integer $padding Padding for the columns - * @throws Zend_Text_Table_Exception When there are too many columns - * @return string - */ - public function render(array $columnWidths, - Zend_Text_Table_Decorator_Interface $decorator, - $padding = 0) - { - // Prepare an array to store all column widths - $this->_columnWidths = array(); - - // If there is no single column, create a column which spans over the - // entire row - if (count($this->_columns) === 0) { - #require_once 'Zend/Text/Table/Column.php'; - $this->appendColumn(new Zend_Text_Table_Column(null, null, count($columnWidths))); - } - - // First we have to render all columns, to get the maximum height - $renderedColumns = array(); - $maxHeight = 0; - $colNum = 0; - foreach ($this->_columns as $column) { - // Get the colspan of the column - $colSpan = $column->getColSpan(); - - // Verify if there are enough column widths defined - if (($colNum + $colSpan) > count($columnWidths)) { - #require_once 'Zend/Text/Table/Exception.php'; - throw new Zend_Text_Table_Exception('Too many columns'); - } - - // Calculate the column width - $columnWidth = ($colSpan - 1 + array_sum(array_slice($columnWidths, - $colNum, - $colSpan))); - - // Render the column and split it's lines into an array - $result = explode("\n", $column->render($columnWidth, $padding)); - - // Store the width of the rendered column - $this->_columnWidths[] = $columnWidth; - - // Store the rendered column and calculate the new max height - $renderedColumns[] = $result; - $maxHeight = max($maxHeight, count($result)); - - // Set up the internal column number - $colNum += $colSpan; - } - - // If the row doesnt contain enough columns to fill the entire row, fill - // it with an empty column - if ($colNum < count($columnWidths)) { - $remainingWidth = (count($columnWidths) - $colNum - 1) + - array_sum(array_slice($columnWidths, - $colNum)); - $renderedColumns[] = array(str_repeat(' ', $remainingWidth)); - - $this->_columnWidths[] = $remainingWidth; - } - - // Add each single column line to the result - $result = ''; - for ($line = 0; $line < $maxHeight; $line++) { - $result .= $decorator->getVertical(); - - foreach ($renderedColumns as $index => $renderedColumn) { - if (isset($renderedColumn[$line]) === true) { - $result .= $renderedColumn[$line]; - } else { - $result .= str_repeat(' ', $this->_columnWidths[$index]); - } - - $result .= $decorator->getVertical(); - } - - $result .= "\n"; - } - - return $result; - } -} diff --git a/lib/Zend/TimeSync.php b/lib/Zend/TimeSync.php deleted file mode 100644 index 2b8de4ea321..00000000000 --- a/lib/Zend/TimeSync.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php - -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @version $Id$ - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** - * Zend_Date - */ -#require_once 'Zend/Date.php'; - -/** - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_TimeSync implements IteratorAggregate -{ - /** - * Set the default timeserver protocol to "Ntp". This will be called - * when no protocol is specified - */ - const DEFAULT_PROTOCOL = 'Ntp'; - - /** - * Contains array of timeserver objects - * - * @var array - */ - protected $_timeservers = array(); - - /** - * Holds a reference to the timeserver that is currently being used - * - * @var object - */ - protected $_current; - - /** - * Allowed timeserver schemes - * - * @var array - */ - protected $_allowedSchemes = array( - 'Ntp', - 'Sntp' - ); - - /** - * Configuration array, set using the constructor or using - * ::setOptions() or ::setOption() - * - * @var array - */ - public static $options = array( - 'timeout' => 1 - ); - - /** - * Zend_TimeSync constructor - * - * @param string|array $target - OPTIONAL single timeserver, or an array of timeservers. - * @param string $alias - OPTIONAL an alias for this timeserver - * @return object - */ - public function __construct($target = null, $alias = null) - { - if ($target !== null) { - $this->addServer($target, $alias); - } - } - - /** - * getIterator() - return an iteratable object for use in foreach and the like, - * this completes the IteratorAggregate interface - * - * @return ArrayObject - */ - public function getIterator() - { - return new ArrayObject($this->_timeservers); - } - - /** - * Add a timeserver or multiple timeservers - * - * Server should be a single string representation of a timeserver, - * or a structured array listing multiple timeservers. - * - * If you provide an array of timeservers in the $target variable, - * $alias will be ignored. you can enter these as the array key - * in the provided array, which should be structured as follows: - * - * <code> - * $example = array( - * 'server_a' => 'ntp://127.0.0.1', - * 'server_b' => 'ntp://127.0.0.1:123', - * 'server_c' => 'ntp://[2000:364:234::2.5]', - * 'server_d' => 'ntp://[2000:364:234::2.5]:123' - * ); - * </code> - * - * If no port number has been suplied, the default matching port - * number will be used. - * - * Supported protocols are: - * - ntp - * - sntp - * - * @param string|array $target - Single timeserver, or an array of timeservers. - * @param string $alias - OPTIONAL an alias for this timeserver - * @throws Zend_TimeSync_Exception - */ - public function addServer($target, $alias = null) - { - if (is_array($target)) { - foreach ($target as $key => $server) { - $this->_addServer($server, $key); - } - } else { - $this->_addServer($target, $alias); - } - } - - /** - * Sets the value for the given options - * - * This will replace any currently defined options. - * - * @param array $options - An array of options to be set - */ - public static function setOptions(array $options) - { - foreach ($options as $key => $value) { - Zend_TimeSync::$options[$key] = $value; - } - } - - /** - * Marks a nameserver as current - * - * @param string|integer $alias - The alias from the timeserver to set as current - * @throws Zend_TimeSync_Exception - */ - public function setServer($alias) - { - if (isset($this->_timeservers[$alias]) === true) { - $this->_current = $this->_timeservers[$alias]; - } else { - #require_once 'Zend/TimeSync/Exception.php'; - throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver"); - } - } - - /** - * Returns the value to the option - * - * @param string $key - The option's identifier - * @return mixed - * @throws Zend_TimeSync_Exception - */ - public static function getOptions($key = null) - { - if ($key == null) { - return Zend_TimeSync::$options; - } - - if (isset(Zend_TimeSync::$options[$key]) === true) { - return Zend_TimeSync::$options[$key]; - } else { - #require_once 'Zend/TimeSync/Exception.php'; - throw new Zend_TimeSync_Exception("'$key' does not point to valid option"); - } - } - - /** - * Return a specified timeserver by alias - * If no alias is given it will return the current timeserver - * - * @param string|integer $alias - The alias from the timeserver to return - * @return object - * @throws Zend_TimeSync_Exception - */ - public function getServer($alias = null) - { - if ($alias === null) { - if (isset($this->_current) && $this->_current !== false) { - return $this->_current; - } else { - #require_once 'Zend/TimeSync/Exception.php'; - throw new Zend_TimeSync_Exception('there is no timeserver set'); - } - } - if (isset($this->_timeservers[$alias]) === true) { - return $this->_timeservers[$alias]; - } else { - #require_once 'Zend/TimeSync/Exception.php'; - throw new Zend_TimeSync_Exception("'$alias' does not point to valid timeserver"); - } - } - - /** - * Returns information sent/returned from the current timeserver - * - * @return array - */ - public function getInfo() - { - return $this->getServer()->getInfo(); - } - - /** - * Query the timeserver list using the fallback mechanism - * - * If there are multiple servers listed, this method will act as a - * facade and will try to return the date from the first server that - * returns a valid result. - * - * @param Zend_Locale $locale - OPTIONAL locale - * @return object - * @throws Zend_TimeSync_Exception - */ - public function getDate($locale = null) - { - #require_once 'Zend/TimeSync/Exception.php'; - foreach ($this->_timeservers as $alias => $server) { - $this->_current = $server; - try { - return $server->getDate($locale); - } catch (Zend_TimeSync_Exception $e) { - if (!isset($masterException)) { - $masterException = new Zend_TimeSync_Exception('all timeservers are bogus'); - } - $masterException->addException($e); - } - } - - throw $masterException; - } - - /** - * Adds a timeserver object to the timeserver list - * - * @param string|array $target - Single timeserver, or an array of timeservers. - * @param string $alias - An alias for this timeserver - */ - protected function _addServer($target, $alias) - { - if ($pos = strpos($target, '://')) { - $protocol = substr($target, 0, $pos); - $adress = substr($target, $pos + 3); - } else { - $adress = $target; - $protocol = self::DEFAULT_PROTOCOL; - } - - if ($pos = strrpos($adress, ':')) { - $posbr = strpos($adress, ']'); - if ($posbr and ($pos > $posbr)) { - $port = substr($adress, $pos + 1); - $adress = substr($adress, 0, $pos); - } else if (!$posbr and $pos) { - $port = substr($adress, $pos + 1); - $adress = substr($adress, 0, $pos); - } else { - $port = null; - } - } else { - $port = null; - } - - $protocol = ucfirst(strtolower($protocol)); - if (!in_array($protocol, $this->_allowedSchemes)) { - #require_once 'Zend/TimeSync/Exception.php'; - throw new Zend_TimeSync_Exception("'$protocol' is not a supported protocol"); - } - - $className = 'Zend_TimeSync_' . $protocol; - if (!class_exists($className)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($className); - } - $timeServerObj = new $className($adress, $port); - - $this->_timeservers[$alias] = $timeServerObj; - } -} diff --git a/lib/Zend/TimeSync/Exception.php b/lib/Zend/TimeSync/Exception.php deleted file mode 100644 index 47135499ea6..00000000000 --- a/lib/Zend/TimeSync/Exception.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Exception - */ -#require_once 'Zend/Exception.php'; - -/** - * Exception class for Zend_TimeSync - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_TimeSync_Exception extends Zend_Exception -{ - /** - * Contains array of exceptions thrown in queried server - * - * @var array - */ - protected $_exceptions; - - /** - * Adds an exception to the exception list - * - * @param Zend_TimeSync_Exception $exception New exteption to throw - * @return void - */ - public function addException(Zend_TimeSync_Exception $exception) - { - $this->_exceptions[] = $exception; - } - - /** - * Returns an array of exceptions that were thrown - * - * @return array - */ - public function get() - { - return $this->_exceptions; - } -} diff --git a/lib/Zend/TimeSync/Ntp.php b/lib/Zend/TimeSync/Ntp.php deleted file mode 100644 index 7d85ea13de3..00000000000 --- a/lib/Zend/TimeSync/Ntp.php +++ /dev/null @@ -1,431 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_TimeSync_Protocol - */ -#require_once 'Zend/TimeSync/Protocol.php'; - -/** - * NTP Protocol handling class - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_TimeSync_Ntp extends Zend_TimeSync_Protocol -{ - /** - * NTP port number (123) assigned by the Internet Assigned Numbers Authority - * - * @var integer - */ - protected $_port = 123; - - /** - * NTP class constructor, sets the timeserver and port number - * - * @param string $timeserver Adress of the timeserver to connect to - * @param integer $port (Optional) Port for this timeserver - */ - public function __construct($timeserver, $port = 123) - { - $this->_timeserver = 'udp://' . $timeserver; - if ($port !== null) { - $this->_port = $port; - } - } - - /** - * Prepare local timestamp for transmission in our request packet - * - * NTP timestamps are represented as a 64-bit fixed-point number, in - * seconds relative to 0000 UT on 1 January 1900. The integer part is - * in the first 32 bits and the fraction part in the last 32 bits - * - * @return string - */ - protected function _prepare() - { - $frac = microtime(); - $fracba = ($frac & 0xff000000) >> 24; - $fracbb = ($frac & 0x00ff0000) >> 16; - $fracbc = ($frac & 0x0000ff00) >> 8; - $fracbd = ($frac & 0x000000ff); - - $sec = (time() + 2208988800); - $secba = ($sec & 0xff000000) >> 24; - $secbb = ($sec & 0x00ff0000) >> 16; - $secbc = ($sec & 0x0000ff00) >> 8; - $secbd = ($sec & 0x000000ff); - - // Flags - $nul = chr(0x00); - $nulbyte = $nul . $nul . $nul . $nul; - $ntppacket = chr(0xd9) . $nul . chr(0x0a) . chr(0xfa); - - /* - * Root delay - * - * Indicates the total roundtrip delay to the primary reference - * source at the root of the synchronization subnet, in seconds - */ - $ntppacket .= $nul . $nul . chr(0x1c) . chr(0x9b); - - /* - * Clock Dispersion - * - * Indicates the maximum error relative to the primary reference source at the - * root of the synchronization subnet, in seconds - */ - $ntppacket .= $nul . chr(0x08) . chr(0xd7) . chr(0xff); - - /* - * ReferenceClockID - * - * Identifying the particular reference clock - */ - $ntppacket .= $nulbyte; - - /* - * The local time, in timestamp format, at the peer when its latest NTP message - * was sent. Contanis an integer and a fractional part - */ - $ntppacket .= chr($secba) . chr($secbb) . chr($secbc) . chr($secbd); - $ntppacket .= chr($fracba) . chr($fracbb) . chr($fracbc) . chr($fracbd); - - /* - * The local time, in timestamp format, at the peer. Contains an integer - * and a fractional part. - */ - $ntppacket .= $nulbyte; - $ntppacket .= $nulbyte; - - /* - * This is the local time, in timestamp format, when the latest NTP message from - * the peer arrived. Contanis an integer and a fractional part. - */ - $ntppacket .= $nulbyte; - $ntppacket .= $nulbyte; - - /* - * The local time, in timestamp format, at which the - * NTP message departed the sender. Contanis an integer - * and a fractional part. - */ - $ntppacket .= chr($secba) . chr($secbb) . chr($secbc) . chr($secbd); - $ntppacket .= chr($fracba) . chr($fracbb) . chr($fracbc) . chr($fracbd); - - return $ntppacket; - } - - /** - * Calculates a 32bit integer - * - * @param string $input - * @return integer - */ - protected function _getInteger($input) - { - $f1 = str_pad(ord($input[0]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[1]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[2]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[3]), 2, '0', STR_PAD_LEFT); - return (int) $f1; - } - - /** - * Calculates a 32bit signed fixed point number - * - * @param string $input - * @return float - */ - protected function _getFloat($input) - { - $f1 = str_pad(ord($input[0]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[1]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[2]), 2, '0', STR_PAD_LEFT); - $f1 .= str_pad(ord($input[3]), 2, '0', STR_PAD_LEFT); - $f2 = $f1 >> 17; - $f3 = ($f1 & 0x0001FFFF); - $f1 = $f2 . '.' . $f3; - return (float) $f1; - } - - /** - * Calculates a 64bit timestamp - * - * @param string $input - * @return float - */ - protected function _getTimestamp($input) - { - $f1 = (ord($input[0]) * pow(256, 3)); - $f1 += (ord($input[1]) * pow(256, 2)); - $f1 += (ord($input[2]) * pow(256, 1)); - $f1 += (ord($input[3])); - $f1 -= 2208988800; - - $f2 = (ord($input[4]) * pow(256, 3)); - $f2 += (ord($input[5]) * pow(256, 2)); - $f2 += (ord($input[6]) * pow(256, 1)); - $f2 += (ord($input[7])); - - return (float) ($f1 . "." . $f2); - } - - /** - * Reads the data returned from the timeserver - * - * This will return an array with binary data listing: - * - * @return array - * @throws Zend_TimeSync_Exception When timeserver can not be connected - */ - protected function _read() - { - $flags = ord(fread($this->_socket, 1)); - $info = stream_get_meta_data($this->_socket); - - if ($info['timed_out'] === true) { - fclose($this->_socket); - throw new Zend_TimeSync_Exception('could not connect to ' . - "'$this->_timeserver' on port '$this->_port', reason: 'server timed out'"); - } - - $result = array( - 'flags' => $flags, - 'stratum' => ord(fread($this->_socket, 1)), - 'poll' => ord(fread($this->_socket, 1)), - 'precision' => ord(fread($this->_socket, 1)), - 'rootdelay' => $this->_getFloat(fread($this->_socket, 4)), - 'rootdispersion' => $this->_getFloat(fread($this->_socket, 4)), - 'referenceid' => fread($this->_socket, 4), - 'referencestamp' => $this->_getTimestamp(fread($this->_socket, 8)), - 'originatestamp' => $this->_getTimestamp(fread($this->_socket, 8)), - 'receivestamp' => $this->_getTimestamp(fread($this->_socket, 8)), - 'transmitstamp' => $this->_getTimestamp(fread($this->_socket, 8)), - 'clientreceived' => microtime(true) - ); - - $this->_disconnect(); - return $result; - } - - /** - * Sends the NTP packet to the server - * - * @param string $data Data to send to the timeserver - * @return void - */ - protected function _write($data) - { - $this->_connect(); - - fwrite($this->_socket, $data); - stream_set_timeout($this->_socket, Zend_TimeSync::$options['timeout']); - } - - /** - * Extracts the binary data returned from the timeserver - * - * @param string|array $binary Data returned from the timeserver - * @return integer Difference in seconds - */ - protected function _extract($binary) - { - /* - * Leap Indicator bit 1100 0000 - * - * Code warning of impending leap-second to be inserted at the end of - * the last day of the current month. - */ - $leap = ($binary['flags'] & 0xc0) >> 6; - switch($leap) { - case 0: - $this->_info['leap'] = '0 - no warning'; - break; - - case 1: - $this->_info['leap'] = '1 - last minute has 61 seconds'; - break; - - case 2: - $this->_info['leap'] = '2 - last minute has 59 seconds'; - break; - - default: - $this->_info['leap'] = '3 - not syncronised'; - break; - } - - /* - * Version Number bit 0011 1000 - * - * This should be 3 (RFC 1305) - */ - $this->_info['version'] = ($binary['flags'] & 0x38) >> 3; - - /* - * Mode bit 0000 0111 - * - * Except in broadcast mode, an NTP association is formed when two peers - * exchange messages and one or both of them create and maintain an - * instantiation of the protocol machine, called an association. - */ - $mode = ($binary['flags'] & 0x07); - switch($mode) { - case 1: - $this->_info['mode'] = 'symetric active'; - break; - - case 2: - $this->_info['mode'] = 'symetric passive'; - break; - - case 3: - $this->_info['mode'] = 'client'; - break; - - case 4: - $this->_info['mode'] = 'server'; - break; - - case 5: - $this->_info['mode'] = 'broadcast'; - break; - - default: - $this->_info['mode'] = 'reserved'; - break; - } - - $ntpserviceid = 'Unknown Stratum ' . $binary['stratum'] . ' Service'; - - /* - * Reference Clock Identifier - * - * Identifies the particular reference clock. - */ - $refid = strtoupper($binary['referenceid']); - switch($binary['stratum']) { - case 0: - if (substr($refid, 0, 3) === 'DCN') { - $ntpserviceid = 'DCN routing protocol'; - } else if (substr($refid, 0, 4) === 'NIST') { - $ntpserviceid = 'NIST public modem'; - } else if (substr($refid, 0, 3) === 'TSP') { - $ntpserviceid = 'TSP time protocol'; - } else if (substr($refid, 0, 3) === 'DTS') { - $ntpserviceid = 'Digital Time Service'; - } - break; - - case 1: - if (substr($refid, 0, 4) === 'ATOM') { - $ntpserviceid = 'Atomic Clock (calibrated)'; - } else if (substr($refid, 0, 3) === 'VLF') { - $ntpserviceid = 'VLF radio'; - } else if ($refid === 'CALLSIGN') { - $ntpserviceid = 'Generic radio'; - } else if (substr($refid, 0, 4) === 'LORC') { - $ntpserviceid = 'LORAN-C radionavigation'; - } else if (substr($refid, 0, 4) === 'GOES') { - $ntpserviceid = 'GOES UHF environment satellite'; - } else if (substr($refid, 0, 3) === 'GPS') { - $ntpserviceid = 'GPS UHF satellite positioning'; - } - break; - - default: - $ntpserviceid = ord(substr($binary['referenceid'], 0, 1)); - $ntpserviceid .= '.'; - $ntpserviceid .= ord(substr($binary['referenceid'], 1, 1)); - $ntpserviceid .= '.'; - $ntpserviceid .= ord(substr($binary['referenceid'], 2, 1)); - $ntpserviceid .= '.'; - $ntpserviceid .= ord(substr($binary['referenceid'], 3, 1)); - break; - } - - $this->_info['ntpid'] = $ntpserviceid; - - /* - * Stratum - * - * Indicates the stratum level of the local clock - */ - switch($binary['stratum']) { - case 0: - $this->_info['stratum'] = 'undefined'; - break; - - case 1: - $this->_info['stratum'] = 'primary reference'; - break; - - default: - $this->_info['stratum'] = 'secondary reference'; - break; - } - - /* - * Indicates the total roundtrip delay to the primary reference source at the - * root of the synchronization subnet, in seconds. - * - * Both positive and negative values, depending on clock precision and skew, are - * possible. - */ - $this->_info['rootdelay'] = $binary['rootdelay']; - - /* - * Indicates the maximum error relative to the primary reference source at the - * root of the synchronization subnet, in seconds. - * - * Only positive values greater than zero are possible. - */ - $this->_info['rootdispersion'] = $binary['rootdispersion']; - - /* - * The roundtrip delay of the peer clock relative to the local clock - * over the network path between them, in seconds. - * - * Note that this variable can take on both positive and negative values, - * depending on clock precision and skew-error accumulation. - */ - $this->_info['roundtrip'] = $binary['receivestamp']; - $this->_info['roundtrip'] -= $binary['originatestamp']; - $this->_info['roundtrip'] -= $binary['transmitstamp']; - $this->_info['roundtrip'] += $binary['clientreceived']; - $this->_info['roundtrip'] /= 2; - - // The offset of the peer clock relative to the local clock, in seconds. - $this->_info['offset'] = $binary['receivestamp']; - $this->_info['offset'] -= $binary['originatestamp']; - $this->_info['offset'] += $binary['transmitstamp']; - $this->_info['offset'] -= $binary['clientreceived']; - $this->_info['offset'] /= 2; - $time = (time() - $this->_info['offset']); - - return $time; - } -} diff --git a/lib/Zend/TimeSync/Protocol.php b/lib/Zend/TimeSync/Protocol.php deleted file mode 100644 index 12dc6d9f9ee..00000000000 --- a/lib/Zend/TimeSync/Protocol.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Abstract class definition for all timeserver protocols - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_TimeSync_Protocol -{ - /** - * Holds the current socket connection - * - * @var array - */ - protected $_socket; - - /** - * Exceptions that might have occured - * - * @var array - */ - protected $_exceptions; - - /** - * Hostname for timeserver - * - * @var string - */ - protected $_timeserver; - - /** - * Holds information passed/returned from timeserver - * - * @var array - */ - protected $_info = array(); - - /** - * Abstract method that prepares the data to send to the timeserver - * - * @return mixed - */ - abstract protected function _prepare(); - - /** - * Abstract method that reads the data returned from the timeserver - * - * @return mixed - */ - abstract protected function _read(); - - /** - * Abstract method that writes data to to the timeserver - * - * @param string $data Data to write - * @return void - */ - abstract protected function _write($data); - - /** - * Abstract method that extracts the binary data returned from the timeserver - * - * @param string|array $data Data returned from the timeserver - * @return integer - */ - abstract protected function _extract($data); - - /** - * Connect to the specified timeserver. - * - * @return void - * @throws Zend_TimeSync_Exception When the connection failed - */ - protected function _connect() - { - $socket = @fsockopen($this->_timeserver, $this->_port, $errno, $errstr, - Zend_TimeSync::$options['timeout']); - if ($socket === false) { - throw new Zend_TimeSync_Exception('could not connect to ' . - "'$this->_timeserver' on port '$this->_port', reason: '$errstr'"); - } - - $this->_socket = $socket; - } - - /** - * Disconnects from the peer, closes the socket. - * - * @return void - */ - protected function _disconnect() - { - @fclose($this->_socket); - $this->_socket = null; - } - - /** - * Return information sent/returned from the timeserver - * - * @return array - */ - public function getInfo() - { - if (empty($this->_info) === true) { - $this->_write($this->_prepare()); - $timestamp = $this->_extract($this->_read()); - } - - return $this->_info; - } - - /** - * Query this timeserver without using the fallback mechanism - * - * @param string|Zend_Locale $locale (Optional) Locale - * @return Zend_Date - */ - public function getDate($locale = null) - { - $this->_write($this->_prepare()); - $timestamp = $this->_extract($this->_read()); - - $date = new Zend_Date($this, null, $locale); - return $date; - } -} diff --git a/lib/Zend/TimeSync/Sntp.php b/lib/Zend/TimeSync/Sntp.php deleted file mode 100644 index 8d83e9a40bd..00000000000 --- a/lib/Zend/TimeSync/Sntp.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_TimeSync_Protocol - */ -#require_once 'Zend/TimeSync/Protocol.php'; - -/** - * SNTP Protocol handling class - * - * @category Zend - * @package Zend_TimeSync - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_TimeSync_Sntp extends Zend_TimeSync_Protocol -{ - /** - * Port number for this timeserver - * - * @var integer - */ - protected $_port = 37; - - /** - * Socket delay - * - * @var integer - */ - private $_delay; - - /** - * Class constructor, sets the timeserver and port number - * - * @param string $timeserver Timeserver to connect to - * @param integer $port Port of the timeserver when it differs from the default port - */ - public function __construct($timeserver, $port) - { - $this->_timeserver = 'udp://' . $timeserver; - if ($port !== null) { - $this->_port = $port; - } - } - - /** - * Prepares the data that will be send to the timeserver - * - * @return array - */ - protected function _prepare() - { - return "\n"; - } - - /** - * Reads the data returned from the timeserver - * - * @return string - */ - protected function _read() - { - $result = fread($this->_socket, 49); - $this->_delay = (($this->_delay - time()) / 2); - - return $result; - } - - /** - * Writes data to to the timeserver - * - * @param string $data Data to write to the timeserver - * @return void - */ - protected function _write($data) - { - $this->_connect(); - $this->_delay = time(); - fputs($this->_socket, $data); - } - - /** - * Extracts the data returned from the timeserver - * - * @param string $result Data to extract - * @return integer - */ - protected function _extract($result) - { - $dec = hexdec('7fffffff'); - $time = abs(($dec - hexdec(bin2hex($result))) - $dec); - $time -= 2208988800; - // Socket delay - $time -= $this->_delay; - - $this->_info['offset'] = $this->_delay; - - return $time; - } -} diff --git a/lib/Zend/Tool/Framework/Action/Base.php b/lib/Zend/Tool/Framework/Action/Base.php deleted file mode 100644 index 593d93204ab..00000000000 --- a/lib/Zend/Tool/Framework/Action/Base.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Action_Interface - */ -#require_once 'Zend/Tool/Framework/Action/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Action_Base implements Zend_Tool_Framework_Action_Interface -{ - - /** - * @var string - */ - protected $_name = null; - - /** - * constructor - - * - * @param unknown_type $options - */ - public function __construct($options = null) - { - if ($options !== null) { - if (is_string($options)) { - $this->setName($options); - } - // implement $options here in the future if this is needed - } - } - - /** - * setName() - * - * @param string $name - * @return Zend_Tool_Framework_Action_Base - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - if ($this->_name == null) { - $this->_name = $this->_parseName(); - } - return $this->_name; - } - - /** - * _parseName - internal method to determine the name of an action when one is not explicity provided. - * - * @param Zend_Tool_Framework_Action_Interface $action - * @return string - */ - protected function _parseName() - { - $className = get_class($this); - $actionName = substr($className, strrpos($className, '_')+1); - return $actionName; - } - -} diff --git a/lib/Zend/Tool/Framework/Action/Exception.php b/lib/Zend/Tool/Framework/Action/Exception.php deleted file mode 100644 index 63231e9ba66..00000000000 --- a/lib/Zend/Tool/Framework/Action/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Exception - */ -#require_once 'Zend/Tool/Framework/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Action_Exception extends Zend_Tool_Framework_Exception -{ - -} diff --git a/lib/Zend/Tool/Framework/Action/Interface.php b/lib/Zend/Tool/Framework/Action/Interface.php deleted file mode 100644 index 17f1ddb9e59..00000000000 --- a/lib/Zend/Tool/Framework/Action/Interface.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Action_Interface -{ - public function getName(); -} diff --git a/lib/Zend/Tool/Framework/Action/Repository.php b/lib/Zend/Tool/Framework/Action/Repository.php deleted file mode 100644 index a701f5967b6..00000000000 --- a/lib/Zend/Tool/Framework/Action/Repository.php +++ /dev/null @@ -1,138 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Action_Repository - implements Zend_Tool_Framework_Registry_EnabledInterface, IteratorAggregate, Countable -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * @var array - */ - protected $_actions = array(); - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - } - - /** - * addAction() - * - * @param Zend_Tool_Framework_Action_Interface $action - * @return Zend_Tool_Framework_Action_Repository - */ - public function addAction(Zend_Tool_Framework_Action_Interface $action, $overrideExistingAction = false) - { - $actionName = $action->getName(); - - if ($actionName == '' || $actionName == 'Base') { - #require_once 'Zend/Tool/Framework/Action/Exception.php'; - throw new Zend_Tool_Framework_Action_Exception('An action name for the provided action could not be determined.'); - } - - if (!$overrideExistingAction && array_key_exists(strtolower($actionName), $this->_actions)) { - #require_once 'Zend/Tool/Framework/Action/Exception.php'; - throw new Zend_Tool_Framework_Action_Exception('An action by the name ' . $actionName - . ' is already registered and $overrideExistingAction is set to false.'); - } - - $this->_actions[strtolower($actionName)] = $action; - return $this; - } - - /** - * process() - this is called when the client is done constructing (after init()) - * - * @return unknown - */ - public function process() - { - return null; - } - - /** - * getActions() - get all actions in the repository - * - * @return array - */ - public function getActions() - { - return $this->_actions; - } - - /** - * getAction() - get an action by a specific name - * - * @param string $actionName - * @return Zend_Tool_Framework_Action_Interface - */ - public function getAction($actionName) - { - if (!array_key_exists(strtolower($actionName), $this->_actions)) { - return null; - } - - return $this->_actions[strtolower($actionName)]; - } - - /** - * count() required by the Countable interface - * - * @return int - */ - public function count() - { - return count($this->_actions); - } - - /** - * getIterator() - get all actions, this supports the IteratorAggregate interface - * - * @return array - */ - public function getIterator() - { - return new ArrayIterator($this->_actions); - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Abstract.php b/lib/Zend/Tool/Framework/Client/Abstract.php deleted file mode 100644 index 8bb8d36a3c8..00000000000 --- a/lib/Zend/Tool/Framework/Client/Abstract.php +++ /dev/null @@ -1,333 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Loader_Autoloader - */ -#require_once 'Zend/Loader/Autoloader.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tool_Framework_Client_Abstract implements Zend_Tool_Framework_Registry_EnabledInterface -{ - - /** - * @var Zend_Tool_Framework_Registry - */ - protected $_registry = null; - - /** - * @var callback|null - */ - protected $_interactiveCallback = null; - - /** - * @var bool - */ - protected $_isInitialized = false; - - /** - * @var Zend_Log - */ - protected $_debugLogger = null; - - public function __construct($options = array()) - { - // require autoloader - Zend_Loader_Autoloader::getInstance(); - - // this might look goofy, but this is setting up the - // registry for dependency injection into the client - $registry = new Zend_Tool_Framework_Registry(); - $registry->setClient($this); - - // NOTE: at this moment, $this->_registry should contain the registry object - - if ($options) { - $this->setOptions($options); - } - } - - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $setMethodName = 'set' . $optionName; - if (method_exists($this, $setMethodName)) { - $this->{$setMethodName}($optionValue); - } - } - } - - /** - * getName() - Return the client name which can be used to - * query the manifest if need be. - * - * @return string The client name - */ - abstract public function getName(); - - /** - * initialized() - This will initialize the client for use - * - */ - public function initialize() - { - // if its already initialized, no need to initialize again - if ($this->_isInitialized) { - return; - } - - // run any preInit - $this->_preInit(); - - $manifest = $this->_registry->getManifestRepository(); - $manifest->addManifest(new Zend_Tool_Framework_Client_Manifest()); - - // setup the debug log - if (!$this->_debugLogger instanceof Zend_Log) { - #require_once 'Zend/Log.php'; - #require_once 'Zend/Log/Writer/Null.php'; - $this->_debugLogger = new Zend_Log(new Zend_Log_Writer_Null()); - } - - // let the loader load, then the repositories process whats been loaded - $this->_registry->getLoader()->load(); - - // process the action repository - $this->_registry->getActionRepository()->process(); - - // process the provider repository - $this->_registry->getProviderRepository()->process(); - - // process the manifest repository - $this->_registry->getManifestRepository()->process(); - - if ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface) { - #require_once 'Zend/Tool/Framework/Client/Interactive/InputHandler.php'; - } - - if ($this instanceof Zend_Tool_Framework_Client_Interactive_OutputInterface) { - $this->_registry->getResponse()->setContentCallback(array($this, 'handleInteractiveOutput')); - } - - } - - - /** - * This method should be implemented by the client implementation to - * construct and set custom inflectors, request and response objects. - */ - protected function _preInit() - { - } - - /** - * This method *must* be implemented by the client implementation to - * parse out and setup the request objects action, provider and parameter - * information. - */ - abstract protected function _preDispatch(); - - /** - * This method should be implemented by the client implementation to - * take the output of the response object and return it (in an client - * specific way) back to the Tooling Client. - */ - protected function _postDispatch() - { - } - - /** - * setRegistry() - Required by the Zend_Tool_Framework_Registry_EnabledInterface - * interface which ensures proper registry dependency resolution - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Client_Abstract - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * getRegistry(); - * - * @return Zend_Tool_Framework_Registry_Interface - */ - public function getRegistry() - { - return $this->_registry; - } - - /** - * hasInteractiveInput() - Convienence method for determining if this - * client can handle interactive input, and thus be able to run the - * promptInteractiveInput - * - * @return bool - */ - public function hasInteractiveInput() - { - return ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface); - } - - public function promptInteractiveInput($inputRequest) - { - if (!$this->hasInteractiveInput()) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('promptInteractive() cannot be called on a non-interactive client.'); - } - - $inputHandler = new Zend_Tool_Framework_Client_Interactive_InputHandler(); - $inputHandler->setClient($this); - $inputHandler->setInputRequest($inputRequest); - return $inputHandler->handle(); - - } - - /** - * This method should be called in order to "handle" a Tooling Client - * request that has come to the client that has been implemented. - */ - public function dispatch() - { - $this->initialize(); - - try { - - $this->_preDispatch(); - - if ($this->_registry->getRequest()->isDispatchable()) { - - if ($this->_registry->getRequest()->getActionName() == null) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Client failed to setup the action name.'); - } - - if ($this->_registry->getRequest()->getProviderName() == null) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Client failed to setup the provider name.'); - } - - $this->_handleDispatch(); - - } - - } catch (Exception $exception) { - $this->_registry->getResponse()->setException($exception); - } - - $this->_postDispatch(); - } - - public function convertToClientNaming($string) - { - return $string; - } - - public function convertFromClientNaming($string) - { - return $string; - } - - protected function _handleDispatch() - { - // get the provider repository - $providerRepository = $this->_registry->getProviderRepository(); - - $request = $this->_registry->getRequest(); - - // get the dispatchable provider signature - $providerSignature = $providerRepository->getProviderSignature($request->getProviderName()); - - // get the actual provider - $provider = $providerSignature->getProvider(); - - // ensure that we can pretend if this is a pretend request - if ($request->isPretend() && (!$provider instanceof Zend_Tool_Framework_Provider_Pretendable)) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Dispatcher error - provider does not support pretend'); - } - - // get the action name - $actionName = $this->_registry->getRequest()->getActionName(); - $specialtyName = $this->_registry->getRequest()->getSpecialtyName(); - - if (!$actionableMethod = $providerSignature->getActionableMethodByActionName($actionName, $specialtyName)) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Dispatcher error - actionable method not found'); - } - - // get the actual method and param information - $methodName = $actionableMethod['methodName']; - $methodParameters = $actionableMethod['parameterInfo']; - - // get the provider params - $requestParameters = $this->_registry->getRequest()->getProviderParameters(); - - // @todo This seems hackish, determine if there is a better way - $callParameters = array(); - foreach ($methodParameters as $methodParameterName => $methodParameterValue) { - if (!array_key_exists($methodParameterName, $requestParameters) && $methodParameterValue['optional'] == false) { - if ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface) { - $promptSting = $this->getMissingParameterPromptString($provider, $actionableMethod['action'], $methodParameterValue['name']); - $parameterPromptValue = $this->promptInteractiveInput($promptSting)->getContent(); - if ($parameterPromptValue == null) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Value supplied for required parameter "' . $methodParameterValue['name'] . '" is empty'); - } - $callParameters[] = $parameterPromptValue; - } else { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('A required parameter "' . $methodParameterValue['name'] . '" was not supplied.'); - } - } else { - $callParameters[] = (array_key_exists($methodParameterName, $requestParameters)) ? $requestParameters[$methodParameterName] : $methodParameterValue['default']; - } - } - - $this->_handleDispatchExecution($provider, $methodName, $callParameters); - } - - protected function _handleDispatchExecution($class, $methodName, $callParameters) - { - if (method_exists($class, $methodName)) { - call_user_func_array(array($class, $methodName), $callParameters); - } elseif (method_exists($class, $methodName . 'Action')) { - call_user_func_array(array($class, $methodName . 'Action'), $callParameters); - } else { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Not a supported method.'); - } - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Config.php b/lib/Zend/Tool/Framework/Client/Config.php deleted file mode 100644 index 740710377be..00000000000 --- a/lib/Zend/Tool/Framework/Client/Config.php +++ /dev/null @@ -1,244 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Config -{ - - protected $_configFilepath = null; - - /** - * @var Zend_Config - */ - protected $_config = null; - - /** - * @param array $options - */ - public function __config($options = array()) - { - if ($options) { - $this->setOptions($options); - } - } - - /** - * @param array $options - */ - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $setMethodName = 'set' . $optionName; - if (method_exists($this, $setMethodName)) { - $this->{$setMethodName}($optionValue); - } - } - } - - /** - * @param string $configFilepath - * @return Zend_Tool_Framework_Client_Config - */ - public function setConfigFilepath($configFilepath) - { - if (!file_exists($configFilepath)) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Provided path to config ' . $configFilepath . ' does not exist'); - } - - $this->_configFilepath = $configFilepath; - $this->loadConfig($configFilepath); - - return $this; - } - - /** - * Load the configuration from the given path. - * - * @param string $configFilepath - */ - protected function loadConfig($configFilepath) - { - $suffix = substr($configFilepath, -4); - - switch ($suffix) { - case '.ini': - #require_once 'Zend/Config/Ini.php'; - $this->_config = new Zend_Config_Ini($configFilepath, null, array('allowModifications' => true)); - break; - case '.xml': - #require_once 'Zend/Config/Xml.php'; - $this->_config = new Zend_Config_Xml($configFilepath, null, array('allowModifications' => true)); - break; - case '.php': - #require_once 'Zend/Config.php'; - $this->_config = new Zend_Config(include $configFilepath, true); - break; - default: - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Unknown config file type ' - . $suffix . ' at location ' . $configFilepath - ); - } - } - - /** - * Return the filepath of the configuration. - * - * @return string - */ - public function getConfigFilepath() - { - return $this->_configFilepath; - } - - /** - * Get a configuration value. - * - * @param string $name - * @param string $defaultValue - * @return mixed - */ - public function get($name, $defaultValue=null) - { - return $this->getConfigInstance()->get($name, $defaultValue); - } - - /** - * Get a configuration value - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - return $this->getConfigInstance()->{$name}; - } - - /** - * Check if a configuration value isset. - * - * @param string $name - * @return boolean - */ - public function __isset($name) - { - if($this->exists() == false) { - return false; - } - return isset($this->getConfigInstance()->{$name}); - } - - /** - * @param string $name - */ - public function __unset($name) - { - unset($this->getConfigInstance()->$name); - } - - /** - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) - { - return $this->getConfigInstance()->$name = $value; - } - - /** - * Check if the User profile has a configuration. - * - * @return bool - */ - public function exists() - { - return ($this->_config!==null); - } - - /** - * @throws Zend_Tool_Framework_Client_Exception - * @return Zend_Config - */ - public function getConfigInstance() - { - if(!$this->exists()) { - #require_once "Zend/Tool/Framework/Client/Exception.php"; - throw new Zend_Tool_Framework_Client_Exception("Client has no persistent configuration."); - } - - return $this->_config; - } - - /** - * Save changes to the configuration into persistence. - * - * @return bool - */ - public function save() - { - if($this->exists()) { - $writer = $this->getConfigWriter(); - $writer->write($this->getConfigFilepath(), $this->getConfigInstance(), true); - $this->loadConfig($this->getConfigFilepath()); - - return true; - } - return false; - } - - /** - * Get the config writer that corresponds to the current config file type. - * - * @return Zend_Config_Writer_FileAbstract - */ - protected function getConfigWriter() - { - $suffix = substr($this->getConfigFilepath(), -4); - switch($suffix) { - case '.ini': - #require_once "Zend/Config/Writer/Ini.php"; - $writer = new Zend_Config_Writer_Ini(); - $writer->setRenderWithoutSections(); - break; - case '.xml': - #require_once "Zend/Config/Writer/Xml.php"; - $writer = new Zend_Config_Writer_Xml(); - break; - case '.php': - #require_once "Zend/Config/Writer/Array.php"; - $writer = new Zend_Config_Writer_Array(); - break; - default: - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Unknown config file type ' - . $suffix . ' at location ' . $this->getConfigFilepath() - ); - } - return $writer; - } -} diff --git a/lib/Zend/Tool/Framework/Client/Console.php b/lib/Zend/Tool/Framework/Client/Console.php deleted file mode 100644 index 221d44f8b3e..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console.php +++ /dev/null @@ -1,312 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Client_Abstract - */ -#require_once 'Zend/Tool/Framework/Client/Abstract.php'; - -/** - * @see Zend_Tool_Framework_Client_Interactive_InputInterface - */ -#require_once 'Zend/Tool/Framework/Client/Interactive/InputInterface.php'; - -/** - * @see Zend_Tool_Framework_Client_Interactive_OutputInterface - */ -#require_once 'Zend/Tool/Framework/Client/Interactive/OutputInterface.php'; - -/** - * Zend_Tool_Framework_Client_Console - the CLI Client implementation for Zend_Tool_Framework - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * - * @todo methods need more API documentation. - */ -class Zend_Tool_Framework_Client_Console - extends Zend_Tool_Framework_Client_Abstract - implements Zend_Tool_Framework_Client_Interactive_InputInterface, - Zend_Tool_Framework_Client_Interactive_OutputInterface -{ - - /** - * @var array - */ - protected $_configOptions = null; - - /** - * @var array - */ - protected $_storageOptions = null; - - /** - * @var Zend_Filter_Word_CamelCaseToDash - */ - protected $_filterToClientNaming = null; - - /** - * @var Zend_Filter_Word_DashToCamelCase - */ - protected $_filterFromClientNaming = null; - - /** - * @var array - */ - protected $_classesToLoad = array(); - - /** - * main() - This is typically called from zf.php. This method is a - * self contained main() function. - * - */ - public static function main($options = array()) - { - $cliClient = new self($options); - $cliClient->dispatch(); - } - - /** - * getName() - return the name of the client, in this case 'console' - * - * @return string - */ - public function getName() - { - return 'console'; - } - - /** - * setConfigOptions() - * - * @param array $configOptions - */ - public function setConfigOptions($configOptions) - { - $this->_configOptions = $configOptions; - return $this; - } - - /** - * setStorageOptions() - * - * @param array $storageOptions - */ - public function setStorageOptions($storageOptions) - { - $this->_storageOptions = $storageOptions; - return $this; - } - - /** - * @param array $classesToLoad - */ - public function setClassesToLoad($classesToLoad) - { - $this->_classesToLoad = $classesToLoad; - return $this; - } - - /** - * _init() - Tasks processed before the constructor, generally setting up objects to use - * - */ - protected function _preInit() - { - $config = $this->_registry->getConfig(); - - if ($this->_configOptions != null) { - $config->setOptions($this->_configOptions); - } - - $storage = $this->_registry->getStorage(); - - if ($this->_storageOptions != null && isset($this->_storageOptions['directory'])) { - $storage->setAdapter( - new Zend_Tool_Framework_Client_Storage_Directory($this->_storageOptions['directory']) - ); - } - - // which classes are essential to initializing Zend_Tool_Framework_Client_Console - $classesToLoad = array( - 'Zend_Tool_Framework_Client_Console_Manifest', - 'Zend_Tool_Framework_System_Manifest' - ); - - if ($this->_classesToLoad) { - if (is_string($this->_classesToLoad)) { - $classesToLoad[] = $this->_classesToLoad; - } elseif (is_array($this->_classesToLoad)) { - $classesToLoad = array_merge($classesToLoad, $this->_classesToLoad); - } - } - - // add classes to the basic loader from the config file basicloader.classes.1 .. - if (isset($config->basicloader) && isset($config->basicloader->classes)) { - foreach ($config->basicloader->classes as $classKey => $className) { - array_push($classesToLoad, $className); - } - } - - $this->_registry->setLoader( - new Zend_Tool_Framework_Loader_BasicLoader(array('classesToLoad' => $classesToLoad)) - ); - - return; - } - - /** - * _preDispatch() - Tasks handed after initialization but before dispatching - * - */ - protected function _preDispatch() - { - $response = $this->_registry->getResponse(); - - $response->addContentDecorator(new Zend_Tool_Framework_Client_Console_ResponseDecorator_AlignCenter()); - $response->addContentDecorator(new Zend_Tool_Framework_Client_Console_ResponseDecorator_Indention()); - $response->addContentDecorator(new Zend_Tool_Framework_Client_Console_ResponseDecorator_Blockize()); - - if (function_exists('posix_isatty')) { - $response->addContentDecorator(new Zend_Tool_Framework_Client_Console_ResponseDecorator_Colorizer()); - } - - $response->addContentDecorator(new Zend_Tool_Framework_Client_Response_ContentDecorator_Separator()) - ->setDefaultDecoratorOptions(array('separator' => true)); - - $optParser = new Zend_Tool_Framework_Client_Console_ArgumentParser(); - $optParser->setArguments($_SERVER['argv']) - ->setRegistry($this->_registry) - ->parse(); - - return; - } - - /** - * _postDispatch() - Tasks handled after dispatching - * - */ - protected function _postDispatch() - { - $request = $this->_registry->getRequest(); - $response = $this->_registry->getResponse(); - - if ($response->isException()) { - $helpSystem = new Zend_Tool_Framework_Client_Console_HelpSystem(); - $helpSystem->setRegistry($this->_registry) - ->respondWithErrorMessage($response->getException()->getMessage(), $response->getException()) - ->respondWithSpecialtyAndParamHelp( - $request->getProviderName(), - $request->getActionName() - ); - } - - echo PHP_EOL; - return; - } - - /** - * handleInteractiveInputRequest() is required by the Interactive InputInterface - * - * - * @param Zend_Tool_Framework_Client_Interactive_InputRequest $inputRequest - * @return string - */ - public function handleInteractiveInputRequest(Zend_Tool_Framework_Client_Interactive_InputRequest $inputRequest) - { - fwrite(STDOUT, $inputRequest->getContent() . PHP_EOL . 'zf> '); - $inputContent = fgets(STDIN); - return rtrim($inputContent); // remove the return from the end of the string - } - - /** - * handleInteractiveOutput() is required by the Interactive OutputInterface - * - * This allows us to display output immediately from providers, rather - * than displaying it after the provider is done. - * - * @param string $output - */ - public function handleInteractiveOutput($output) - { - echo $output; - } - - /** - * getMissingParameterPromptString() - * - * @param Zend_Tool_Framework_Provider_Interface $provider - * @param Zend_Tool_Framework_Action_Interface $actionInterface - * @param string $missingParameterName - * @return string - */ - public function getMissingParameterPromptString(Zend_Tool_Framework_Provider_Interface $provider, Zend_Tool_Framework_Action_Interface $actionInterface, $missingParameterName) - { - return 'Please provide a value for $' . $missingParameterName; - } - - - /** - * convertToClientNaming() - * - * Convert words to client specific naming, in this case is lower, dash separated - * - * Filters are lazy-loaded. - * - * @param string $string - * @return string - */ - public function convertToClientNaming($string) - { - if (!$this->_filterToClientNaming) { - $filter = new Zend_Filter(); - $filter->addFilter(new Zend_Filter_Word_CamelCaseToDash()); - $filter->addFilter(new Zend_Filter_StringToLower()); - - $this->_filterToClientNaming = $filter; - } - - return $this->_filterToClientNaming->filter($string); - } - - /** - * convertFromClientNaming() - * - * Convert words from client specific naming to code naming - camelcased - * - * Filters are lazy-loaded. - * - * @param string $string - * @return string - */ - public function convertFromClientNaming($string) - { - if (!$this->_filterFromClientNaming) { - $this->_filterFromClientNaming = new Zend_Filter_Word_DashToCamelCase(); - } - - return $this->_filterFromClientNaming->filter($string); - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Console/ArgumentParser.php b/lib/Zend/Tool/Framework/Client/Console/ArgumentParser.php deleted file mode 100644 index 6b8d40ca96e..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/ArgumentParser.php +++ /dev/null @@ -1,539 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Console_GetOpt - */ -#require_once 'Zend/Console/Getopt.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Console_ArgumentParser implements Zend_Tool_Framework_Registry_EnabledInterface -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * Holds the manifest repository taken from the registry. - * - * @var Zend_Tool_Framework_Manifest_Repository - */ - protected $_manifestRepository = null; - - /** - * @var Zend_Tool_Framework_Client_Request - */ - protected $_request = null; - - /** - * @var Zend_Tool_Framework_Client_Response - */ - protected $_response = null; - - /**#@+ - * @var array - */ - protected $_argumentsOriginal = null; - protected $_argumentsWorking = null; - /**#@-*/ - - /** - * @var bool - */ - protected $_help = false; - protected $_helpKnownAction = false; - protected $_helpKnownProvider = false; - protected $_helpKnownSpecialty = false; - - - /** - * setArguments - * - * @param array $arguments - * @return Zend_Tool_Framework_Client_Console_ArgumentParser - */ - public function setArguments(Array $arguments) - { - $this->_argumentsOriginal = $this->_argumentsWorking = $arguments; - return $this; - } - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Client_Console_ArgumentParser - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - // get the client registry - $this->_registry = $registry; - - // set manifest repository, request, response for easy access - $this->_manifestRepository = $this->_registry->getManifestRepository(); - $this->_request = $this->_registry->getRequest(); - $this->_response = $this->_registry->getResponse(); - return $this; - } - - /** - * Parse() - This method does the work of parsing the arguments into the enpooint request, - * this will also (during help operations) fill the response in with information as needed - * - * @return null - */ - public function parse() - { - - if ($this->_request == null || $this->_response == null) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('The client registry must have both a request and response registered.'); - } - - // setup the help options - $helpResponseOptions = array(); - - // check to see if the first cli arg is the script name - if ($this->_argumentsWorking[0] == $_SERVER['SCRIPT_NAME' ]) { - array_shift($this->_argumentsWorking); - } - - // process global options - try { - $this->_parseGlobalPart(); - } catch (Zend_Tool_Framework_Client_Exception $exception) { - $this->_createHelpResponse(array('error' => $exception->getMessage())); - return; - } - - // ensure there are arguments left - if (count($this->_argumentsWorking) == 0) { - $this->_request->setDispatchable(false); // at this point request is not dispatchable - - // check to see if this was a help request - if ($this->_help) { - $this->_createHelpResponse(); - } else { - $this->_createHelpResponse(array('error' => 'An action and provider is required.')); - } - return; - } - - // process the action part of the command line - try { - $this->_parseActionPart(); - } catch (Zend_Tool_Framework_Client_Exception $exception) { - $this->_request->setDispatchable(false); - $this->_createHelpResponse(array('error' => $exception->getMessage())); - return; - } - - if ($this->_helpKnownAction) { - $helpResponseOptions = array_merge( - $helpResponseOptions, - array('actionName' => $this->_request->getActionName()) - ); - } - - /* @TODO Action Parameter Requirements */ - - // make sure there are more "words" on the command line - if (count($this->_argumentsWorking) == 0) { - $this->_request->setDispatchable(false); // at this point request is not dispatchable - - // check to see if this is a help request - if ($this->_help) { - $this->_createHelpResponse($helpResponseOptions); - } else { - $this->_createHelpResponse(array_merge($helpResponseOptions, array('error' => 'A provider is required.'))); - } - return; - } - - - // process the provider part of the command line - try { - $this->_parseProviderPart(); - } catch (Zend_Tool_Framework_Client_Exception $exception) { - $this->_request->setDispatchable(false); - $this->_createHelpResponse(array('error' => $exception->getMessage())); - return; - } - - if ($this->_helpKnownProvider) { - $helpResponseOptions = array_merge( - $helpResponseOptions, - array('providerName' => $this->_request->getProviderName()) - ); - } - - if ($this->_helpKnownSpecialty) { - $helpResponseOptions = array_merge( - $helpResponseOptions, - array('specialtyName' => $this->_request->getSpecialtyName()) - ); - } - - // if there are arguments on the command line, lets process them as provider options - if (count($this->_argumentsWorking) != 0) { - $this->_parseProviderOptionsPart(); - } - - // if there is still arguments lingering around, we can assume something is wrong - if (count($this->_argumentsWorking) != 0) { - $this->_request->setDispatchable(false); // at this point request is not dispatchable - if ($this->_help) { - $this->_createHelpResponse($helpResponseOptions); - } else { - $this->_createHelpResponse(array_merge( - $helpResponseOptions, - array('error' => 'Unknown arguments left on the command line: ' . implode(' ', $this->_argumentsWorking)) - )); - } - return; - } - - // everything was processed and this is a request for help information - if ($this->_help) { - $this->_request->setDispatchable(false); // at this point request is not dispatchable - $this->_createHelpResponse($helpResponseOptions); - } - - return; - } - - /** - * Internal routine for parsing global options from the command line - * - * @return null - */ - protected function _parseGlobalPart() - { - $getoptOptions = array(); - $getoptOptions['help|h'] = 'HELP'; - $getoptOptions['verbose|v'] = 'VERBOSE'; - $getoptOptions['pretend|p'] = 'PRETEND'; - $getoptOptions['debug|d'] = 'DEBUG'; - $getoptParser = new Zend_Console_Getopt($getoptOptions, $this->_argumentsWorking, array('parseAll' => false)); - - // @todo catch any exceptions here - $getoptParser->parse(); - - foreach ($getoptParser->getOptions() as $option) { - if ($option == 'pretend') { - $this->_request->setPretend(true); - } elseif ($option == 'debug') { - $this->_request->setDebug(true); - } elseif ($option == 'verbose') { - $this->_request->setVerbose(true); - } else { - $property = '_'.$option; - $this->{$property} = true; - } - } - - $this->_argumentsWorking = $getoptParser->getRemainingArgs(); - - return; - } - - /** - * Internal routine for parsing the action name from the arguments - * - * @return null - */ - protected function _parseActionPart() - { - // the next "word" should be the action name - $consoleActionName = array_shift($this->_argumentsWorking); - - if ($consoleActionName == '?') { - $this->_help = true; - return; - } - - $actionSearchCriteria = array( - 'type' => 'Tool', - 'name' => 'actionName', - 'value' => $consoleActionName, - 'clientName' => 'console' - ); - - // is the action name valid? - $actionMetadata = $this->_manifestRepository->getMetadata($actionSearchCriteria); - - // check for normalized names as well (all lower, no separators) - if (!$actionMetadata) { - $actionSearchCriteria['name'] = 'normalizedActionName'; - $actionSearchCriteria['value'] = strtolower(str_replace(array('-', '_'), '', $consoleActionName)); - $actionSearchCriteria['clientName'] = 'all'; - $actionMetadata = $this->_manifestRepository->getMetadata($actionSearchCriteria); - } - - // if no action, handle error - if (!$actionMetadata) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('Action \'' . $consoleActionName . '\' is not a valid action.'); - } - - // prepare action request name - $this->_helpKnownAction = true; - $this->_request->setActionName($actionMetadata->getActionName()); - return; - } - - /** - * Internal routine for parsing the provider part of the command line arguments - * - * @return null - */ - protected function _parseProviderPart() - { - // get the cli "word" as the provider name from command line - $consoleProviderFull = array_shift($this->_argumentsWorking); - $consoleSpecialtyName = '_global'; - - // if there is notation for specialties? If so, break them up - if (strstr($consoleProviderFull, '.')) { - list($consoleProviderName, $consoleSpecialtyName) = explode('.', $consoleProviderFull); - } else { - $consoleProviderName = $consoleProviderFull; - } - - if ($consoleProviderName == '?') { - $this->_help = true; - return; - } - - $providerSearchCriteria = array( - 'type' => 'Tool', - 'name' => 'providerName', - 'value' => $consoleProviderName, - 'clientName' => 'console' - ); - - // get the cli provider names from the manifest - $providerMetadata = $this->_manifestRepository->getMetadata($providerSearchCriteria); - - // check for normalized names as well (all lower, no separators) - if (!$providerMetadata) { - $providerSearchCriteria['name'] = 'normalizedProviderName'; - $providerSearchCriteria['value'] = strtolower(str_replace(array('-', '_'), '', $consoleProviderName)); - $providerSearchCriteria['clientName'] = 'all'; - $providerMetadata = $this->_manifestRepository->getMetadata($providerSearchCriteria); - } - - if (!$providerMetadata) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception( - 'Provider \'' . $consoleProviderFull . '\' is not a valid provider.' - ); - } - - $this->_helpKnownProvider = true; - $this->_request->setProviderName($providerMetadata->getProviderName()); - - if ($consoleSpecialtyName == '?') { - $this->_help = true; - return; - } - - $providerSpecialtySearchCriteria = array( - 'type' => 'Tool', - 'name' => 'specialtyName', - 'value' => $consoleSpecialtyName, - 'providerName' => $providerMetadata->getProviderName(), - 'clientName' => 'console' - ); - - $providerSpecialtyMetadata = $this->_manifestRepository->getMetadata($providerSpecialtySearchCriteria); - - if (!$providerSpecialtyMetadata) { - $providerSpecialtySearchCriteria['name'] = 'normalizedSpecialtyName'; - $providerSpecialtySearchCriteria['value'] = strtolower(str_replace(array('-', '_'), '', $consoleSpecialtyName)); - $providerSpecialtySearchCriteria['clientName'] = 'all'; - $providerSpecialtyMetadata = $this->_manifestRepository->getMetadata($providerSpecialtySearchCriteria); - } - - if (!$providerSpecialtyMetadata) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception( - 'Provider \'' . $consoleSpecialtyName . '\' is not a valid specialty.' - ); - } - - $this->_helpKnownSpecialty = true; - $this->_request->setSpecialtyName($providerSpecialtyMetadata->getSpecialtyName()); - return; - } - - /** - * Internal routine for parsing the provider options from the command line - * - * @return null - */ - protected function _parseProviderOptionsPart() - { - if (current($this->_argumentsWorking) == '?') { - $this->_help = true; - return; - } - - $searchParams = array( - 'type' => 'Tool', - 'providerName' => $this->_request->getProviderName(), - 'actionName' => $this->_request->getActionName(), - 'specialtyName' => $this->_request->getSpecialtyName(), - 'clientName' => 'console' - ); - - $actionableMethodLongParamsMetadata = $this->_manifestRepository->getMetadata( - array_merge($searchParams, array('name' => 'actionableMethodLongParams')) - ); - - $actionableMethodShortParamsMetadata = $this->_manifestRepository->getMetadata( - array_merge($searchParams, array('name' => 'actionableMethodShortParams')) - ); - - $paramNameShortValues = $actionableMethodShortParamsMetadata->getValue(); - - $getoptOptions = array(); - $wordArguments = array(); - $longParamCanonicalNames = array(); - - $actionableMethodLongParamsMetadataReference = $actionableMethodLongParamsMetadata->getReference(); - foreach ($actionableMethodLongParamsMetadata->getValue() as $parameterNameLong => $consoleParameterNameLong) { - $optionConfig = $consoleParameterNameLong . '|'; - - $parameterInfo = $actionableMethodLongParamsMetadataReference['parameterInfo'][$parameterNameLong]; - - // process ParameterInfo into array for command line option matching - if ($parameterInfo['type'] == 'string' || $parameterInfo['type'] == 'bool') { - $optionConfig .= $paramNameShortValues[$parameterNameLong] - . (($parameterInfo['optional']) ? '-' : '=') . 's'; - } elseif (in_array($parameterInfo['type'], array('int', 'integer', 'float'))) { - $optionConfig .= $paramNameShortValues[$parameterNameLong] - . (($parameterInfo['optional']) ? '-' : '=') . 'i'; - } else { - $optionConfig .= $paramNameShortValues[$parameterNameLong] . '-s'; - } - - $getoptOptions[$optionConfig] = ($parameterInfo['description'] != '') ? $parameterInfo['description'] : 'No description available.'; - - - // process ParameterInfo into array for command line WORD (argument) matching - $wordArguments[$parameterInfo['position']]['parameterName'] = $parameterInfo['name']; - $wordArguments[$parameterInfo['position']]['optional'] = $parameterInfo['optional']; - $wordArguments[$parameterInfo['position']]['type'] = $parameterInfo['type']; - - // keep a translation of console to canonical names - $longParamCanonicalNames[$consoleParameterNameLong] = $parameterNameLong; - } - - - if (!$getoptOptions) { - // no options to parse here, return - return; - } - - // if non-option arguments exist, attempt to process them before processing options - $wordStack = array(); - while (($wordOnTop = array_shift($this->_argumentsWorking))) { - if (substr($wordOnTop, 0, 1) != '-') { - array_push($wordStack, $wordOnTop); - } else { - // put word back on stack and move on - array_unshift($this->_argumentsWorking, $wordOnTop); - break; - } - - if (count($wordStack) == count($wordArguments)) { - // when we get at most the number of arguments we are expecting - // then break out. - break; - } - - } - - if ($wordStack && $wordArguments) { - for ($wordIndex = 1; $wordIndex <= count($wordArguments); $wordIndex++) { - if (!array_key_exists($wordIndex-1, $wordStack) || !array_key_exists($wordIndex, $wordArguments)) { - break; - } - $this->_request->setProviderParameter($wordArguments[$wordIndex]['parameterName'], $wordStack[$wordIndex-1]); - unset($wordStack[$wordIndex-1]); - } - } - - $getoptParser = new Zend_Console_Getopt($getoptOptions, $this->_argumentsWorking, array('parseAll' => false)); - $getoptParser->parse(); - foreach ($getoptParser->getOptions() as $option) { - $value = $getoptParser->getOption($option); - $providerParamOption = $longParamCanonicalNames[$option]; - $this->_request->setProviderParameter($providerParamOption, $value); - } - - $this->_argumentsWorking = $getoptParser->getRemainingArgs(); - - return; - } - - /** - * _createHelpResponse - * - * @param unknown_type $options - */ - protected function _createHelpResponse($options = array()) - { - #require_once 'Zend/Tool/Framework/Client/Console/HelpSystem.php'; - $helpSystem = new Zend_Tool_Framework_Client_Console_HelpSystem(); - $helpSystem->setRegistry($this->_registry); - - if (isset($options['error'])) { - $helpSystem->respondWithErrorMessage($options['error']); - } - - if (isset($options['actionName']) && isset($options['providerName'])) { - $helpSystem->respondWithSpecialtyAndParamHelp($options['providerName'], $options['actionName']); - } elseif (isset($options['actionName'])) { - $helpSystem->respondWithActionHelp($options['actionName']); - } elseif (isset($options['providerName'])) { - $helpSystem->respondWithProviderHelp($options['providerName']); - } else { - $helpSystem->respondWithGeneralHelp(); - } - - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Console/HelpSystem.php b/lib/Zend/Tool/Framework/Client/Console/HelpSystem.php deleted file mode 100644 index b2c97271026..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/HelpSystem.php +++ /dev/null @@ -1,378 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Console_HelpSystem -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * @var Zend_Tool_Framework_Client_Response - */ - protected $_response = null; - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - $this->_response = $registry->getResponse(); - return $this; - } - - /** - * respondWithErrorMessage() - * - * @param string $errorMessage - * @param Exception $exception - */ - public function respondWithErrorMessage($errorMessage, Exception $exception = null) - { - // break apart the message into wrapped chunks - $errorMessages = explode(PHP_EOL, wordwrap($errorMessage, 70, PHP_EOL, false)); - - $text = 'An Error Has Occurred'; - $this->_response->appendContent($text, array('color' => array('hiWhite', 'bgRed'), 'aligncenter' => true)); - $this->_response->appendContent($errorMessage, array('indention' => 1, 'blockize' => 72, 'color' => array('white', 'bgRed'))); - - if ($exception && $this->_registry->getRequest()->isDebug()) { - $this->_response->appendContent($exception->getTraceAsString()); - } - - $this->_response->appendContent(null, array('separator' => true)); - return $this; - } - - /** - * respondWithGeneralHelp() - * - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - public function respondWithGeneralHelp() - { - $this->_respondWithHeader(); - - $noSeparator = array('separator' => false); - - $this->_response->appendContent('Usage:', array('color' => 'green')) - ->appendContent(' ', $noSeparator) - ->appendContent('zf', array_merge(array('color' => 'cyan'), $noSeparator)) - ->appendContent(' [--global-opts]', $noSeparator) - ->appendContent(' action-name', array_merge(array('color' => 'cyan'), $noSeparator)) - ->appendContent(' [--action-opts]', $noSeparator) - ->appendContent(' provider-name', array_merge(array('color' => 'cyan'), $noSeparator)) - ->appendContent(' [--provider-opts]', $noSeparator) - ->appendContent(' [provider parameters ...]') - ->appendContent(' Note: You may use "?" in any place of the above usage string to ask for more specific help information.', array('color'=>'yellow')) - ->appendContent(' Example: "zf ? version" will list all available actions for the version provider.', array('color'=>'yellow', 'separator' => 2)) - ->appendContent('Providers and their actions:', array('color' => 'green')); - - $this->_respondWithSystemInformation(); - return $this; - } - - /** - * respondWithActionHelp() - * - * @param string $actionName - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - public function respondWithActionHelp($actionName) - { - $this->_respondWithHeader(); - $this->_response->appendContent('Providers that support the action "' . $actionName . '"', array('color' => 'green')); - $this->_respondWithSystemInformation(null, $actionName); - return $this; - } - - /** - * respondWithSpecialtyAndParamHelp() - * - * @param string $providerName - * @param string $actionName - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - public function respondWithSpecialtyAndParamHelp($providerName, $actionName) - { - $this->_respondWithHeader(); - $this->_response->appendContent( - 'Details for action "' . $actionName . '" and provider "' . $providerName . '"', - array('color' => 'green') - ); - $this->_respondWithSystemInformation($providerName, $actionName, true); - return $this; - } - - /** - * respondWithProviderHelp() - * - * @param string $providerName - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - public function respondWithProviderHelp($providerName) - { - $this->_respondWithHeader(); - $this->_response->appendContent('Actions supported by provider "' . $providerName . '"', array('color' => 'green')); - $this->_respondWithSystemInformation($providerName); - return $this; - } - - /** - * _respondWithHeader() - * - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - protected function _respondWithHeader() - { - /** - * @see Zend_Version - */ - #require_once 'Zend/Version.php'; - $this->_response->appendContent('Zend Framework', array('color' => array('hiWhite'), 'separator' => false)); - $this->_response->appendContent(' Command Line Console Tool v' . Zend_Version::VERSION . ''); - return $this; - } - - /** - * _respondWithSystemInformation() - * - * @param string $providerNameFilter - * @param string $actionNameFilter - * @param bool $includeAllSpecialties - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - protected function _respondWithSystemInformation($providerNameFilter = null, $actionNameFilter = null, $includeAllSpecialties = false) - { - $manifest = $this->_registry->getManifestRepository(); - - $providerMetadatasSearch = array( - 'type' => 'Tool', - 'name' => 'providerName', - 'clientName' => 'console' - ); - - if (is_string($providerNameFilter)) { - $providerMetadatasSearch = array_merge($providerMetadatasSearch, array('providerName' => $providerNameFilter)); - } - - $actionMetadatasSearch = array( - 'type' => 'Tool', - 'name' => 'actionName', - 'clientName' => 'console' - ); - - if (is_string($actionNameFilter)) { - $actionMetadatasSearch = array_merge($actionMetadatasSearch, array('actionName' => $actionNameFilter)); - } - - // get the metadata's for the things to display - $displayProviderMetadatas = $manifest->getMetadatas($providerMetadatasSearch); - $displayActionMetadatas = $manifest->getMetadatas($actionMetadatasSearch); - - // create index of actionNames - for ($i = 0; $i < count($displayActionMetadatas); $i++) { - $displayActionNames[] = $displayActionMetadatas[$i]->getActionName(); - } - - foreach ($displayProviderMetadatas as $providerMetadata) { - - $providerNameDisplayed = false; - - $providerName = $providerMetadata->getProviderName(); - $providerSignature = $providerMetadata->getReference(); - - foreach ($providerSignature->getActions() as $actionInfo) { - - $actionName = $actionInfo->getName(); - - // check to see if this action name is valid - if (($foundActionIndex = array_search($actionName, $displayActionNames)) === false) { - continue; - } else { - $actionMetadata = $displayActionMetadatas[$foundActionIndex]; - } - - $specialtyMetadata = $manifest->getMetadata(array( - 'type' => 'Tool', - 'name' => 'specialtyName', - 'providerName' => $providerName, - 'specialtyName' => '_Global', - 'clientName' => 'console' - )); - - // lets do the main _Global action first - $actionableGlobalLongParamMetadata = $manifest->getMetadata(array( - 'type' => 'Tool', - 'name' => 'actionableMethodLongParams', - 'providerName' => $providerName, - 'specialtyName' => '_Global', - 'actionName' => $actionName, - 'clientName' => 'console' - )); - - $actionableGlobalMetadatas = $manifest->getMetadatas(array( - 'type' => 'Tool', - 'name' => 'actionableMethodLongParams', - 'providerName' => $providerName, - 'actionName' => $actionName, - 'clientName' => 'console' - )); - - if ($actionableGlobalLongParamMetadata) { - - if (!$providerNameDisplayed) { - $this->_respondWithProviderName($providerMetadata); - $providerNameDisplayed = true; - } - - $this->_respondWithCommand($providerMetadata, $actionMetadata, $specialtyMetadata, $actionableGlobalLongParamMetadata); - - $actionIsGlobal = true; - } else { - $actionIsGlobal = false; - } - - // check for providers without a _Global action - $isSingleSpecialProviderAction = false; - if (!$actionIsGlobal && count($actionableGlobalMetadatas) == 1) { - $isSingleSpecialProviderAction = true; - $this->_respondWithProviderName($providerMetadata); - $providerNameDisplayed = true; - } - - if ($includeAllSpecialties || $isSingleSpecialProviderAction) { - - foreach ($providerSignature->getSpecialties() as $specialtyName) { - - if ($specialtyName == '_Global') { - continue; - } - - $specialtyMetadata = $manifest->getMetadata(array( - 'type' => 'Tool', - 'name' => 'specialtyName', - 'providerName' => $providerMetadata->getProviderName(), - 'specialtyName' => $specialtyName, - 'clientName' => 'console' - )); - - $actionableSpecialtyLongMetadata = $manifest->getMetadata(array( - 'type' => 'Tool', - 'name' => 'actionableMethodLongParams', - 'providerName' => $providerMetadata->getProviderName(), - 'specialtyName' => $specialtyName, - 'actionName' => $actionName, - 'clientName' => 'console' - )); - - if($actionableSpecialtyLongMetadata) { - $this->_respondWithCommand($providerMetadata, $actionMetadata, $specialtyMetadata, $actionableSpecialtyLongMetadata); - } - - } - } - - // reset the special flag for single provider action with specialty - $isSingleSpecialProviderAction = false; - - if (!$includeAllSpecialties && count($actionableGlobalMetadatas) > 1) { - $this->_response->appendContent(' Note: There are specialties, use ', array('color' => 'yellow', 'separator' => false)); - $this->_response->appendContent( - 'zf ' . $actionMetadata->getValue() . ' ' . $providerMetadata->getValue() . '.?', - array('color' => 'cyan', 'separator' => false) - ); - $this->_response->appendContent(' to get specific help on them.', array('color' => 'yellow')); - } - - } - - if ($providerNameDisplayed) { - $this->_response->appendContent(null, array('separator' => true)); - } - } - return $this; - } - - /** - * _respondWithProviderName() - * - * @param Zend_Tool_Framework_Metadata_Tool $providerMetadata - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - protected function _respondWithProviderName(Zend_Tool_Framework_Metadata_Tool $providerMetadata) - { - $this->_response->appendContent(' ' . $providerMetadata->getProviderName()); - return $this; - } - - /** - * _respondWithCommand() - * - * @param Zend_Tool_Framework_Metadata_Tool $providerMetadata - * @param Zend_Tool_Framework_Metadata_Tool $actionMetadata - * @param Zend_Tool_Framework_Metadata_Tool $specialtyMetadata - * @param Zend_Tool_Framework_Metadata_Tool $parameterLongMetadata - * @return Zend_Tool_Framework_Client_Console_HelpSystem - */ - protected function _respondWithCommand( - Zend_Tool_Framework_Metadata_Tool $providerMetadata, - Zend_Tool_Framework_Metadata_Tool $actionMetadata, - Zend_Tool_Framework_Metadata_Tool $specialtyMetadata, - Zend_Tool_Framework_Metadata_Tool $parameterLongMetadata)//, - //Zend_Tool_Framework_Metadata_Tool $parameterShortMetadata) - { - $this->_response->appendContent( - ' zf ' . $actionMetadata->getValue() . ' ' . $providerMetadata->getValue(), - array('color' => 'cyan', 'separator' => false) - ); - - if ($specialtyMetadata->getSpecialtyName() != '_Global') { - $this->_response->appendContent('.' . $specialtyMetadata->getValue(), array('color' => 'cyan', 'separator' => false)); - } - - foreach ($parameterLongMetadata->getValue() as $paramName => $consoleParamName) { - $methodInfo = $parameterLongMetadata->getReference(); - $paramString = ' ' . $consoleParamName; - if ( ($defaultValue = $methodInfo['parameterInfo'][$paramName]['default']) != null) { - $paramString .= '[=' . $defaultValue . ']'; - } - $this->_response->appendContent($paramString . '', array('separator' => false)); - } - - $this->_response->appendContent(null, array('separator' => true)); - return $this; - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Console/Manifest.php b/lib/Zend/Tool/Framework/Client/Console/Manifest.php deleted file mode 100644 index 82554b99a0a..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/Manifest.php +++ /dev/null @@ -1,209 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Manifest_MetadataManifestable - */ -#require_once 'Zend/Tool/Framework/Manifest/MetadataManifestable.php'; - -/** - * @see Zend_Filter - */ -#require_once 'Zend/Filter.php'; - -/** - * @see Zend_Filter_Word_CamelCaseToDash - */ -#require_once 'Zend/Filter/Word/CamelCaseToDash.php'; - -/** - * @see Zend_Filter_StringToLower - */ -#require_once 'Zend/Filter/StringToLower.php'; - -/** - * @see Zend_Tool_Framework_Metadata_Tool - */ -#require_once 'Zend/Tool/Framework/Metadata/Tool.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * Zend_Tool_Framework_Client_ConsoleClient_Manifest - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Console_Manifest - implements Zend_Tool_Framework_Registry_EnabledInterface, - Zend_Tool_Framework_Manifest_MetadataManifestable -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * setRegistry() - Required for the Zend_Tool_Framework_Registry_EnabledInterface interface - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Client_Console_Manifest - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * getMetadata() is required by the Manifest Interface. - * - * These are the following metadatas that will be setup: - * - * actionName - * - metadata for actions - * - value will be a dashed name for the action named in 'actionName' - * providerName - * - metadata for providers - * - value will be a dashed-name for the provider named in 'providerName' - * providerSpecialtyNames - * - metadata for providers - * actionableMethodLongParameters - * - metadata for providers - * actionableMethodShortParameters - * - metadata for providers - * - * @return array Array of Metadatas - */ - public function getMetadata() - { - $metadatas = array(); - - // setup the camelCase to dashed filter to use since cli expects dashed named - $ccToDashedFilter = new Zend_Filter(); - $ccToDashedFilter - ->addFilter(new Zend_Filter_Word_CamelCaseToDash()) - ->addFilter(new Zend_Filter_StringToLower()); - - // get the registry to get the action and provider repository - $actionRepository = $this->_registry->getActionRepository(); - $providerRepository = $this->_registry->getProviderRepository(); - - // loop through all actions and create a metadata for each - foreach ($actionRepository->getActions() as $action) { - // each action metadata will be called - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'actionName', - 'value' => $ccToDashedFilter->filter($action->getName()), - 'reference' => $action, - 'actionName' => $action->getName(), - 'clientName' => 'console', - 'clientReference' => $this->_registry->getClient() - )); - } - - foreach ($providerRepository->getProviderSignatures() as $providerSignature) { - - // create the metadata for the provider's cliProviderName - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'providerName', - 'value' => $ccToDashedFilter->filter($providerSignature->getName()), - 'reference' => $providerSignature, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'clientReference' => $this->_registry->getClient() - )); - - // create the metadatas for the per provider specialites in providerSpecaltyNames - foreach ($providerSignature->getSpecialties() as $specialty) { - - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'specialtyName', - 'value' => $ccToDashedFilter->filter($specialty), - 'reference' => $providerSignature, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $specialty, - 'clientReference' => $this->_registry->getClient() - )); - - } - - // $actionableMethod is keyed by the methodName (but not used) - foreach ($providerSignature->getActionableMethods() as $actionableMethodData) { - - $methodLongParams = array(); - $methodShortParams = array(); - - // $actionableMethodData get both the long and short names - foreach ($actionableMethodData['parameterInfo'] as $parameterInfoData) { - - // filter to dashed - $methodLongParams[$parameterInfoData['name']] = $ccToDashedFilter->filter($parameterInfoData['name']); - - // simply lower the character, (its only 1 char after all) - $methodShortParams[$parameterInfoData['name']] = strtolower($parameterInfoData['name'][0]); - - } - - // create metadata for the long name cliActionableMethodLongParameters - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'actionableMethodLongParams', - 'value' => $methodLongParams, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $actionableMethodData['specialty'], - 'actionName' => $actionableMethodData['actionName'], - 'reference' => &$actionableMethodData, - 'clientReference' => $this->_registry->getClient() - )); - - // create metadata for the short name cliActionableMethodShortParameters - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'actionableMethodShortParams', - 'value' => $methodShortParams, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $actionableMethodData['specialty'], - 'actionName' => $actionableMethodData['actionName'], - 'reference' => &$actionableMethodData, - 'clientReference' => $this->_registry->getClient() - )); - - } - - } - - return $metadatas; - } - - public function getIndex() - { - return 10000; - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/AlignCenter.php b/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/AlignCenter.php deleted file mode 100644 index 6f3eafb5ec8..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/AlignCenter.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -#require_once "Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php"; - -/** - * Try to align a given text central on the screen. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Tool_Framework_Client_Console_ResponseDecorator_AlignCenter - implements Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - public function getName() - { - return "aligncenter"; - } - - /** - * @param string $content - * @param integer $lineLength - */ - public function decorate($content, $lineLength) - { - if(!is_numeric($lineLength)) { - $lineLength = 72; - } - if(strlen($content) < $lineLength) { - $append = false; - $len = strlen($content); - for($i = $len; $i < $lineLength; $i++) { - if($append == true) { - $content = $content." "; - $append = false; - } else { - $content = " ".$content; - $append = true; - } - } - } - return $content; - } -} diff --git a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Blockize.php b/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Blockize.php deleted file mode 100644 index 3161a7506bf..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Blockize.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -#require_once "Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php"; - -/** - * Take a text and block it into several lines of a fixed length. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Tool_Framework_Client_Console_ResponseDecorator_Blockize - implements Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - public function getName() - { - return 'blockize'; - } - - /** - * - * @param string $content - * @param int $lineLength - * @return string - */ - public function decorate($content, $lineLength) - { - if(intval(strval($lineLength)) != $lineLength) { - $lineLength = 72; - } - - // break apart the message into wrapped chunks - $lines = explode(PHP_EOL, wordwrap($content, $lineLength, PHP_EOL, false)); - $content = array(); - foreach($lines AS $line) { - if(strlen(trim($line)) == 0) { - continue; - } - - if(strlen($line) < $lineLength) { - $line .= str_repeat(" ", $lineLength-strlen($line)); - } - $content[] = $line; - } - return implode(PHP_EOL, $content); - } -} diff --git a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Colorizer.php b/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Colorizer.php deleted file mode 100644 index 5d83feaee1e..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Colorizer.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Console_ResponseDecorator_Colorizer - implements Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - - protected $_colorOptions = array( - // blacks - 'black' => '30m', - 'hiBlack' => '1;30m', - 'bgBlack' => '40m', - // reds - 'red' => '31m', - 'hiRed' => '1;31m', - 'bgRed' => '41m', - // greens - 'green' => '32m', - 'hiGreen' => '1;32m', - 'bgGreen' => '42m', - // yellows - 'yellow' => '33m', - 'hiYellow' => '1;33m', - 'bgYellow' => '43m', - // blues - 'blue' => '34m', - 'hiBlue' => '1;34m', - 'bgBlue' => '44m', - // magentas - 'magenta' => '35m', - 'hiMagenta' => '1;35m', - 'bgMagenta' => '45m', - // cyans - 'cyan' => '36m', - 'hiCyan' => '1;36m', - 'bgCyan' => '46m', - // whites - 'white' => '37m', - 'hiWhite' => '1;37m', - 'bgWhite' => '47m' - ); - - public function getName() - { - return 'color'; - } - - public function decorate($content, $color) - { - if (is_string($color)) { - $color = array($color); - } - - $newContent = ''; - - foreach ($color as $c) { - if (array_key_exists($c, $this->_colorOptions)) { - $newContent .= "\033[" . $this->_colorOptions[$c]; - } - } - - $newContent .= $content . "\033[m"; - - return $newContent; - } - - -} diff --git a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Indention.php b/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Indention.php deleted file mode 100644 index 5e9b3ab0aaa..00000000000 --- a/lib/Zend/Tool/Framework/Client/Console/ResponseDecorator/Indention.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once "Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php"; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Console_ResponseDecorator_Indention - implements Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - public function getName() - { - return 'indention'; - } - - /** - * @param string $content - * @param integer $indention - */ - public function decorate($content, $indention) - { - if(strval(intval($indention)) != $indention) { - return $content; - } - - $newContent = ""; - $lines = preg_split('((\r\n|\r|\n)+)', $content); - $lineIndention = str_repeat(' ', $indention); - foreach($lines AS $line) { - $newContent .= $lineIndention.$line.PHP_EOL; - } - return rtrim($newContent); - } -} diff --git a/lib/Zend/Tool/Framework/Client/Exception.php b/lib/Zend/Tool/Framework/Client/Exception.php deleted file mode 100644 index ef54a9d785b..00000000000 --- a/lib/Zend/Tool/Framework/Client/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Exception - */ -#require_once 'Zend/Tool/Framework/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Exception extends Zend_Tool_Framework_Exception -{ -} diff --git a/lib/Zend/Tool/Framework/Client/Interactive/InputHandler.php b/lib/Zend/Tool/Framework/Client/Interactive/InputHandler.php deleted file mode 100644 index 050c4dd7984..00000000000 --- a/lib/Zend/Tool/Framework/Client/Interactive/InputHandler.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Interactive_InputHandler -{ - - /** - * @var Zend_Tool_Framework_Client_Interactive_InputInterface - */ - protected $_client = null; - - protected $_inputRequest = null; - - public function setClient(Zend_Tool_Framework_Client_Interactive_InputInterface $client) - { - $this->_client = $client; - return $this; - } - - public function setInputRequest($inputRequest) - { - if (is_string($inputRequest)) { - #require_once 'Zend/Tool/Framework/Client/Interactive/InputRequest.php'; - $inputRequest = new Zend_Tool_Framework_Client_Interactive_InputRequest($inputRequest); - } elseif (!$inputRequest instanceof Zend_Tool_Framework_Client_Interactive_InputRequest) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('promptInteractive() requires either a string or an instance of Zend_Tool_Framework_Client_Interactive_InputRequest.'); - } - - $this->_inputRequest = $inputRequest; - return $this; - } - - public function handle() - { - $inputResponse = $this->_client->handleInteractiveInputRequest($this->_inputRequest); - - if (is_string($inputResponse)) { - #require_once 'Zend/Tool/Framework/Client/Interactive/InputResponse.php'; - $inputResponse = new Zend_Tool_Framework_Client_Interactive_InputResponse($inputResponse); - } elseif (!$inputResponse instanceof Zend_Tool_Framework_Client_Interactive_InputResponse) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('The registered $_interactiveCallback for the client must either return a string or an instance of Zend_Tool_Framework_Client_Interactive_InputResponse.'); - } - - return $inputResponse; - } - - -} diff --git a/lib/Zend/Tool/Framework/Client/Interactive/InputInterface.php b/lib/Zend/Tool/Framework/Client/Interactive/InputInterface.php deleted file mode 100644 index a12a833b54e..00000000000 --- a/lib/Zend/Tool/Framework/Client/Interactive/InputInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Client_Interactive_InputInterface -{ - - /** - * Handle Interactive Input Request - * - * @param Zend_Tool_Framework_Client_Interactive_InputRequest $inputRequest - * @return Zend_Tool_Framework_Client_Interactive_InputResponse|string - */ - public function handleInteractiveInputRequest(Zend_Tool_Framework_Client_Interactive_InputRequest $inputRequest); - - public function getMissingParameterPromptString(Zend_Tool_Framework_Provider_Interface $provider, Zend_Tool_Framework_Action_Interface $actionInterface, $missingParameterName); - -} diff --git a/lib/Zend/Tool/Framework/Client/Interactive/InputRequest.php b/lib/Zend/Tool/Framework/Client/Interactive/InputRequest.php deleted file mode 100644 index 5871bb1699c..00000000000 --- a/lib/Zend/Tool/Framework/Client/Interactive/InputRequest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Interactive_InputRequest -{ - protected $_content = null; - - public function __construct($content = null) - { - if ($content) { - $this->setContent($content); - } - } - - public function setContent($content) - { - $this->_content = $content; - return $this; - } - - public function getContent() - { - return $this->_content; - } - - public function __toString() - { - return $this->_content; - } -} diff --git a/lib/Zend/Tool/Framework/Client/Interactive/InputResponse.php b/lib/Zend/Tool/Framework/Client/Interactive/InputResponse.php deleted file mode 100644 index 5a68043855b..00000000000 --- a/lib/Zend/Tool/Framework/Client/Interactive/InputResponse.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Interactive_InputResponse -{ - - protected $_content = null; - - public function __construct($content = null) - { - if ($content) { - $this->setContent($content); - } - } - - public function setContent($content) - { - $this->_content = $content; - return $this; - } - - public function getContent() - { - return $this->_content; - } - - -} diff --git a/lib/Zend/Tool/Framework/Client/Interactive/OutputInterface.php b/lib/Zend/Tool/Framework/Client/Interactive/OutputInterface.php deleted file mode 100644 index 03ecfcc48dd..00000000000 --- a/lib/Zend/Tool/Framework/Client/Interactive/OutputInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Client_Interactive_OutputInterface -{ - - public function handleInteractiveOutput($string); - -} diff --git a/lib/Zend/Tool/Framework/Client/Manifest.php b/lib/Zend/Tool/Framework/Client/Manifest.php deleted file mode 100644 index 54a37f8bb73..00000000000 --- a/lib/Zend/Tool/Framework/Client/Manifest.php +++ /dev/null @@ -1,206 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Manifest_MetadataManifestable - */ -#require_once 'Zend/Tool/Framework/Manifest/MetadataManifestable.php'; - -/** - * @see Zend_Filter - */ -#require_once 'Zend/Filter.php'; - -/** - * @see Zend_Filter_Word_CamelCaseToDash - */ -#require_once 'Zend/Filter/Word/CamelCaseToDash.php'; - -/** - * @see Zend_Filter_StringToLower - */ -#require_once 'Zend/Filter/StringToLower.php'; - -/** - * @see Zend_Tool_Framework_Metadata_Tool - */ -#require_once 'Zend/Tool/Framework/Metadata/Tool.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * Zend_Tool_Framework_Client_ConsoleClient_Manifest - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Manifest - implements Zend_Tool_Framework_Registry_EnabledInterface, - Zend_Tool_Framework_Manifest_MetadataManifestable -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * setRegistry() - Required for the Zend_Tool_Framework_Registry_EnabledInterface interface - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Client_Console_Manifest - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * getMetadata() is required by the Manifest Interface. - * - * These are the following metadatas that will be setup: - * - * normalizedActionName - * - metadata for actions - * - value will be a dashed name for the action named in 'actionName' - * normalizedProviderName - * - metadata for providers - * - value will be a dashed-name for the provider named in 'providerName' - * normalizedProviderSpecialtyNames - * - metadata for providers - * normalizedActionableMethodLongParameters - * - metadata for providers - * normalizedActionableMethodShortParameters - * - metadata for providers - * - * @return array Array of Metadatas - */ - public function getMetadata() - { - $metadatas = array(); - - // setup the camelCase to dashed filter to use since cli expects dashed named - $lowerFilter = new Zend_Filter(); - $lowerFilter->addFilter(new Zend_Filter_StringToLower()); - - // get the registry to get the action and provider repository - $actionRepository = $this->_registry->getActionRepository(); - $providerRepository = $this->_registry->getProviderRepository(); - - // loop through all actions and create a metadata for each - foreach ($actionRepository->getActions() as $action) { - // each action metadata will be called - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'normalizedActionName', - 'value' => $lowerFilter->filter($action->getName()), - 'reference' => $action, - 'actionName' => $action->getName(), - 'clientName' => 'all' - )); - } - - foreach ($providerRepository->getProviderSignatures() as $providerSignature) { - - // create the metadata for the provider's cliProviderName - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'normalizedProviderName', - 'value' => $lowerFilter->filter($providerSignature->getName()), - 'reference' => $providerSignature, - 'clientName' => 'all', - 'providerName' => $providerSignature->getName() - )); - - // create the metadatas for the per provider specialites in providerSpecaltyNames - foreach ($providerSignature->getSpecialties() as $specialty) { - - if ($specialty == '_Global') { - continue; - } - - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'normalizedSpecialtyName', - 'value' => $lowerFilter->filter($specialty), - 'reference' => $providerSignature, - 'clientName' => 'all', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $specialty - )); - - } - - // $actionableMethod is keyed by the methodName (but not used) - foreach ($providerSignature->getActionableMethods() as $actionableMethodData) { - - $methodLongParams = array(); - $methodShortParams = array(); - - // $actionableMethodData get both the long and short names - foreach ($actionableMethodData['parameterInfo'] as $parameterInfoData) { - - // filter to dashed - $methodLongParams[$parameterInfoData['name']] = $lowerFilter->filter($parameterInfoData['name']); - - // simply lower the character, (its only 1 char after all) - $methodShortParams[$parameterInfoData['name']] = strtolower($parameterInfoData['name'][0]); - - } - - // create metadata for the long name cliActionableMethodLongParameters - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'normalizedActionableMethodLongParams', - 'value' => $methodLongParams, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $actionableMethodData['specialty'], - 'actionName' => $actionableMethodData['actionName'], - 'reference' => &$actionableMethodData - )); - - // create metadata for the short name cliActionableMethodShortParameters - $metadatas[] = new Zend_Tool_Framework_Metadata_Tool(array( - 'name' => 'normalizedActionableMethodShortParams', - 'value' => $methodShortParams, - 'clientName' => 'console', - 'providerName' => $providerSignature->getName(), - 'specialtyName' => $actionableMethodData['specialty'], - 'actionName' => $actionableMethodData['actionName'], - 'reference' => &$actionableMethodData - )); - - } - - } - - return $metadatas; - } - - public function getIndex() - { - return 100000; - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Request.php b/lib/Zend/Tool/Framework/Client/Request.php deleted file mode 100644 index c3896c680d1..00000000000 --- a/lib/Zend/Tool/Framework/Client/Request.php +++ /dev/null @@ -1,299 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Request -{ - - /** - * @var string - */ - protected $_providerName = null; - - /** - * @var string - */ - protected $_specialtyName = null; - - /** - * @var string - */ - protected $_actionName = null; - - /** - * @var array - */ - protected $_actionParameters = array(); - - /** - * @var array - */ - protected $_providerParameters = array(); - - /** - * @var bool - */ - protected $_isPretend = false; - - /** - * @var bool - */ - protected $_isDebug = false; - - /** - * @var bool - */ - protected $_isVerbose = false; - - /** - * @var bool - */ - protected $_isDispatchable = true; - - /** - * setProviderName() - * - * @param string $providerName - * @return Zend_Tool_Framework_Client_Request - */ - public function setProviderName($providerName) - { - $this->_providerName = $providerName; - return $this; - } - - /** - * getProviderName() - * - * @return string - */ - public function getProviderName() - { - return $this->_providerName; - } - - /** - * setSpecialtyName() - * - * @param string $specialtyName - * @return Zend_Tool_Framework_Client_Request - */ - public function setSpecialtyName($specialtyName) - { - $this->_specialtyName = $specialtyName; - return $this; - } - - /** - * getSpecialtyName() - * - * @return string - */ - public function getSpecialtyName() - { - return $this->_specialtyName; - } - - /** - * setActionName() - * - * @param string $actionName - * @return Zend_Tool_Framework_Client_Request - */ - public function setActionName($actionName) - { - $this->_actionName = $actionName; - return $this; - } - - /** - * getActionName() - * - * @return string - */ - public function getActionName() - { - return $this->_actionName; - } - - /** - * setActionParameter() - * - * @param string $parameterName - * @param string $parameterValue - * @return Zend_Tool_Framework_Client_Request - */ - public function setActionParameter($parameterName, $parameterValue) - { - $this->_actionParameters[$parameterName] = $parameterValue; - return $this; - } - - /** - * getActionParameters() - * - * @return array - */ - public function getActionParameters() - { - return $this->_actionParameters; - } - - /** - * getActionParameter() - * - * @param string $parameterName - * @return string - */ - public function getActionParameter($parameterName) - { - return (isset($this->_actionParameters[$parameterName])) ? $this->_actionParameters[$parameterName] : null; - } - - /** - * setProviderParameter() - * - * @param string $parameterName - * @param string $parameterValue - * @return Zend_Tool_Framework_Client_Request - */ - public function setProviderParameter($parameterName, $parameterValue) - { - $this->_providerParameters[$parameterName] = $parameterValue; - return $this; - } - - /** - * getProviderParameters() - * - * @return array - */ - public function getProviderParameters() - { - return $this->_providerParameters; - } - - /** - * getProviderParameter() - * - * @param string $parameterName - * @return string - */ - public function getProviderParameter($parameterName) - { - return (isset($this->_providerParameters[$parameterName])) ? $this->_providerParameters[$parameterName] : null; - } - - /** - * setPretend() - * - * @param bool $pretend - * @return Zend_Tool_Framework_Client_Request - */ - public function setPretend($pretend) - { - $this->_isPretend = (bool) $pretend; - return $this; - } - - /** - * isPretend() - Whether or not this is a pretend request - * - * @return bool - */ - public function isPretend() - { - return $this->_isPretend; - } - - /** - * setDebug() - * - * @param bool $pretend - * @return Zend_Tool_Framework_Client_Request - */ - public function setDebug($debug) - { - $this->_isDebug = (bool) $debug; - return $this; - } - - /** - * isDebug() - Whether or not this is a debug enabled request - * - * @return bool - */ - public function isDebug() - { - return $this->_isDebug; - } - - /** - * setVerbose() - * - * @param bool $verbose - * @return Zend_Tool_Framework_Client_Request - */ - public function setVerbose($verbose) - { - $this->_isVerbose = (bool) $verbose; - return $this; - } - - /** - * isVerbose() - Whether or not this is a verbose enabled request - * - * @return bool - */ - public function isVerbose() - { - return $this->_isVerbose; - } - - /** - * setDispatchable() - * - * @param bool $dispatchable - * @return Zend_Tool_Framework_Client_Request - */ - public function setDispatchable($dispatchable) - { - $this->_isDispatchable = (bool) $dispatchable; - return $this; - } - - /** - * isDispatchable() Is this request Dispatchable? - * - * @return bool - */ - public function isDispatchable() - { - return $this->_isDispatchable; - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Response.php b/lib/Zend/Tool/Framework/Client/Response.php deleted file mode 100644 index c71afb81fa4..00000000000 --- a/lib/Zend/Tool/Framework/Client/Response.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Response -{ - /** - * @var callback|null - */ - protected $_callback = null; - - /** - * @var array - */ - protected $_content = array(); - - /** - * @var Zend_Tool_Framework_Exception - */ - protected $_exception = null; - - /** - * @var array - */ - protected $_decorators = array(); - - /** - * @var array - */ - protected $_defaultDecoratorOptions = array(); - - /** - * setContentCallback() - * - * @param callback $callback - * @return Zend_Tool_Framework_Client_Response - */ - public function setContentCallback($callback) - { - if (!is_callable($callback)) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('The callback provided is not callable'); - } - $this->_callback = $callback; - return $this; - } - - /** - * setContent() - * - * @param string $content - * @return Zend_Tool_Framework_Client_Response - */ - public function setContent($content, Array $decoratorOptions = array()) - { - $content = $this->_applyDecorators($content, $decoratorOptions); - - $this->_content = array(); - $this->appendContent($content); - return $this; - } - - /** - * appendCallback - * - * @param string $content - * @return Zend_Tool_Framework_Client_Response - */ - public function appendContent($content, Array $decoratorOptions = array()) - { - $content = $this->_applyDecorators($content, $decoratorOptions); - - if ($this->_callback !== null) { - call_user_func($this->_callback, $content); - } - - $this->_content[] = $content; - - return $this; - } - - /** - * setDefaultDecoratorOptions() - * - * @param array $decoratorOptions - * @param bool $mergeIntoExisting - * @return Zend_Tool_Framework_Client_Response - */ - public function setDefaultDecoratorOptions(Array $decoratorOptions, $mergeIntoExisting = false) - { - if ($mergeIntoExisting == false) { - $this->_defaultDecoratorOptions = array(); - } - - $this->_defaultDecoratorOptions = array_merge($this->_defaultDecoratorOptions, $decoratorOptions); - return $this; - } - - /** - * getContent() - * - * @return string - */ - public function getContent() - { - return implode('', $this->_content); - } - - /** - * isException() - * - * @return bool - */ - public function isException() - { - return isset($this->_exception); - } - - /** - * setException() - * - * @param Exception $exception - * @return Zend_Tool_Framework_Client_Response - */ - public function setException(Exception $exception) - { - $this->_exception = $exception; - return $this; - } - - /** - * getException() - * - * @return Exception - */ - public function getException() - { - return $this->_exception; - } - - /** - * Add Content Decorator - * - * @param Zend_Tool_Framework_Client_Response_ContentDecorator_Interface $contentDecorator - * @return unknown - */ - public function addContentDecorator(Zend_Tool_Framework_Client_Response_ContentDecorator_Interface $contentDecorator) - { - $decoratorName = strtolower($contentDecorator->getName()); - $this->_decorators[$decoratorName] = $contentDecorator; - return $this; - } - - /** - * getContentDecorators() - * - * @return array - */ - public function getContentDecorators() - { - return $this->_decorators; - } - - /** - * __toString() to cast to a string - * - * @return string - */ - public function __toString() - { - return (string) implode('', $this->_content); - } - - /** - * _applyDecorators() apply a group of decorators - * - * @param string $content - * @param array $decoratorOptions - * @return string - */ - protected function _applyDecorators($content, Array $decoratorOptions) - { - $options = array_merge($this->_defaultDecoratorOptions, $decoratorOptions); - - $options = array_change_key_case($options, CASE_LOWER); - - if ($options) { - foreach ($this->_decorators as $decoratorName => $decorator) { - if (array_key_exists($decoratorName, $options)) { - $content = $decorator->decorate($content, $options[$decoratorName]); - } - } - } - - return $content; - - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php b/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php deleted file mode 100644 index ec29803daf6..00000000000 --- a/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - - public function getName(); - - public function decorate($content, $decoratorValue); - -} diff --git a/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Separator.php b/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Separator.php deleted file mode 100644 index c67a0ba3d81..00000000000 --- a/lib/Zend/Tool/Framework/Client/Response/ContentDecorator/Separator.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Client_Response_ContentDecorator_Interface - */ -#require_once 'Zend/Tool/Framework/Client/Response/ContentDecorator/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Response_ContentDecorator_Separator - implements Zend_Tool_Framework_Client_Response_ContentDecorator_Interface -{ - - /** - * @var string - */ - protected $_separator = PHP_EOL; - - /** - * getName() - name of the decorator - * - * @return string - */ - public function getName() - { - return 'separator'; - } - - /** - * setSeparator() - * - * @param string $separator - * @return Zend_Tool_Framework_Client_Response_ContentDecorator_Separator - */ - public function setSeparator($separator) - { - $this->_separator = $separator; - return $this; - } - - /** - * getSeparator() - * - * @return string - */ - public function getSeparator() - { - return $this->_separator; - } - - public function decorate($content, $decoratorValue) - { - $run = 1; - if (is_bool($decoratorValue) && $decoratorValue === false) { - return $content; - } - - if (is_int($decoratorValue)) { - $run = $decoratorValue; - } - - for ($i = 0; $i < $run; $i++) { - $content .= $this->_separator; - } - - return $content; - } - -} diff --git a/lib/Zend/Tool/Framework/Client/Storage.php b/lib/Zend/Tool/Framework/Client/Storage.php deleted file mode 100644 index 63da6a07336..00000000000 --- a/lib/Zend/Tool/Framework/Client/Storage.php +++ /dev/null @@ -1,117 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Client_Storage_AdapterInterface - */ -#require_once 'Zend/Tool/Framework/Client/Storage/AdapterInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Storage -{ - - /** - * @var Zend_Tool_Framework_Client_Storage_AdapterInterface - */ - protected $_adapter = null; - - public function __construct($options = array()) - { - if (isset($options['adapter'])) { - $this->setAdapter($options['adapter']); - } - } - - public function setAdapter($adapter) - { - if (is_string($adapter)) { - $storageAdapterClass = 'Zend_Tool_Framework_Client_Storage_' . ucfirst($adapter); - Zend_Loader::loadClass($storageAdapterClass); - $adapter = new $storageAdapterClass(); - } - $this->_adapter = $adapter; - } - - public function isEnabled() - { - return ($this->_adapter instanceof Zend_Tool_Framework_Client_Storage_AdapterInterface); - } - - public function put($name, $value) - { - if (!$this->_adapter) { - return false; - } - - $this->_adapter->put($name, $value); - - return $this; - } - - public function get($name, $defaultValue = false) - { - if (!$this->_adapter) { - return false; - } - - if ($this->_adapter->has($name)) { - return $this->_adapter->get($name); - } else { - return $defaultValue; - } - - } - - public function has($name) - { - if (!$this->_adapter) { - return false; - } - - return $this->_adapter->has($name); - } - - public function remove($name) - { - if (!$this->_adapter) { - return false; - } - - $this->_adapter->remove($name); - - return $this; - } - - public function getStreamUri($name) - { - if (!$this->_adapter) { - return false; - } - - return $this->_adapter->getStreamUri($name); - } -} diff --git a/lib/Zend/Tool/Framework/Client/Storage/AdapterInterface.php b/lib/Zend/Tool/Framework/Client/Storage/AdapterInterface.php deleted file mode 100644 index e3e717ab914..00000000000 --- a/lib/Zend/Tool/Framework/Client/Storage/AdapterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Client_Storage_AdapterInterface -{ - - public function put($name, $value); - - public function get($name); - - public function has($name); - - public function remove($name); - - public function getStreamUri($name); - -} diff --git a/lib/Zend/Tool/Framework/Client/Storage/Directory.php b/lib/Zend/Tool/Framework/Client/Storage/Directory.php deleted file mode 100644 index 720b46144dd..00000000000 --- a/lib/Zend/Tool/Framework/Client/Storage/Directory.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Client_Storage_AdapterInterface - */ -#require_once 'Zend/Tool/Framework/Client/Storage/AdapterInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Client_Storage_Directory - implements Zend_Tool_Framework_Client_Storage_AdapterInterface -{ - - protected $_directoryPath = null; - - public function __construct($directoryPath) - { - if (!file_exists($directoryPath)) { - throw new Zend_Tool_Framework_Client_Exception(__CLASS__ . ': the supplied directory does not exist'); - } - $this->_directoryPath = $directoryPath; - } - - public function put($name, $value) - { - return file_put_contents($this->_directoryPath . DIRECTORY_SEPARATOR . $name, $value); - } - - public function get($name) - { - return file_get_contents($this->_directoryPath . DIRECTORY_SEPARATOR . $name); - } - - public function has($name) - { - return file_exists($this->_directoryPath . DIRECTORY_SEPARATOR . $name); - } - - public function remove($name) - { - return unlink($this->_directoryPath . DIRECTORY_SEPARATOR . $name); - } - - public function getStreamUri($name) - { - return $this->_directoryPath . DIRECTORY_SEPARATOR . $name; - } - -} diff --git a/lib/Zend/Tool/Framework/Exception.php b/lib/Zend/Tool/Framework/Exception.php deleted file mode 100644 index fe2efeae1a5..00000000000 --- a/lib/Zend/Tool/Framework/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Exception - */ -#require_once 'Zend/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Exception extends Zend_Exception -{ -} diff --git a/lib/Zend/Tool/Framework/Loader/Abstract.php b/lib/Zend/Tool/Framework/Loader/Abstract.php deleted file mode 100644 index 3e48f5cee7a..00000000000 --- a/lib/Zend/Tool/Framework/Loader/Abstract.php +++ /dev/null @@ -1,156 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -#require_once 'Zend/Tool/Framework/Loader/Interface.php'; -#require_once 'Zend/Tool/Framework/Manifest/Interface.php'; -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; - - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tool_Framework_Loader_Abstract - implements Zend_Tool_Framework_Loader_Interface, Zend_Tool_Framework_Registry_EnabledInterface -{ - /** - * @var Zend_Tool_Framework_Repository_Interface - */ - protected $_registry = null; - - /** - * @var array - */ - private $_retrievedFiles = array(); - - /** - * @var array - */ - private $_loadedClasses = array(); - - /** - * _getFiles - * - * @return array Array Of Files - */ - abstract protected function _getFiles(); - - /** - * setRegistry() - required by the enabled interface to get an instance of - * the registry - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Loader_Abstract - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * load() - called by the client initialize routine to load files - * - */ - public function load() - { - $this->_retrievedFiles = $this->getRetrievedFiles(); - $this->_loadedClasses = array(); - - $manifestRepository = $this->_registry->getManifestRepository(); - $providerRepository = $this->_registry->getProviderRepository(); - - $loadedClasses = array(); - - // loop through files and find the classes declared by loading the file - foreach ($this->_retrievedFiles as $file) { - if(is_dir($file)) { - continue; - } - - $classesLoadedBefore = get_declared_classes(); - $oldLevel = error_reporting(E_ALL | ~E_STRICT); // remove strict so that other packages wont throw warnings - // should we lint the files here? i think so - include_once $file; - error_reporting($oldLevel); // restore old error level - $classesLoadedAfter = get_declared_classes(); - $loadedClasses = array_merge($loadedClasses, array_diff($classesLoadedAfter, $classesLoadedBefore)); - } - - // loop through the loaded classes and ensure that - foreach ($loadedClasses as $loadedClass) { - - // reflect class to see if its something we want to load - $reflectionClass = new ReflectionClass($loadedClass); - if ($reflectionClass->implementsInterface('Zend_Tool_Framework_Manifest_Interface') - && !$reflectionClass->isAbstract()) - { - $manifestRepository->addManifest($reflectionClass->newInstance()); - $this->_loadedClasses[] = $loadedClass; - } - - if ($reflectionClass->implementsInterface('Zend_Tool_Framework_Provider_Interface') - && !$reflectionClass->isAbstract() - && !$providerRepository->hasProvider($reflectionClass->getName(), false)) - { - $providerRepository->addProvider($reflectionClass->newInstance()); - $this->_loadedClasses[] = $loadedClass; - } - - } - - return $this->_loadedClasses; - } - - /** - * getRetrievedFiles() - * - * @return array Array of Files Retrieved - */ - public function getRetrievedFiles() - { - if ($this->_retrievedFiles == null) { - $this->_retrievedFiles = $this->_getFiles(); - } - - return $this->_retrievedFiles; - } - - /** - * getLoadedClasses() - * - * @return array Array of Loaded Classes - */ - public function getLoadedClasses() - { - return $this->_loadedClasses; - } - - -} diff --git a/lib/Zend/Tool/Framework/Loader/BasicLoader.php b/lib/Zend/Tool/Framework/Loader/BasicLoader.php deleted file mode 100644 index 0fe3143b164..00000000000 --- a/lib/Zend/Tool/Framework/Loader/BasicLoader.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Loader_Abstract - */ -#require_once 'Zend/Tool/Framework/Loader/Interface.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @see Zend_Loader - */ -#require_once 'Zend/Loader.php'; -#require_once 'Zend/Tool/Framework/Manifest/Interface.php'; -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Loader_BasicLoader - implements Zend_Tool_Framework_Loader_Interface, Zend_Tool_Framework_Registry_EnabledInterface -{ - /** - * @var Zend_Tool_Framework_Repository_Interface - */ - protected $_registry = null; - - /** - * @var array - */ - protected $_classesToLoad = array(); - - public function __construct($options = array()) - { - if ($options) { - $this->setOptions($options); - } - } - - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $setMethod = 'set' . $optionName; - if (method_exists($this, $setMethod)) { - $this->{$setMethod}($optionValue); - } - } - } - - /** - * setRegistry() - required by the enabled interface to get an instance of - * the registry - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Loader_Abstract - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * @param array $classesToLoad - * @return Zend_Tool_Framework_Loader_Abstract - */ - public function setClassesToLoad(array $classesToLoad) - { - $this->_classesToLoad = $classesToLoad; - return $this; - } - - public function load() - { - $manifestRegistry = $this->_registry->getManifestRepository(); - $providerRegistry = $this->_registry->getProviderRepository(); - - $loadedClasses = array(); - - // loop through the loaded classes and ensure that - foreach ($this->_classesToLoad as $class) { - - if (!class_exists($class)) { - Zend_Loader::loadClass($class); - } - - // reflect class to see if its something we want to load - $reflectionClass = new ReflectionClass($class); - if ($this->_isManifestImplementation($reflectionClass)) { - $manifestRegistry->addManifest($reflectionClass->newInstance()); - $loadedClasses[] = $class; - } - - if ($this->_isProviderImplementation($reflectionClass)) { - $providerRegistry->addProvider($reflectionClass->newInstance()); - $loadedClasses[] = $class; - } - - } - - return $loadedClasses; - } - - /** - * @param ReflectionClass $reflectionClass - * @return bool - */ - private function _isManifestImplementation($reflectionClass) - { - return ( - $reflectionClass->implementsInterface('Zend_Tool_Framework_Manifest_Interface') - && !$reflectionClass->isAbstract() - ); - } - - /** - * @param ReflectionClass $reflectionClass - * @return bool - */ - private function _isProviderImplementation($reflectionClass) - { - $providerRegistry = $this->_registry->getProviderRepository(); - - return ( - $reflectionClass->implementsInterface('Zend_Tool_Framework_Provider_Interface') - && !$reflectionClass->isAbstract() - && !$providerRegistry->hasProvider($reflectionClass->getName(), false) - ); - } - -} diff --git a/lib/Zend/Tool/Framework/Loader/IncludePathLoader.php b/lib/Zend/Tool/Framework/Loader/IncludePathLoader.php deleted file mode 100644 index 53bdb772203..00000000000 --- a/lib/Zend/Tool/Framework/Loader/IncludePathLoader.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Loader_Abstract - */ -#require_once 'Zend/Tool/Framework/Loader/Abstract.php'; - -/** - * @see Zend_Tool_Framework_Loader_IncludePathLoader_RecursiveFilterIterator - */ -#require_once 'Zend/Tool/Framework/Loader/IncludePathLoader/RecursiveFilterIterator.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Loader_IncludePathLoader extends Zend_Tool_Framework_Loader_Abstract -{ - - /** - * _getFiles() - * - * @return array Array of files to load - */ - protected function _getFiles() - { - #require_once 'Zend/Loader.php'; - $paths = Zend_Loader::explodeIncludePath(); - - // used for checking similarly named files - $relativeItems = array(); - $files = array(); - $isZendTraversed = false; - - foreach ($paths as $path) { - - // default patterns to use - $filterDenyDirectoryPattern = '.*(/|\\\\).svn'; - $filterAcceptFilePattern = '.*(?:Manifest|Provider)\.php$'; - - if (!file_exists($path) || $path[0] == '.') { - continue; - } - - $realIncludePath = realpath($path); - - // ensure that we only traverse a single version of Zend Framework on all include paths - if (file_exists($realIncludePath . '/Zend/Tool/Framework/Loader/IncludePathLoader.php')) { - if ($isZendTraversed === false) { - $isZendTraversed = true; - } else { - // use the deny directory pattern that includes the path to 'Zend', it will not be accepted - $filterDenyDirectoryPattern = '.*((/|\\\\).svn|' . preg_quote($realIncludePath . DIRECTORY_SEPARATOR) . 'Zend)'; - } - } - - // create recursive directory iterator - $rdi = new RecursiveDirectoryIterator($path); - - // pass in the RecursiveDirectoryIterator & the patterns - $filter = new Zend_Tool_Framework_Loader_IncludePathLoader_RecursiveFilterIterator( - $rdi, - $filterDenyDirectoryPattern, - $filterAcceptFilePattern - ); - - // build the rii with the filter - $iterator = new RecursiveIteratorIterator($filter); - - // iterate over the accepted items - foreach ($iterator as $item) { - $file = (string)$item; - if($this->_fileIsBlacklisted($file)) { - continue; - } - - // ensure that the same named file from separate include_paths is not loaded - $relativeItem = preg_replace('#^' . preg_quote($realIncludePath . DIRECTORY_SEPARATOR, '#') . '#', '', $item->getRealPath()); - - // no links allowed here for now - if ($item->isLink()) { - continue; - } - - // no items that are relavitely the same are allowed - if (in_array($relativeItem, $relativeItems)) { - continue; - } - - $relativeItems[] = $relativeItem; - $files[] = $item->getRealPath(); - } - } - - return $files; - } - - /** - * - * @param string $file - * @return bool - */ - protected function _fileIsBlacklisted($file) - { - $blacklist = array( - "PHPUnit".DIRECTORY_SEPARATOR."Framework", - "Zend".DIRECTORY_SEPARATOR."OpenId".DIRECTORY_SEPARATOR."Provider" - ); - - foreach($blacklist AS $blacklitedPattern) { - if(strpos($file, $blacklitedPattern) !== false) { - return true; - } - } - return false; - } -} diff --git a/lib/Zend/Tool/Framework/Loader/IncludePathLoader/RecursiveFilterIterator.php b/lib/Zend/Tool/Framework/Loader/IncludePathLoader/RecursiveFilterIterator.php deleted file mode 100644 index 6859c13f4b0..00000000000 --- a/lib/Zend/Tool/Framework/Loader/IncludePathLoader/RecursiveFilterIterator.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Loader_IncludePathLoader_RecursiveFilterIterator extends RecursiveFilterIterator -{ - - protected $_denyDirectoryPattern = null; - protected $_acceptFilePattern = null; - - /** - * constructor - * - * @param RecursiveIterator $iterator - * @param string $denyDirectoryPattern - * @param string $acceptFilePattern - */ - public function __construct(RecursiveIterator $iterator, $denyDirectoryPattern = null, $acceptFilePattern = null) - { - $this->_denyDirectoryPattern = $denyDirectoryPattern; - $this->_acceptFilePattern = $acceptFilePattern; - parent::__construct($iterator); - } - - /** - * accept() - Which iterable items to accept or deny, required by FilterInterface - * - * @return unknown - */ - #[ReturnTypeWillChange] - public function accept() - { - $currentNode = $this->current(); - $currentNodeRealPath = $currentNode->getRealPath(); - - // if the current node is a directory AND doesn't match the denyDirectory pattern, accept - if ($currentNode->isDir() - && !preg_match('#' . $this->_denyDirectoryPattern . '#', $currentNodeRealPath)) { - return true; - } - - // if the file matches the accept file pattern, accept - $acceptable = (preg_match('#' . $this->_acceptFilePattern . '#', $currentNodeRealPath)) ? true : false; - return $acceptable; - } - - /** - * getChildren() - overridden from RecursiveFilterIterator to allow the persistence of - * the $_denyDirectoryPattern and the $_acceptFilePattern when sub iterators of this filter - * are needed to be created. - * - * @return Zend_Tool_Framework_Loader_IncludePathLoader_RecursiveFilterIterator - */ - #[ReturnTypeWillChange] - public function getChildren() - { - if (empty($this->ref)) { - $this->ref = new ReflectionClass($this); - } - - return $this->ref->newInstance( - $this->getInnerIterator()->getChildren(), - $this->_denyDirectoryPattern, - $this->_acceptFilePattern - ); - } - -} - diff --git a/lib/Zend/Tool/Framework/Loader/Interface.php b/lib/Zend/Tool/Framework/Loader/Interface.php deleted file mode 100644 index f734a7cc1d8..00000000000 --- a/lib/Zend/Tool/Framework/Loader/Interface.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Basic Interface for factilities that load Zend_Tool providers or manifests. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Loader_Interface -{ - /** - * Load Providers and Manifests - * - * Returns an array of all loaded class names. - * - * @return array - */ - public function load(); -} diff --git a/lib/Zend/Tool/Framework/Manifest/ActionManifestable.php b/lib/Zend/Tool/Framework/Manifest/ActionManifestable.php deleted file mode 100644 index 0321d12f542..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/ActionManifestable.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Manifest_Interface - */ -#require_once 'Zend/Tool/Framework/Manifest/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Manifest_ActionManifestable extends Zend_Tool_Framework_Manifest_Interface -{ - - /** - * getActions() - * - * Should either return a single action, or an array - * of actions - * - * @return array|Zend_Tool_Framework_Action_Interface - */ - public function getActions(); - -} diff --git a/lib/Zend/Tool/Framework/Manifest/ActionMetadata.php b/lib/Zend/Tool/Framework/Manifest/ActionMetadata.php deleted file mode 100644 index 573ccc6116e..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/ActionMetadata.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Manifest_ActionMetadata -{ - -} diff --git a/lib/Zend/Tool/Framework/Manifest/Exception.php b/lib/Zend/Tool/Framework/Manifest/Exception.php deleted file mode 100644 index abbe62cd335..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Exception - */ -#require_once 'Zend/Tool/Framework/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Manifest_Exception extends Zend_Tool_Framework_Exception -{ - -} diff --git a/lib/Zend/Tool/Framework/Manifest/Indexable.php b/lib/Zend/Tool/Framework/Manifest/Indexable.php deleted file mode 100644 index 532c2ceb880..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/Indexable.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Manifest_Indexable extends Zend_Tool_Framework_Manifest_Interface -{ - - /** - * getActions() - * - * Should either return a single action, or an array - * of actions - * - * @return array|Zend_Tool_Framework_Action_Interface - */ - public function getIndex(); - -} diff --git a/lib/Zend/Tool/Framework/Manifest/Interface.php b/lib/Zend/Tool/Framework/Manifest/Interface.php deleted file mode 100644 index 81677a068bd..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/Interface.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Manifest_Interface -{ - - /** - * The following methods are completely optional, and any combination of them - * can be used as part of a manifest. The manifest repository will process - * the return values of these actions as specfied in the following method docblocks. - * - * Since these actions are - * - */ - - /** - * getMetadata() - * - * Should either return a single metadata object or an array - * of metadata objects - * - * @return array|Zend_Tool_Framework_Manifest_Metadata - ** - - public function getMetadata(); - - **/ - - - - /** - * getActions() - * - * Should either return a single action, or an array - * of actions - * - * @return array|Zend_Tool_Framework_Action_Interface - ** - - public function getActions(); - - **/ - - - - /** - * getProviders() - * - * Should either return a single provider or an array - * of providers - * - ** - - public function getProviders(); - - **/ - -} diff --git a/lib/Zend/Tool/Framework/Manifest/Metadata.php b/lib/Zend/Tool/Framework/Manifest/Metadata.php deleted file mode 100644 index 5e0a6c29b8e..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/Metadata.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Manifest_Metadata -{ - -} diff --git a/lib/Zend/Tool/Framework/Manifest/MetadataManifestable.php b/lib/Zend/Tool/Framework/Manifest/MetadataManifestable.php deleted file mode 100644 index 448b44135ed..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/MetadataManifestable.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Manifest_Interface.php - */ -#require_once 'Zend/Tool/Framework/Manifest/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Manifest_MetadataManifestable extends Zend_Tool_Framework_Manifest_Interface -{ - - /** - * getMetadata() - * - * Should either return a single metadata object or an array - * of metadata objects - * - * @return array|Zend_Tool_Framework_Manifest_Metadata - */ - public function getMetadata(); - -} diff --git a/lib/Zend/Tool/Framework/Manifest/ProviderManifestable.php b/lib/Zend/Tool/Framework/Manifest/ProviderManifestable.php deleted file mode 100644 index e68a8a18b1b..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/ProviderManifestable.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Manifest_Interface.php - */ -#require_once 'Zend/Tool/Framework/Manifest/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Manifest_ProviderManifestable extends Zend_Tool_Framework_Manifest_Interface -{ - - /** - * getProviders() - * - * Should either return a single provider or an array - * of providers - * - * @return array|string|Zend_Tool_Framework_Provider_Interface - */ - public function getProviders(); - -} diff --git a/lib/Zend/Tool/Framework/Manifest/ProviderMetadata.php b/lib/Zend/Tool/Framework/Manifest/ProviderMetadata.php deleted file mode 100644 index bff1d378f37..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/ProviderMetadata.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Manifest_ProviderMetadata -{ - -} diff --git a/lib/Zend/Tool/Framework/Manifest/Repository.php b/lib/Zend/Tool/Framework/Manifest/Repository.php deleted file mode 100644 index 3d6ee3ac73a..00000000000 --- a/lib/Zend/Tool/Framework/Manifest/Repository.php +++ /dev/null @@ -1,313 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Manifest_Repository - implements Zend_Tool_Framework_Registry_EnabledInterface, IteratorAggregate, Countable -{ - - /** - * @var Zend_Tool_Framework_Provider_Registry_Interface - */ - protected $_registry = null; - - /** - * @var array - */ - protected $_manifests = array(); - - /** - * @var array Array of Zend_Tool_Framework_Metadata_Interface - */ - protected $_metadatas = array(); - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return unknown - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * addManifest() - Add a manifest for later processing - * - * @param Zend_Tool_Framework_Manifest_Interface $manifest - * @return Zend_Tool_Framework_Manifest_Repository - */ - public function addManifest(Zend_Tool_Framework_Manifest_Interface $manifest) - { - // we need to get an index number so that manifests with - // higher indexes have priority over others - $index = count($this->_manifests); - - if ($manifest instanceof Zend_Tool_Framework_Registry_EnabledInterface) { - $manifest->setRegistry($this->_registry); - } - - // if the manifest supplies a getIndex() method, use it - if ($manifest instanceof Zend_Tool_Framework_Manifest_Indexable) { - $index = $manifest->getIndex(); - } - - // get the required objects from the framework registry - $actionRepository = $this->_registry->getActionRepository(); - $providerRepository = $this->_registry->getProviderRepository(); - - // load providers if interface supports that method - if ($manifest instanceof Zend_Tool_Framework_Manifest_ProviderManifestable) { - $providers = $manifest->getProviders(); - if (!is_array($providers)) { - $providers = array($providers); - } - - foreach ($providers as $provider) { - - // if provider is a string, try and load it as an object - if (is_string($provider)) { - $provider = new $provider(); - } - - if (!$provider instanceof Zend_Tool_Framework_Provider_Interface) { - #require_once 'Zend/Tool/Framework/Manifest/Exception.php'; - throw new Zend_Tool_Framework_Manifest_Exception( - 'A provider provided by the ' . get_class($manifest) - . ' does not implement Zend_Tool_Framework_Provider_Interface' - ); - } - if (!$providerRepository->hasProvider($provider, false)) { - $providerRepository->addProvider($provider); - } - } - - } - - // load actions if interface supports that method - if ($manifest instanceof Zend_Tool_Framework_Manifest_ActionManifestable) { - $actions = $manifest->getActions(); - if (!is_array($actions)) { - $actions = array($actions); - } - - foreach ($actions as $action) { - if (is_string($action)) { - $action = new Zend_Tool_Framework_Action_Base($action); - } - $actionRepository->addAction($action); - } - } - - // should we detect collisions here? does it even matter? - $this->_manifests[$index] = $manifest; - ksort($this->_manifests); - - return $this; - } - - /** - * getManifests() - * - * @return Zend_Tool_Framework_Manifest_Interface[] - */ - public function getManifests() - { - return $this->_manifests; - } - - /** - * addMetadata() - add a metadata peice by peice - * - * @param Zend_Tool_Framework_Manifest_Metadata $metadata - * @return Zend_Tool_Framework_Manifest_Repository - */ - public function addMetadata(Zend_Tool_Framework_Metadata_Interface $metadata) - { - $this->_metadatas[] = $metadata; - return $this; - } - - /** - * process() - Process is expected to be called at the end of client construction time. - * By this time, the loader has run and loaded any found manifests into the repository - * for loading - * - * @return Zend_Tool_Framework_Manifest_Repository - */ - public function process() - { - - foreach ($this->_manifests as $manifest) { - if ($manifest instanceof Zend_Tool_Framework_Manifest_MetadataManifestable) { - $metadatas = $manifest->getMetadata(); - if (!is_array($metadatas)) { - $metadatas = array($metadatas); - } - - foreach ($metadatas as $metadata) { - if (is_array($metadata)) { - if (!class_exists('Zend_Tool_Framework_Metadata_Dynamic')) { - #require_once 'Zend/Tool/Framework/Metadata/Dynamic.php'; - } - $metadata = new Zend_Tool_Framework_Metadata_Dynamic($metadata); - } - - if (!$metadata instanceof Zend_Tool_Framework_Metadata_Interface) { - #require_once 'Zend/Tool/Framework/Manifest/Exception.php'; - throw new Zend_Tool_Framework_Manifest_Exception( - 'A Zend_Tool_Framework_Metadata_Interface object was not found in manifest ' . get_class($manifest) - ); - } - - $this->addMetadata($metadata); - } - - } - } - - return $this; - } - - /** - * getMetadatas() - This is the main search function for the repository. - * - * example: This will retrieve all metadata that matches the following criteria - * $manifestRepo->getMetadatas(array( - * 'providerName' => 'Version', - * 'actionName' => 'show' - * )); - * - * @param array $searchProperties - * @param bool $includeNonExistentProperties - * @return Zend_Tool_Framework_Manifest_Metadata[] - */ - public function getMetadatas(Array $searchProperties = array(), $includeNonExistentProperties = true) - { - - $returnMetadatas = array(); - - // loop through the metadatas so that we can search each individual one - foreach ($this->_metadatas as $metadata) { - - // each value will be retrieved from the metadata, each metadata should - // implement a getter method to retrieve the value - foreach ($searchProperties as $searchPropertyName => $searchPropertyValue) { - if (method_exists($metadata, 'get' . $searchPropertyName)) { - if ($metadata->{'get' . $searchPropertyName}() != $searchPropertyValue) { - // if the metadata supports a specific property but the value does not - // match, move on - continue 2; - } - } elseif (!$includeNonExistentProperties) { - // if the option $includeNonExitentProperties is false, then move on as - // we dont want to include this metadata if non existent - // search properties are not inside the target (current) metadata - continue 2; - } - } - - // all searching has been accounted for, if we reach this point, then the metadata - // is good and we can return it - $returnMetadatas[] = $metadata; - - } - - return $returnMetadatas; - } - - /** - * getMetadata() - This will proxy to getMetadatas(), but will only return a single metadata. This method - * should be used in situations where the search criteria is known to only find a single metadata object - * - * @param array $searchProperties - * @param bool $includeNonExistentProperties - * @return Zend_Tool_Framework_Manifest_Metadata - */ - public function getMetadata(Array $searchProperties = array(), $includeNonExistentProperties = true) - { - $metadatas = $this->getMetadatas($searchProperties, $includeNonExistentProperties); - return array_shift($metadatas); - } - - /** - * __toString() - cast to string - * - * @return string - */ - public function __toString() - { - $metadatasByType = array(); - - foreach ($this->_metadatas as $metadata) { - if (!array_key_exists($metadata->getType(), $metadatasByType)) { - $metadatasByType[$metadata->getType()] = array(); - } - $metadatasByType[$metadata->getType()][] = $metadata; - } - - $string = ''; - foreach ($metadatasByType as $type => $metadatas) { - $string .= $type . PHP_EOL; - foreach ($metadatas as $metadata) { - $metadataString = ' ' . $metadata->__toString() . PHP_EOL; - //$metadataString = str_replace(PHP_EOL, PHP_EOL . ' ', $metadataString); - $string .= $metadataString; - } - } - - return $string; - } - - /** - * count() - required by the Countable Interface - * - * @return int - */ - public function count() - { - return count($this->_metadatas); - } - - /** - * getIterator() - required by the IteratorAggregate interface - * - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->_metadatas); - } - -} diff --git a/lib/Zend/Tool/Framework/Metadata/Attributable.php b/lib/Zend/Tool/Framework/Metadata/Attributable.php deleted file mode 100644 index 869f5d5e296..00000000000 --- a/lib/Zend/Tool/Framework/Metadata/Attributable.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Metadata_Attributable -{ - public function getAttributes(); -} - - diff --git a/lib/Zend/Tool/Framework/Metadata/Basic.php b/lib/Zend/Tool/Framework/Metadata/Basic.php deleted file mode 100644 index 511af884e3d..00000000000 --- a/lib/Zend/Tool/Framework/Metadata/Basic.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Metadata_Interface - */ -#require_once 'Zend/Tool/Framework/Metadata/Interface.php'; - -/** - * @see Zend_Tool_Framework_Metadata_Attributable - */ -#require_once 'Zend/Tool/Framework/Metadata/Attributable.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Metadata_Basic - implements Zend_Tool_Framework_Metadata_Interface, Zend_Tool_Framework_Metadata_Attributable -{ - - /**#@+ - * Search constants - */ - const ATTRIBUTES_ALL = 'attributesAll'; - const ATTRIBUTES_NO_PARENT = 'attributesParent'; - /**#@-*/ - - /**#@+ - * @var string - */ - protected $_type = 'Basic'; - protected $_name = null; - protected $_value = null; - /**#@-*/ - - /** - * @var mixed - */ - protected $_reference = null; - - /** - * Constructor - allows for the setting of options - * - * @param array $options - */ - public function __construct(Array $options = array()) - { - if ($options) { - $this->setOptions($options); - } - } - - /** - * setOptions() - standard issue implementation, this will set any - * options that are supported via a set method. - * - * @param array $options - * @return Zend_Tool_Framework_Metadata_Basic - */ - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - $setMethod = 'set' . $optionName; - if (method_exists($this, $setMethod)) { - $this->{$setMethod}($optionValue); - } - } - - return $this; - } - - /** - * getType() - * - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * setType() - * - * @param string $type - * @return Zend_Tool_Framework_Metadata_Basic - */ - public function setType($type) - { - $this->_type = $type; - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * setName() - * - * @param string $name - * @return Zend_Tool_Framework_Metadata_Basic - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getValue() - * - * @return mixed - */ - public function getValue() - { - return $this->_value; - } - - /** - * setValue() - * - * @param unknown_type $Value - * @return Zend_Tool_Framework_Metadata_Basic - */ - public function setValue($value) - { - $this->_value = $value; - return $this; - } - - /** - * setReference() - * - * @param mixed $reference - * @return Zend_Tool_Framework_Metadata_Basic - */ - public function setReference($reference) - { - $this->_reference = $reference; - return $this; - } - - /** - * getReference() - * - * @return mixed - */ - public function getReference() - { - return $this->_reference; - } - - /** - * getAttributes() - this will retrieve any attributes of this object that exist as properties - * This is most useful for printing metadata. - * - * @param const $type - * @return array - */ - public function getAttributes($type = self::ATTRIBUTES_ALL, $stringRepresentationOfNonScalars = false) - { - $thisReflection = new ReflectionObject($this); - - $metadataPairValues = array(); - - foreach (get_object_vars($this) as $varName => $varValue) { - if ($type == self::ATTRIBUTES_NO_PARENT && ($thisReflection->getProperty($varName)->getDeclaringClass()->getName() == 'Zend_Tool_Framework_Metadata_Basic')) { - continue; - } - - if ($stringRepresentationOfNonScalars) { - - if (is_object($varValue)) { - $varValue = '(object)'; - } - - if ($varValue === null) { - $varValue = '(null)'; - } - - } - - $metadataPairValues[ltrim($varName, '_')] = $varValue; - } - - return $metadataPairValues; - } - - /** - * __toString() - string representation of this object - * - * @return string - */ - public function __toString() - { - return 'Type: ' . $this->_type . ', Name: ' . $this->_name . ', Value: ' . (is_array($this->_value) ? http_build_query($this->_value) : (string) $this->_value); - } -} diff --git a/lib/Zend/Tool/Framework/Metadata/Dynamic.php b/lib/Zend/Tool/Framework/Metadata/Dynamic.php deleted file mode 100644 index 9c8791b6fae..00000000000 --- a/lib/Zend/Tool/Framework/Metadata/Dynamic.php +++ /dev/null @@ -1,219 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Metadata_Interface - */ -#require_once 'Zend/Tool/Framework/Metadata/Interface.php'; - -/** - * @see Zend_Tool_Framework_Metadata_Attributable - */ -#require_once 'Zend/Tool/Framework/Metadata/Attributable.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Metadata_Dynamic - implements Zend_Tool_Framework_Metadata_Interface, Zend_Tool_Framework_Metadata_Attributable -{ - - /** - * @var string - */ - protected $_type = 'Dynamic'; - - /** - * @var string - */ - protected $_name = null; - - /** - * @var string - */ - protected $_value = null; - - /** - * @var array - */ - protected $_dynamicAttributes = array(); - - public function __construct($options = array()) - { - if ($options) { - $this->setOptions($options); - } - } - - public function setOptions(Array $options = array()) - { - foreach ($options as $optName => $optValue) { - $methodName = 'set' . $optName; - $this->{$methodName}($optValue); - } - } - - /** - * setType() - * - * @param string $type - * @return Zend_Tool_Framework_Metadata_Dynamic - */ - public function setType($type) - { - $this->_type = $type; - return $this; - } - - /** - * getType() - * - * The type of metadata this describes - * - * @return string - */ - public function getType() - { - return $this->_type; - } - - /** - * setName() - * - * @param string $name - * @return Zend_Tool_Framework_Metadata_Dynamic - */ - public function setName($name) - { - $this->_name = $name; - return $this; - } - - /** - * getName() - * - * Metadata name - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * setValue() - * - * @param mixed $value - * @return Zend_Tool_Framework_Metadata_Dynamic - */ - public function setValue($value) - { - $this->_value = $value; - return $this; - } - - /** - * getValue() - * - * Metadata Value - * - * @return string - */ - public function getValue() - { - return $this->_value; - } - - public function getAttributes() - { - return $this->_dynamicAttributes; - } - - /** - * __isset() - * - * Check if an attrbute is set - * - * @param string $name - * @return bool - */ - public function __isset($name) - { - return isset($this->_dynamicAttributes[$name]); - } - - /** - * __unset() - * - * @param string $name - * @return null - */ - public function __unset($name) - { - unset($this->_dynamicAttributes[$name]); - return; - } - - /** - * __get() - Get a property via property call $metadata->foo - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, 'get' . $name)) { - return $this->{'get' . $name}(); - } elseif (array_key_exists($name, $this->_dynamicAttributes)) { - return $this->_dynamicAttributes[$name]; - } else { - #require_once 'Zend/Tool/Framework/Registry/Exception.php'; - throw new Zend_Tool_Framework_Registry_Exception('Property ' . $name . ' was not located in this metadata.'); - } - } - - /** - * __set() - Set a property via the magic set $metadata->foo = 'foo' - * - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) - { - if (method_exists($this, 'set' . $name)) { - $this->{'set' . $name}($value); - return $this; - } else { - $this->_dynamicAttributes[$name] = $value; - return $this; - } -// { -// #require_once 'Zend/Tool/Framework/Registry/Exception.php'; -// throw new Zend_Tool_Framework_Registry_Exception('Property ' . $name . ' was not located in this registry.'); -// } - } - -} diff --git a/lib/Zend/Tool/Framework/Metadata/Interface.php b/lib/Zend/Tool/Framework/Metadata/Interface.php deleted file mode 100644 index d7e327bf340..00000000000 --- a/lib/Zend/Tool/Framework/Metadata/Interface.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Metadata_Interface -{ - - /** - * getType() - * - * The type of metadata this describes - * - */ - public function getType(); - - /** - * getName() - * - */ - public function getName(); - - /** - * getValue() - * - */ - public function getValue(); - -} diff --git a/lib/Zend/Tool/Framework/Metadata/Tool.php b/lib/Zend/Tool/Framework/Metadata/Tool.php deleted file mode 100644 index 2dc678c4d2c..00000000000 --- a/lib/Zend/Tool/Framework/Metadata/Tool.php +++ /dev/null @@ -1,218 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Metadata_Basic - */ -#require_once 'Zend/Tool/Framework/Metadata/Basic.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Metadata_Tool extends Zend_Tool_Framework_Metadata_Basic -{ - - /** - * @var string - */ - protected $_type = 'Tool'; - - /**#@+ - * @var string - */ - protected $_clientName = null; - protected $_actionName = null; - protected $_providerName = null; - protected $_specialtyName = null; - /**#@-*/ - - /**#@+ - * @var string - */ - protected $_clientReference = null; - protected $_actionReference = null; - protected $_providerReference = null; - /**#@-*/ - - public function setClientName($clientName) - { - $this->_clientName = $clientName; - return $this; - } - - public function getClientName() - { - return $this->_clientName; - } - - /** - * setActionName() - * - * @param string $actionName - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setActionName($actionName) - { - $this->_actionName = $actionName; - return $this; - } - - /** - * getActionName() - * - * @return string - */ - public function getActionName() - { - return $this->_actionName; - } - - /** - * setProviderName() - * - * @param string $providerName - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setProviderName($providerName) - { - $this->_providerName = $providerName; - return $this; - } - - /** - * getProviderName() - * - * @return string - */ - public function getProviderName() - { - return $this->_providerName; - } - - /** - * setSpecialtyName() - * - * @param string $specialtyName - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setSpecialtyName($specialtyName) - { - $this->_specialtyName = $specialtyName; - return $this; - } - - /** - * getSpecialtyName() - * - * @return string - */ - public function getSpecialtyName() - { - return $this->_specialtyName; - } - - /** - * setClientReference() - * - * @param Zend_Tool_Framework_Client_Abstract $client - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setClientReference(Zend_Tool_Framework_Client_Abstract $client) - { - $this->_clientReference = $client; - return $this; - } - - /** - * getClientReference() - * - * @return Zend_Tool_Framework_Client_Abstract - */ - public function getClientReference() - { - return $this->_clientReference; - } - - /** - * setActionReference() - * - * @param Zend_Tool_Framework_Action_Interface $action - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setActionReference(Zend_Tool_Framework_Action_Interface $action) - { - $this->_actionReference = $action; - return $this; - } - - /** - * getActionReference() - * - * @return Zend_Tool_Framework_Action_Interface - */ - public function getActionReference() - { - return $this->_actionReference; - } - - /** - * setProviderReference() - * - * @param Zend_Tool_Framework_Provider_Interface $provider - * @return Zend_Tool_Framework_Metadata_Tool - */ - public function setProviderReference(Zend_Tool_Framework_Provider_Interface $provider) - { - $this->_providerReference = $provider; - return $this; - } - - /** - * getProviderReference() - * - * @return Zend_Tool_Framework_Provider_Interface - */ - public function getProviderReference() - { - return $this->_providerReference; - } - - /** - * __toString() cast to string - * - * @return string - */ - public function __toString() - { - $string = parent::__toString(); - $string .= ' (ProviderName: ' . $this->_providerName - . ', ActionName: ' . $this->_actionName - . ', SpecialtyName: ' . $this->_specialtyName - . ')'; - - return $string; - } - -} diff --git a/lib/Zend/Tool/Framework/Provider/Abstract.php b/lib/Zend/Tool/Framework/Provider/Abstract.php deleted file mode 100644 index 0fc0709c55b..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Abstract.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Provider_Interface - */ -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - - -/** - * This is a convenience class. - * - * At current it will return the request and response from the client registry - * as they are the more common things that will be needed by providers - * - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tool_Framework_Provider_Abstract - implements Zend_Tool_Framework_Provider_Interface, Zend_Tool_Framework_Registry_EnabledInterface -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - /** - * setRegistry() - required by Zend_Tool_Framework_Registry_EnabledInterface - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Provider_Abstract - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - -} diff --git a/lib/Zend/Tool/Framework/Provider/DocblockManifestable.php b/lib/Zend/Tool/Framework/Provider/DocblockManifestable.php deleted file mode 100644 index 19bd7d6d79c..00000000000 --- a/lib/Zend/Tool/Framework/Provider/DocblockManifestable.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Provider_DocblockManifestInterface -{ -} diff --git a/lib/Zend/Tool/Framework/Provider/Exception.php b/lib/Zend/Tool/Framework/Provider/Exception.php deleted file mode 100644 index 9eb80b313a3..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Exception - */ -#require_once 'Zend/Tool/Framework/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Provider_Exception extends Zend_Tool_Framework_Exception -{ - -} diff --git a/lib/Zend/Tool/Framework/Provider/Initializable.php b/lib/Zend/Tool/Framework/Provider/Initializable.php deleted file mode 100644 index 2e3e106845b..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Initializable.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: Interactable.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Provider_Initializable -{ - public function initialize(); -} diff --git a/lib/Zend/Tool/Framework/Provider/Interactable.php b/lib/Zend/Tool/Framework/Provider/Interactable.php deleted file mode 100644 index bc9d5449f64..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Interactable.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Provider_Interactable -{ -} diff --git a/lib/Zend/Tool/Framework/Provider/Interface.php b/lib/Zend/Tool/Framework/Provider/Interface.php deleted file mode 100644 index 085164755b3..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Interface.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Provider_Interface -{ -} diff --git a/lib/Zend/Tool/Framework/Provider/Pretendable.php b/lib/Zend/Tool/Framework/Provider/Pretendable.php deleted file mode 100644 index dde07def895..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Pretendable.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Provider_Pretendable -{ -} diff --git a/lib/Zend/Tool/Framework/Provider/Repository.php b/lib/Zend/Tool/Framework/Provider/Repository.php deleted file mode 100644 index f03f79aa08b..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Repository.php +++ /dev/null @@ -1,275 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Provider_Signature - */ -#require_once 'Zend/Tool/Framework/Provider/Signature.php'; - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Provider_Repository - implements Zend_Tool_Framework_Registry_EnabledInterface, IteratorAggregate, Countable -{ - - /** - * @var Zend_Tool_Framework_Registry - */ - protected $_registry = null; - - /** - * @var bool - */ - protected $_processOnAdd = false; - - /** - * @var Zend_Tool_Framework_Provider_Interface[] - */ - protected $_unprocessedProviders = array(); - - /** - * @var Zend_Tool_Framework_Provider_Signature[] - */ - protected $_providerSignatures = array(); - - /** - * @var array Array of Zend_Tool_Framework_Provider_Inteface - */ - protected $_providers = array(); - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return unknown - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * Set the ProcessOnAdd flag - * - * @param unknown_type $processOnAdd - * @return unknown - */ - public function setProcessOnAdd($processOnAdd = true) - { - $this->_processOnAdd = (bool) $processOnAdd; - return $this; - } - - /** - * Add a provider to the repository for processing - * - * @param Zend_Tool_Framework_Provider_Interface $provider - * @return Zend_Tool_Framework_Provider_Repository - */ - public function addProvider(Zend_Tool_Framework_Provider_Interface $provider, $overwriteExistingProvider = false) - { - if ($provider instanceof Zend_Tool_Framework_Registry_EnabledInterface) { - $provider->setRegistry($this->_registry); - } - - if (method_exists($provider, 'getName')) { - $providerName = $provider->getName(); - } else { - $providerName = $this->_parseName($provider); - } - - // if a provider by the given name already exist, and its not set as overwritable, throw exception - if (!$overwriteExistingProvider && - (array_key_exists($providerName, $this->_unprocessedProviders) - || array_key_exists($providerName, $this->_providers))) - { - #require_once 'Zend/Tool/Framework/Provider/Exception.php'; - throw new Zend_Tool_Framework_Provider_Exception('A provider by the name ' . $providerName - . ' is already registered and $overrideExistingProvider is set to false.'); - } - - $this->_unprocessedProviders[$providerName] = $provider; - - // if process has already been called, process immediately. - if ($this->_processOnAdd) { - $this->process(); - } - - return $this; - } - - public function hasProvider($providerOrClassName, $processedOnly = true) - { - if ($providerOrClassName instanceof Zend_Tool_Framework_Provider_Interface) { - $targetProviderClassName = get_class($providerOrClassName); - } else { - $targetProviderClassName = (string) $providerOrClassName; - } - - if (!$processedOnly) { - foreach ($this->_unprocessedProviders as $unprocessedProvider) { - if (get_class($unprocessedProvider) == $targetProviderClassName) { - return true; - } - } - } - - foreach ($this->_providers as $processedProvider) { - if (get_class($processedProvider) == $targetProviderClassName) { - return true; - } - } - - return false; - } - - /** - * Process all of the unprocessed providers - * - */ - public function process() - { - - // process all providers in the unprocessedProviders array - //foreach ($this->_unprocessedProviders as $providerName => $provider) { - reset($this->_unprocessedProviders); - while ($this->_unprocessedProviders) { - - $providerName = key($this->_unprocessedProviders); - $provider = array_shift($this->_unprocessedProviders); - - // create a signature for the provided provider - $providerSignature = new Zend_Tool_Framework_Provider_Signature($provider); - - if ($providerSignature instanceof Zend_Tool_Framework_Registry_EnabledInterface) { - $providerSignature->setRegistry($this->_registry); - } - - $providerSignature->process(); - - // ensure the name is lowercased for easier searching - $providerName = strtolower($providerName); - - // add to the appropraite place - $this->_providerSignatures[$providerName] = $providerSignature; - $this->_providers[$providerName] = $providerSignature->getProvider(); - - if ($provider instanceof Zend_Tool_Framework_Provider_Initializable) { - $provider->initialize(); - } - - } - - } - - /** - * getProviders() Get all the providers in the repository - * - * @return array - */ - public function getProviders() - { - return $this->_providers; - } - - /** - * getProviderSignatures() Get all the provider signatures - * - * @return array - */ - public function getProviderSignatures() - { - return $this->_providerSignatures; - } - - /** - * getProvider() - * - * @param string $providerName - * @return Zend_Tool_Framework_Provider_Interface - */ - public function getProvider($providerName) - { - return $this->_providers[strtolower($providerName)]; - } - - /** - * getProviderSignature() - * - * @param string $providerName - * @return Zend_Tool_Framework_Provider_Signature - */ - public function getProviderSignature($providerName) - { - return $this->_providerSignatures[strtolower($providerName)]; - } - - /** - * count() - return the number of providers - * - * @return int - */ - public function count() - { - return count($this->_providers); - } - - /** - * getIterator() - Required by the IteratorAggregate Interface - * - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->getProviders()); - } - - /** - * _parseName - internal method to determine the name of an action when one is not explicity provided. - * - * @param Zend_Tool_Framework_Action_Interface $action - * @return string - */ - protected function _parseName(Zend_Tool_Framework_Provider_Interface $provider) - { - $className = get_class($provider); - $providerName = $className; - if (strpos($providerName, '_') !== false) { - $providerName = substr($providerName, strrpos($providerName, '_')+1); - } - if (substr($providerName, -8) == 'Provider') { - $providerName = substr($providerName, 0, strlen($providerName)-8); - } - return $providerName; - } - -} diff --git a/lib/Zend/Tool/Framework/Provider/Signature.php b/lib/Zend/Tool/Framework/Provider/Signature.php deleted file mode 100644 index 6cb3ff31439..00000000000 --- a/lib/Zend/Tool/Framework/Provider/Signature.php +++ /dev/null @@ -1,394 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Reflection_Class - */ -#require_once 'Zend/Reflection/Class.php'; - -/** - * @see Zend_Tool_Framework_Registry - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @see Zend_Tool_Framework_Action_Base - */ -#require_once 'Zend/Tool/Framework/Action/Base.php'; - -/** - * The purpose of Zend_Tool_Framework_Provider_Signature is to derive - * callable signatures from the provided provider. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Provider_Signature implements Zend_Tool_Framework_Registry_EnabledInterface -{ - - /** - * @var Zend_Tool_Framework_Registry - */ - protected $_registry = null; - - /** - * @var Zend_Tool_Framework_Provider_Interface - */ - protected $_provider = null; - - /** - * @var string - */ - protected $_name = null; - - /** - * @var array - */ - protected $_specialties = array(); - - /** - * @var array - */ - protected $_actionableMethods = array(); - - /** - * @var unknown_type - */ - protected $_actions = array(); - - /** - * @var Zend_Reflection_Class - */ - protected $_providerReflection = null; - - /** - * @var bool - */ - protected $_isProcessed = false; - - /** - * Constructor - * - * @param Zend_Tool_Framework_Provider_Interface $provider - */ - public function __construct(Zend_Tool_Framework_Provider_Interface $provider) - { - $this->_provider = $provider; - $this->_providerReflection = new Zend_Reflection_Class($provider); - } - - /** - * setRegistry() - * - * @param Zend_Tool_Framework_Registry_Interface $registry - * @return Zend_Tool_Framework_Provider_Signature - */ - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - public function process() - { - if ($this->_isProcessed) { - return; - } - - $this->_process(); - } - - /** - * getName() of the provider - * - * @return unknown - */ - public function getName() - { - return $this->_name; - } - - /** - * Get the provider for this signature - * - * @return Zend_Tool_Framework_Provider_Interface - */ - public function getProvider() - { - return $this->_provider; - } - - /** - * getProviderReflection() - * - * @return Zend_Reflection_Class - */ - public function getProviderReflection() - { - return $this->_providerReflection; - } - - /** - * getSpecialities() - * - * @return array - */ - public function getSpecialties() - { - return $this->_specialties; - } - - /** - * getActions() - * - * @return array Array of Actions - */ - public function getActions() - { - return $this->_actions; - } - - /** - * getActionableMethods() - * - * @return array - */ - public function getActionableMethods() - { - return $this->_actionableMethods; - } - - /** - * getActionableMethod() - Get an actionable method by name, this will return an array of - * useful information about what can be exectued on this provider - * - * @param string $methodName - * @return array - */ - public function getActionableMethod($methodName) - { - if (isset($this->_actionableMethods[$methodName])) { - return $this->_actionableMethods[$methodName]; - } - - return false; - } - - /** - * getActionableMethodByActionName() - Get an actionable method by its action name, this - * will return an array of useful information about what can be exectued on this provider - * - * @param string $actionName - * @return array - */ - public function getActionableMethodByActionName($actionName, $specialtyName = '_Global') - { - foreach ($this->_actionableMethods as $actionableMethod) { - if ($actionName == $actionableMethod['actionName'] - && $specialtyName == $actionableMethod['specialty']) { - return $actionableMethod; - } - } - - return false; - } - - /** - * _process() is called at construction time and is what will build the signature information - * for determining what is actionable - * - */ - protected function _process() - { - $this->_isProcessed = true; - $this->_processName(); - $this->_processSpecialties(); - $this->_processActionableMethods(); - } - - /** - * _processName(); - * - */ - protected function _processName() - { - if (method_exists($this->_provider, 'getName')) { - $this->_name = $this->_provider->getName(); - } - - if ($this->_name == null) { - $className = get_class($this->_provider); - $name = $className; - if (strpos($name, '_')) { - $name = substr($name, strrpos($name, '_')+1); - } - $name = preg_replace('#(Provider|Manifest)$#', '', $name); - $this->_name = $name; - } - } - - /** - * _processSpecialties() - Break out the specialty names for this provider - * - */ - protected function _processSpecialties() - { - $specialties = array(); - - if ($this->_providerReflection->hasMethod('getSpecialties')) { - $specialties = $this->_provider->getSpecialties(); - if (!is_array($specialties)) { - #require_once 'Zend/Tool/Framework/Provider/Exception.php'; - throw new Zend_Tool_Framework_Provider_Exception( - 'Provider ' . get_class($this->_provider) . ' must return an array for method getSpecialties().' - ); - } - } else { - $defaultProperties = $this->_providerReflection->getDefaultProperties(); - $specialties = (isset($defaultProperties['_specialties'])) ? $defaultProperties['_specialties'] : array(); - if (!is_array($specialties)) { - #require_once 'Zend/Tool/Framework/Provider/Exception.php'; - throw new Zend_Tool_Framework_Provider_Exception( - 'Provider ' . get_class($this->_provider) . '\'s property $_specialties must be an array.' - ); - } - } - - $this->_specialties = array_merge(array('_Global'), $specialties); - - } - - /** - * _processActionableMethods() - process all methods that can be called on this provider. - * - */ - protected function _processActionableMethods() - { - - $specialtyRegex = '#(.*)(' . implode('|', $this->_specialties) . ')$#i'; - - - $methods = $this->_providerReflection->getMethods(); - - $actionableMethods = array(); - foreach ($methods as $method) { - - $methodName = $method->getName(); - - /** - * the following will determine what methods are actually actionable - * public, non-static, non-underscore prefixed, classes that dont - * contain the name " - */ - if (!$method->getDeclaringClass()->isInstantiable() - || !$method->isPublic() - || $methodName[0] == '_' - || $method->isStatic() - || in_array($methodName, array('getContextClasses', 'getName')) // other protected public methods will nee to go here - ) { - continue; - } - - /** - * check to see if the method was a required method by a Zend_Tool_* interface - */ - foreach ($method->getDeclaringClass()->getInterfaces() as $methodDeclaringClassInterface) { - if (strpos($methodDeclaringClassInterface->getName(), 'Zend_Tool_') === 0 - && $methodDeclaringClassInterface->hasMethod($methodName)) { - continue 2; - } - } - - $actionableName = ucfirst($methodName); - - if (substr($actionableName, -6) == 'Action') { - $actionableName = substr($actionableName, 0, -6); - } - - $actionableMethods[$methodName]['methodName'] = $methodName; - - $matches = null; - if (preg_match($specialtyRegex, $actionableName, $matches)) { - $actionableMethods[$methodName]['actionName'] = $matches[1]; - $actionableMethods[$methodName]['specialty'] = $matches[2]; - } else { - $actionableMethods[$methodName]['actionName'] = $actionableName; - $actionableMethods[$methodName]['specialty'] = '_Global'; - } - - // get the action, and create non-existent actions when they dont exist (the true part below) - $action = $this->_registry->getActionRepository()->getAction($actionableMethods[$methodName]['actionName']); - if ($action == null) { - $action = new Zend_Tool_Framework_Action_Base($actionableMethods[$methodName]['actionName']); - $this->_registry->getActionRepository()->addAction($action); - } - $actionableMethods[$methodName]['action'] = $action; - - if (!in_array($actionableMethods[$methodName]['action'], $this->_actions)) { - $this->_actions[] = $actionableMethods[$methodName]['action']; - } - - $parameterInfo = array(); - $position = 1; - foreach ($method->getParameters() as $parameter) { - $currentParam = $parameter->getName(); - $parameterInfo[$currentParam]['position'] = $position++; - $parameterInfo[$currentParam]['optional'] = $parameter->isOptional(); - $parameterInfo[$currentParam]['default'] = ($parameter->isOptional()) ? $parameter->getDefaultValue() : null; - $parameterInfo[$currentParam]['name'] = $currentParam; - $parameterInfo[$currentParam]['type'] = 'string'; - $parameterInfo[$currentParam]['description'] = null; - } - - $matches = null; - if (($docComment = $method->getDocComment()) != '' && - (preg_match_all('/@param\s+(\w+)+\s+(\$\S+)\s+(.*?)(?=(?:\*\s*@)|(?:\*\/))/s', $docComment, $matches))) - { - for ($i=0; $i <= count($matches[0])-1; $i++) { - $currentParam = ltrim($matches[2][$i], '$'); - - if ($currentParam != '' && isset($parameterInfo[$currentParam])) { - - $parameterInfo[$currentParam]['type'] = $matches[1][$i]; - - $descriptionSource = $matches[3][$i]; - - if ($descriptionSource != '') { - $parameterInfo[$currentParam]['description'] = trim($descriptionSource); - } - - } - - } - - } - - $actionableMethods[$methodName]['parameterInfo'] = $parameterInfo; - - } - - $this->_actionableMethods = $actionableMethods; - } - -} diff --git a/lib/Zend/Tool/Framework/Registry.php b/lib/Zend/Tool/Framework/Registry.php deleted file mode 100644 index 12bba90bba0..00000000000 --- a/lib/Zend/Tool/Framework/Registry.php +++ /dev/null @@ -1,419 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Registry_Interface - */ -#require_once 'Zend/Tool/Framework/Registry/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Registry implements Zend_Tool_Framework_Registry_Interface -{ - /** - * @var Zend_Tool_Framework_Loader_Abstract - */ - protected $_loader = null; - - /** - * @var Zend_Tool_Framework_Client_Abstract - */ - protected $_client = null; - - /** - * @var Zend_Tool_Framework_Client_Config - */ - protected $_config = null; - - /** - * @var Zend_Tool_Framework_Client_Storage - */ - protected $_storage = null; - - /** - * @var Zend_Tool_Framework_Action_Repository - */ - protected $_actionRepository = null; - - /** - * @var Zend_Tool_Framework_Provider_Repository - */ - protected $_providerRepository = null; - - /** - * @var Zend_Tool_Framework_Manifest_Repository - */ - protected $_manifestRepository = null; - - /** - * @var Zend_Tool_Framework_Client_Request - */ - protected $_request = null; - - /** - * @var Zend_Tool_Framework_Client_Response - */ - protected $_response = null; - - /** - * reset() - Reset all internal properties - * - */ - public function reset() - { - unset($this->_client); - unset($this->_loader); - unset($this->_actionRepository); - unset($this->_providerRepository); - unset($this->_request); - unset($this->_response); - } - -// public function __construct() -// { -// // no instantiation from outside -// } - - /** - * Enter description here... - * - * @param Zend_Tool_Framework_Client_Abstract $client - * @return Zend_Tool_Framework_Registry - */ - public function setClient(Zend_Tool_Framework_Client_Abstract $client) - { - $this->_client = $client; - if ($this->isObjectRegistryEnablable($this->_client)) { - $this->enableRegistryOnObject($this->_client); - } - return $this; - } - - /** - * getClient() return the client in the registry - * - * @return Zend_Tool_Framework_Client_Abstract - */ - public function getClient() - { - return $this->_client; - } - - /** - * setConfig() - * - * @param Zend_Tool_Framework_Client_Config $config - * @return Zend_Tool_Framework_Registry - */ - public function setConfig(Zend_Tool_Framework_Client_Config $config) - { - $this->_config = $config; - return $this; - } - - /** - * getConfig() - * - * @return Zend_Tool_Framework_Client_Config - */ - public function getConfig() - { - if ($this->_config === null) { - #require_once 'Zend/Tool/Framework/Client/Config.php'; - $this->setConfig(new Zend_Tool_Framework_Client_Config()); - } - - return $this->_config; - } - - /** - * setStorage() - * - * @param Zend_Tool_Framework_Client_Storage $storage - * @return Zend_Tool_Framework_Registry - */ - public function setStorage(Zend_Tool_Framework_Client_Storage $storage) - { - $this->_storage = $storage; - return $this; - } - - /** - * getConfig() - * - * @return Zend_Tool_Framework_Client_Storage - */ - public function getStorage() - { - if ($this->_storage === null) { - #require_once 'Zend/Tool/Framework/Client/Storage.php'; - $this->setStorage(new Zend_Tool_Framework_Client_Storage()); - } - - return $this->_storage; - } - - /** - * setLoader() - * - * @param Zend_Tool_Framework_Loader_Interface $loader - * @return Zend_Tool_Framework_Registry - */ - public function setLoader(Zend_Tool_Framework_Loader_Interface $loader) - { - $this->_loader = $loader; - if ($this->isObjectRegistryEnablable($this->_loader)) { - $this->enableRegistryOnObject($this->_loader); - } - return $this; - } - - /** - * getLoader() - * - * @return Zend_Tool_Framework_Loader_Abstract - */ - public function getLoader() - { - if ($this->_loader === null) { - #require_once 'Zend/Tool/Framework/Loader/IncludePathLoader.php'; - $this->setLoader(new Zend_Tool_Framework_Loader_IncludePathLoader()); - } - - return $this->_loader; - } - - /** - * setActionRepository() - * - * @param Zend_Tool_Framework_Action_Repository $actionRepository - * @return Zend_Tool_Framework_Registry - */ - public function setActionRepository(Zend_Tool_Framework_Action_Repository $actionRepository) - { - $this->_actionRepository = $actionRepository; - if ($this->isObjectRegistryEnablable($this->_actionRepository)) { - $this->enableRegistryOnObject($this->_actionRepository); - } - return $this; - } - - /** - * getActionRepository() - * - * @return Zend_Tool_Framework_Action_Repository - */ - public function getActionRepository() - { - if ($this->_actionRepository == null) { - #require_once 'Zend/Tool/Framework/Action/Repository.php'; - $this->setActionRepository(new Zend_Tool_Framework_Action_Repository()); - } - - return $this->_actionRepository; - } - - /** - * setProviderRepository() - * - * @param Zend_Tool_Framework_Provider_Repository $providerRepository - * @return Zend_Tool_Framework_Registry - */ - public function setProviderRepository(Zend_Tool_Framework_Provider_Repository $providerRepository) - { - $this->_providerRepository = $providerRepository; - if ($this->isObjectRegistryEnablable($this->_providerRepository)) { - $this->enableRegistryOnObject($this->_providerRepository); - } - return $this; - } - - /** - * getProviderRepository() - * - * @return Zend_Tool_Framework_Provider_Repository - */ - public function getProviderRepository() - { - if ($this->_providerRepository == null) { - #require_once 'Zend/Tool/Framework/Provider/Repository.php'; - $this->setProviderRepository(new Zend_Tool_Framework_Provider_Repository()); - } - - return $this->_providerRepository; - } - - /** - * setManifestRepository() - * - * @param Zend_Tool_Framework_Manifest_Repository $manifestRepository - * @return Zend_Tool_Framework_Registry - */ - public function setManifestRepository(Zend_Tool_Framework_Manifest_Repository $manifestRepository) - { - $this->_manifestRepository = $manifestRepository; - if ($this->isObjectRegistryEnablable($this->_manifestRepository)) { - $this->enableRegistryOnObject($this->_manifestRepository); - } - return $this; - } - - /** - * getManifestRepository() - * - * @return Zend_Tool_Framework_Manifest_Repository - */ - public function getManifestRepository() - { - if ($this->_manifestRepository == null) { - #require_once 'Zend/Tool/Framework/Manifest/Repository.php'; - $this->setManifestRepository(new Zend_Tool_Framework_Manifest_Repository()); - } - - return $this->_manifestRepository; - } - - /** - * setRequest() - * - * @param Zend_Tool_Framework_Client_Request $request - * @return Zend_Tool_Framework_Registry - */ - public function setRequest(Zend_Tool_Framework_Client_Request $request) - { - $this->_request = $request; - return $this; - } - - /** - * getRequest() - * - * @return Zend_Tool_Framework_Client_Request - */ - public function getRequest() - { - if ($this->_request == null) { - #require_once 'Zend/Tool/Framework/Client/Request.php'; - $this->setRequest(new Zend_Tool_Framework_Client_Request()); - } - - return $this->_request; - } - - /** - * setResponse() - * - * @param Zend_Tool_Framework_Client_Response $response - * @return Zend_Tool_Framework_Registry - */ - public function setResponse(Zend_Tool_Framework_Client_Response $response) - { - $this->_response = $response; - return $this; - } - - /** - * getResponse() - * - * @return Zend_Tool_Framework_Client_Response - */ - public function getResponse() - { - if ($this->_response == null) { - #require_once 'Zend/Tool/Framework/Client/Response.php'; - $this->setResponse(new Zend_Tool_Framework_Client_Response()); - } - - return $this->_response; - } - - /** - * __get() - Get a property via property call $registry->foo - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, 'get' . $name)) { - return $this->{'get' . $name}(); - } else { - #require_once 'Zend/Tool/Framework/Registry/Exception.php'; - throw new Zend_Tool_Framework_Registry_Exception('Property ' . $name . ' was not located in this registry.'); - } - } - - /** - * __set() - Set a property via the magic set $registry->foo = 'foo' - * - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) - { - if (method_exists($this, 'set' . $name)) { - $this->{'set' . $name}($value); - return; - } else { - #require_once 'Zend/Tool/Framework/Registry/Exception.php'; - throw new Zend_Tool_Framework_Registry_Exception('Property ' . $name . ' was not located in this registry.'); - } - } - - /** - * isObjectRegistryEnablable() - Check whether an object is registry enablable - * - * @param object $object - * @return bool - */ - public function isObjectRegistryEnablable($object) - { - if (!is_object($object)) { - #require_once 'Zend/Tool/Framework/Registry/Exception.php'; - throw new Zend_Tool_Framework_Registry_Exception('isObjectRegistryEnablable() expects an object.'); - } - - return ($object instanceof Zend_Tool_Framework_Registry_EnabledInterface); - } - - /** - * enableRegistryOnObject() - make an object registry enabled - * - * @param object $object - * @return Zend_Tool_Framework_Registry - */ - public function enableRegistryOnObject($object) - { - if (!$this->isObjectRegistryEnablable($object)) { - #require_once 'Zend/Tool/Framework/Registry/Exception.php'; - throw new Zend_Tool_Framework_Registry_Exception('Object provided is not registry enablable, check first with Zend_Tool_Framework_Registry::isObjectRegistryEnablable()'); - } - - $object->setRegistry($this); - return $this; - } - -} diff --git a/lib/Zend/Tool/Framework/Registry/EnabledInterface.php b/lib/Zend/Tool/Framework/Registry/EnabledInterface.php deleted file mode 100644 index 5a97c8bd325..00000000000 --- a/lib/Zend/Tool/Framework/Registry/EnabledInterface.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This is a convenience class. - * - * At current it will return the request and response from the client registry - * as they are the more common things that will be needed by providers - * - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Registry_EnabledInterface -{ - - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry); - -} diff --git a/lib/Zend/Tool/Framework/Registry/Exception.php b/lib/Zend/Tool/Framework/Registry/Exception.php deleted file mode 100644 index 2597e09c634..00000000000 --- a/lib/Zend/Tool/Framework/Registry/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Framework/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_Registry_Exception extends Zend_Tool_Framework_Exception -{ - -} diff --git a/lib/Zend/Tool/Framework/Registry/Interface.php b/lib/Zend/Tool/Framework/Registry/Interface.php deleted file mode 100644 index 6636583e776..00000000000 --- a/lib/Zend/Tool/Framework/Registry/Interface.php +++ /dev/null @@ -1,137 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Framework_Registry_Interface -{ - - - /** - * setClient() - * - * @param Zend_Tool_Framework_Client_Abstract $client - * @return Zend_Tool_Framework_Registry - */ - public function setClient(Zend_Tool_Framework_Client_Abstract $client); - - /** - * getClient() return the client in the registry - * - * @return Zend_Tool_Framework_Client_Abstract - */ - public function getClient(); - - /** - * setLoader() - * - * @param Zend_Tool_Framework_Loader_Abstract $loader - * @return Zend_Tool_Framework_Registry - */ - public function setLoader(Zend_Tool_Framework_Loader_Interface $loader); - - /** - * getLoader() - * - * @return Zend_Tool_Framework_Loader_Abstract - */ - public function getLoader(); - - /** - * setActionRepository() - * - * @param Zend_Tool_Framework_Action_Repository $actionRepository - * @return Zend_Tool_Framework_Registry - */ - public function setActionRepository(Zend_Tool_Framework_Action_Repository $actionRepository); - - /** - * getActionRepository() - * - * @return Zend_Tool_Framework_Action_Repository - */ - public function getActionRepository(); - - /** - * setProviderRepository() - * - * @param Zend_Tool_Framework_Provider_Repository $providerRepository - * @return Zend_Tool_Framework_Registry - */ - public function setProviderRepository(Zend_Tool_Framework_Provider_Repository $providerRepository); - - /** - * getProviderRepository() - * - * @return Zend_Tool_Framework_Provider_Repository - */ - public function getProviderRepository(); - - /** - * setManifestRepository() - * - * @param Zend_Tool_Framework_Manifest_Repository $manifestRepository - * @return Zend_Tool_Framework_Registry - */ - public function setManifestRepository(Zend_Tool_Framework_Manifest_Repository $manifestRepository); - - /** - * getManifestRepository() - * - * @return Zend_Tool_Framework_Manifest_Repository - */ - public function getManifestRepository(); - - /** - * setRequest() - * - * @param Zend_Tool_Framework_Client_Request $request - * @return Zend_Tool_Framework_Registry - */ - public function setRequest(Zend_Tool_Framework_Client_Request $request); - - /** - * getRequest() - * - * @return Zend_Tool_Framework_Client_Request - */ - public function getRequest(); - - /** - * setResponse() - * - * @param Zend_Tool_Framework_Client_Response $response - * @return Zend_Tool_Framework_Registry - */ - public function setResponse(Zend_Tool_Framework_Client_Response $response); - - /** - * getResponse() - * - * @return Zend_Tool_Framework_Client_Response - */ - public function getResponse(); - -} diff --git a/lib/Zend/Tool/Framework/System/Action/Create.php b/lib/Zend/Tool/Framework/System/Action/Create.php deleted file mode 100644 index dc504cc4dc8..00000000000 --- a/lib/Zend/Tool/Framework/System/Action/Create.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Action_Base - */ -#require_once 'Zend/Tool/Framework/Action/Base.php'; - - -/** - * This is a convenience class. - * - * At current it will return the request and response from the client registry - * as they are the more common things that will be needed by providers - * - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Action_Create extends Zend_Tool_Framework_Action_Base -{ - -} diff --git a/lib/Zend/Tool/Framework/System/Action/Delete.php b/lib/Zend/Tool/Framework/System/Action/Delete.php deleted file mode 100644 index 06b29ae584e..00000000000 --- a/lib/Zend/Tool/Framework/System/Action/Delete.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Action_Base - */ -#require_once 'Zend/Tool/Framework/Action/Base.php'; - - -/** - * This is a convenience class. - * - * At current it will return the request and response from the client registry - * as they are the more common things that will be needed by providers - * - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Action_Delete extends Zend_Tool_Framework_Action_Base -{ - -} diff --git a/lib/Zend/Tool/Framework/System/Manifest.php b/lib/Zend/Tool/Framework/System/Manifest.php deleted file mode 100644 index cb3692765b8..00000000000 --- a/lib/Zend/Tool/Framework/System/Manifest.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Framework/Manifest/ProviderManifestable.php'; -#require_once 'Zend/Tool/Framework/Manifest/ActionManifestable.php'; -#require_once 'Zend/Tool/Framework/System/Provider/Version.php'; -#require_once 'Zend/Tool/Framework/System/Provider/Config.php'; -#require_once 'Zend/Tool/Framework/System/Provider/Phpinfo.php'; -#require_once 'Zend/Tool/Framework/System/Provider/Manifest.php'; -#require_once 'Zend/Tool/Framework/System/Action/Create.php'; -#require_once 'Zend/Tool/Framework/System/Action/Delete.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Manifest - implements Zend_Tool_Framework_Manifest_ProviderManifestable, Zend_Tool_Framework_Manifest_ActionManifestable -{ - - public function getProviders() - { - $providers = array( - new Zend_Tool_Framework_System_Provider_Version(), - new Zend_Tool_Framework_System_Provider_Config(), - new Zend_Tool_Framework_System_Provider_Phpinfo(), - new Zend_Tool_Framework_System_Provider_Manifest() - ); - - return $providers; - } - - public function getActions() - { - $actions = array( - new Zend_Tool_Framework_System_Action_Create(), - new Zend_Tool_Framework_System_Action_Delete() - ); - - return $actions; - } -} diff --git a/lib/Zend/Tool/Framework/System/Provider/Config.php b/lib/Zend/Tool/Framework/System/Provider/Config.php deleted file mode 100644 index 1d15ba7b03d..00000000000 --- a/lib/Zend/Tool/Framework/System/Provider/Config.php +++ /dev/null @@ -1,323 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ - -/** - * @see Zend_Tool_Framework_Provider_Abstract - */ -#require_once "Zend/Tool/Framework/Provider/Abstract.php"; - -/** - * @see Zend_Config - */ -#require_once "Zend/Config.php"; - -/** - * @see Zend_Config_Writer_Ini - */ -#require_once "Zend/Config/Writer/Ini.php"; - -/** - * @see Zend_Loader - */ -#require_once "Zend/Loader.php"; - -/** - * Configuration Provider - * - * @category Zend - * @package Zend_Tool - * @package Framework - * @uses Zend_Tool_Framework_Provider_Abstract - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ -class Zend_Tool_Framework_System_Provider_Config extends Zend_Tool_Framework_Provider_Abstract -{ - /** - * @var array - */ - protected $_levelCompleted = array(); - - /** - * array of specialties handled by this provider - * - * @var array - */ - protected $_specialties = array('Manifest', 'Provider'); - - /** - * @param string $type - */ - public function create() - { - /* @var $userConfig Zend_Tool_Framework_Client_Config */ - $userConfig = $this->_registry->getConfig(); - - $resp = $this->_registry->getResponse(); - if ($userConfig->exists()) { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception( - "A configuration already exists, cannot create a new one."); - } - - $homeDirectory = $this->_detectHomeDirectory(); - - $writer = new Zend_Config_Writer_Ini(); - $writer->setRenderWithoutSections(); - $filename = $homeDirectory."/.zf.ini"; - - $config = array( - 'php' => array( - 'include_path' => get_include_path(), - ), - ); - $writer->write($filename, new Zend_Config($config)); - - $resp = $this->_registry->getResponse(); - $resp->appendContent("Successfully written Zend Tool config."); - $resp->appendContent("It is located at: ".$filename); - } - - /** - * @return string - */ - protected function _detectHomeDirectory() - { - $envVars = array("ZF_HOME", "HOME", "HOMEPATH"); - foreach($envVars AS $env) { - $homeDirectory = getenv($env); - if ($homeDirectory != false && file_exists($homeDirectory)) { - return $homeDirectory; - } - } - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception("Cannot detect user home directory, set ZF_HOME enviroment variable."); - } - - /** - * Show Zend Tool User Configuration - * - * @return void - */ - public function show() - { - $userConfig = $this->_loadUserConfigIfExists(); - $configArray = $userConfig->getConfigInstance()->toArray(); - - $resp = $this->_registry->getResponse(); - - $i = 0; - $tree = ""; - foreach($configArray AS $k => $v) { - $i++; - $tree .= $this->_printTree($k, $v, 1, count($configArray)==$i); - } - $resp->appendContent("User Configuration: ".$userConfig->getConfigFilepath(), array("color" => "green")); - $resp->appendContent($tree, array("indention" => 2)); - } - - /** - * - * @param string $key - * @param string $value - * @param int $level - * @return string - */ - protected function _printTree($key, $value, $level=1, $isLast=false) - { - $this->_levelCompleted[$level] = false; - - $prefix = ""; - for ($i = 1; $i < $level; $i++) { - if ($this->_levelCompleted[$i] == true) { - $prefix .= " "; - } else { - $prefix .= "| "; - } - } - if ($isLast) { - $pointer = "`-- "; - } else { - $pointer = "|-- "; - } - - $tree = ""; - if (is_array($value)) { - $tree .= $prefix.$pointer.$key.PHP_EOL; - - if ($isLast == true) { - $this->_levelCompleted[$level] = true; - } - - $i = 0; - foreach ($value as $k => $v) { - $i++; - $tree .= $this->_printTree($k, $v, $level+1, (count($value)==$i)); - } - } else { - $tree .= $prefix.$pointer.$key.": ".trim($value).PHP_EOL; - } - - return $tree; - } - - public function enable() - { - $resp = $this->_registry->getResponse(); - $resp->appendContent('Use either "zf enable config.provider" or "zf enable config.manifest".'); - } - - public function disable() - { - $resp = $this->_registry->getResponse(); - $resp->appendContent('Use either "zf disable config.provider" or "zf disable config.manifest".'); - } - - /** - * @param string $className - */ - public function enableProvider($className) - { - Zend_Loader::loadClass($className); - $reflClass = new ReflectionClass($className); - if (!in_array("Zend_Tool_Framework_Provider_Interface", $reflClass->getInterfaceNames())) { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception("Given class is not a provider"); - } - $this->_doEnable($className); - } - - protected function _doEnable($className) - { - - $userConfig = $this->_loadUserConfigIfExists(); - - if (!isset($userConfig->basicloader)) { - $userConfig->basicloader = array(); - } - if (!isset($userConfig->basicloader->classes)) { - $userConfig->basicloader->classes = array(); - } - - $providerClasses = $userConfig->basicloader->classes->toArray(); - if (!in_array($className, $providerClasses)) { - if (count($providerClasses)) { - $pos = max(array_keys($providerClasses))+1; - } else { - $pos = 0; - } - $userConfig->basicloader->classes->$pos = $className; - - if ($userConfig->save()) { - $this->_registry->getResponse()->appendContent( - "Provider/Manifest '".$className."' was enabled for usage with Zend Tool.", - array("color" => "green", "aligncenter" => true) - ); - } else { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception( - "Could not write user configuration to persistence." - ); - } - } else { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception( - "Provider/Manifest '".$className."' is already enabled." - ); - } - } - - /** - * @param string $className - */ - public function enableManifest($className) - { - Zend_Loader::loadClass($className); - $reflClass = new ReflectionClass($className); - if (!in_array("Zend_Tool_Framework_Manifest_Interface", $reflClass->getInterfaceNames())) { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception("Given class is not a manifest."); - } - $this->_doEnable($className); - } - - /** - * @param string $className - */ - public function disableManifest($className) - { - $this->disableProvider($className); - } - - /** - * @param string $className - */ - public function disableProvider($className) - { - $userConfig = $this->_loadUserConfigIfExists(); - - if (!isset($userConfig->basicloader)) { - $userConfig->basicloader = array(); - } - if (!isset($userConfig->basicloader->classes)) { - $userConfig->basicloader->classes = array(); - } - - $providerClasses = $userConfig->basicloader->classes->toArray(); - if (($key = array_search($className, $providerClasses)) !== false) { - unset($userConfig->basicloader->classes->$key); - - if ($userConfig->save()) { - $this->_registry->getResponse()->appendContent( - "Provider/Manifest '".$className."' was disabled.", - array("color" => "green", "aligncenter" => true) - ); - } else { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception( - "Could not write user configuration to persistence." - ); - } - } else { - #require_once "Zend/Tool/Framework/Exception.php"; - throw new Zend_Tool_Framework_Exception( - "Provider/Manifest '".$className."' is not enabled." - ); - } - } - - /** - * @return Zend_Tool_Framework_Client_Config - */ - protected function _loadUserConfigIfExists() - { - /* @var $userConfig Zend_Tool_Framework_Client_Config */ - $userConfig = $this->_registry->getConfig(); - - $resp = $this->_registry->getResponse(); - if (!$userConfig->exists()) { - $resp->appendContent("User has no config file.", array("aligncenter" => true, "color" => array('hiWhite', 'bgRed'))); - } - - return $userConfig; - } -} diff --git a/lib/Zend/Tool/Framework/System/Provider/Manifest.php b/lib/Zend/Tool/Framework/System/Provider/Manifest.php deleted file mode 100644 index 9bed8f5ca2d..00000000000 --- a/lib/Zend/Tool/Framework/System/Provider/Manifest.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Framework_Registry_EnabledInterface - */ -#require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; - -/** - * @see Zend_Tool_Framework_Provider_Interface - */ -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Provider_Manifest - implements Zend_Tool_Framework_Provider_Interface, Zend_Tool_Framework_Registry_EnabledInterface -{ - - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - } - - public function getName() - { - return 'Manifest'; - } - - public function show() - { - - $manifestRepository = $this->_registry->getManifestRepository(); - $response = $this->_registry->getResponse(); - - $metadataTree = array(); - - $longestAttrNameLen = 50; - - foreach ($manifestRepository as $metadata) { - - $metadataType = $metadata->getType(); - $metadataName = $metadata->getName(); - $metadataAttrs = $metadata->getAttributes('attributesParent'); - - if (!$metadataAttrs) { - $metadataAttrs = '(None)'; - } else { - $metadataAttrs = urldecode(http_build_query($metadataAttrs, null, ', ')); - } - - if (!array_key_exists($metadataType, $metadataTree)) { - $metadataTree[$metadataType] = array(); - } - - if (!array_key_exists($metadataName, $metadataTree[$metadataType])) { - $metadataTree[$metadataType][$metadataName] = array(); - } - - if (!array_key_exists($metadataAttrs, $metadataTree[$metadataType][$metadataName])) { - $metadataTree[$metadataType][$metadataName][$metadataAttrs] = array(); - } - - $longestAttrNameLen = (strlen($metadataAttrs) > $longestAttrNameLen) ? strlen($metadataAttrs) : $longestAttrNameLen; - - $metadataValue = $metadata->getValue(); - if (is_array($metadataValue) && count($metadataValue) > 0) { - $metadataValue = urldecode(http_build_query($metadataValue, null, ', ')); - } elseif (is_array($metadataValue)) { - $metadataValue = '(empty array)'; - } - - $metadataTree[$metadataType][$metadataName][$metadataAttrs][] = $metadataValue; - } - - foreach ($metadataTree as $metadataType => $metadatasByName) { - $response->appendContent($metadataType); - foreach ($metadatasByName as $metadataName => $metadatasByAttributes) { - $response->appendContent(" " . $metadataName); - foreach ($metadatasByAttributes as $metadataAttributeName => $metadataValues) { - foreach ($metadataValues as $metadataValue) { - $string = sprintf(" %-{$longestAttrNameLen}.{$longestAttrNameLen}s : ", $metadataAttributeName) - . $metadataValue; - $response->appendContent($string); - } - } - } - } - - } -} diff --git a/lib/Zend/Tool/Framework/System/Provider/Phpinfo.php b/lib/Zend/Tool/Framework/System/Provider/Phpinfo.php deleted file mode 100644 index b74e84fcdbb..00000000000 --- a/lib/Zend/Tool/Framework/System/Provider/Phpinfo.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Provider_Phpinfo implements Zend_Tool_Framework_Provider_Interface -{ - - public function showAction() - { - phpinfo(); - } - -} diff --git a/lib/Zend/Tool/Framework/System/Provider/Version.php b/lib/Zend/Tool/Framework/System/Provider/Version.php deleted file mode 100644 index 9eb2ce65ecd..00000000000 --- a/lib/Zend/Tool/Framework/System/Provider/Version.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Framework/Registry.php'; -#require_once 'Zend/Tool/Framework/Provider/Interface.php'; -#require_once 'Zend/Version.php'; - -/** - * Version Provider - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Framework_System_Provider_Version - implements Zend_Tool_Framework_Provider_Interface, Zend_Tool_Framework_Registry_EnabledInterface -{ - - /** - * @var Zend_Tool_Framework_Registry_Interface - */ - protected $_registry = null; - - const MODE_MAJOR = 'major'; - const MODE_MINOR = 'minor'; - const MODE_MINI = 'mini'; - - protected $_specialties = array('MajorPart', 'MinorPart', 'MiniPart'); - - public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * Show Action - * - * @param string $mode The mode switch can be one of: major, minor, or mini (default) - * @param bool $nameIncluded - */ - public function show($mode = self::MODE_MINI, $nameIncluded = true) - { - - $versionInfo = $this->_splitVersion(); - - switch($mode) { - case self::MODE_MINOR: - unset($versionInfo['mini']); - break; - case self::MODE_MAJOR: - unset($versionInfo['mini'], $versionInfo['minor']); - break; - } - - $output = implode('.', $versionInfo); - - if ($nameIncluded) { - $output = 'Zend Framework Version: ' . $output; - } - - $this->_registry->response->appendContent($output); - } - - public function showMajorPart($nameIncluded = true) - { - $versionNumbers = $this->_splitVersion(); - $output = (($nameIncluded == true) ? 'ZF Major Version: ' : null) . $versionNumbers['major']; - $this->_registry->response->appendContent($output); - } - - public function showMinorPart($nameIncluded = true) - { - $versionNumbers = $this->_splitVersion(); - $output = (($nameIncluded == true) ? 'ZF Minor Version: ' : null) . $versionNumbers['minor']; - $this->_registry->response->appendContent($output); - } - - public function showMiniPart($nameIncluded = true) - { - $versionNumbers = $this->_splitVersion(); - $output = (($nameIncluded == true) ? 'ZF Mini Version: ' : null) . $versionNumbers['mini']; - $this->_registry->response->appendContent($output); - } - - protected function _splitVersion() - { - list($major, $minor, $mini) = explode('.', Zend_Version::VERSION); - return array('major' => $major, 'minor' => $minor, 'mini' => $mini); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Content/Engine.php b/lib/Zend/Tool/Project/Context/Content/Engine.php deleted file mode 100644 index 849e79f82aa..00000000000 --- a/lib/Zend/Tool/Project/Context/Content/Engine.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Content_Engine_CodeGenerator - */ -#require_once 'Zend/Tool/Project/Context/Content/Engine/CodeGenerator.php'; - -/** - * @see Zend_Tool_Project_Context_Content_Engine_Phtml - */ -#require_once 'Zend/Tool/Project/Context/Content/Engine/Phtml.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Content_Engine -{ - /** - * @var Zend_Tool_Framework_Client_Storage - */ - protected $_storage = null; - - /** - * @var string - */ - protected $_keyInStorage = 'project/content'; - - /** - * @var array - */ - protected $_engines = array(); - - /** - * __construct() - * - * @param Zend_Tool_Framework_Client_Storage $storage - */ - public function __construct(Zend_Tool_Framework_Client_Storage $storage) - { - $this->_storage = $storage; - $this->_engines = array( - new Zend_Tool_Project_Context_Content_Engine_CodeGenerator($storage, $this->_keyInStorage), - new Zend_Tool_Project_Context_Content_Engine_Phtml($storage, $this->_keyInStorage), - ); - } - - /** - * getContent() - * - * @param Zend_Tool_Project_Context_Interface $context - * @param string $methodName - * @param mixed $parameters - * @return string - */ - public function getContent(Zend_Tool_Project_Context_Interface $context, $methodName, $parameters) - { - $content = null; - - foreach ($this->_engines as $engine) { - if ($engine->hasContent($context, $methodName, $parameters)) { - $content = $engine->getContent($context, $methodName, $parameters); - - if ($content != null) { - break; - } - - } - - } - - if ($content == null) { - return false; - } - - return $content; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Content/Engine/CodeGenerator.php b/lib/Zend/Tool/Project/Context/Content/Engine/CodeGenerator.php deleted file mode 100644 index b29346782ad..00000000000 --- a/lib/Zend/Tool/Project/Context/Content/Engine/CodeGenerator.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Content_Engine_CodeGenerator -{ - /** - * @var Zend_Tool_Framework_Client_Storage - */ - protected $_storage = null; - - /** - * @var string - */ - protected $_contentPrefix = null; - - /** - * __construct() - * - * @param Zend_Tool_Framework_Client_Storage $storage - * @param string $contentPrefix - */ - public function __construct(Zend_Tool_Framework_Client_Storage $storage, $contentPrefix) - { - $this->_storage = $storage; - $this->_contentPrefix = $contentPrefix; - } - - /** - * hasContent() - * - * @param Zend_Tool_Project_Context_Interface $context - * @param string $method - * @return string - */ - public function hasContent(Zend_Tool_Project_Context_Interface $context, $method) - { - return $this->_storage->has($this->_contentPrefix . '/' . $context->getName() . '/' . $method . '.php'); - } - - /** - * getContent() - * - * @param Zend_Tool_Project_Context_Interface $context - * @param string $method - * @param mixed $parameters - * @return string - */ - public function getContent(Zend_Tool_Project_Context_Interface $context, $method, $parameters) - { - $streamUri = $this->_storage->getStreamUri($this->_contentPrefix . '/' . $context->getName() . '/' . $method . '.php'); - - if (method_exists($context, 'getCodeGenerator')) { - $codeGenerator = $context->getCodeGenerator(); - } else { - $codeGenerator = new Zend_CodeGenerator_Php_File(); - } - - $codeGenerator = include $streamUri; - - if (!$codeGenerator instanceof Zend_CodeGenerator_Abstract) { - throw new Zend_Tool_Project_Exception('Custom file at ' . $streamUri . ' did not return the $codeGenerator object.'); - } - - return $codeGenerator->generate(); - } - - -} diff --git a/lib/Zend/Tool/Project/Context/Content/Engine/Phtml.php b/lib/Zend/Tool/Project/Context/Content/Engine/Phtml.php deleted file mode 100644 index 7a7cbef0a21..00000000000 --- a/lib/Zend/Tool/Project/Context/Content/Engine/Phtml.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Content_Engine_Phtml -{ - - /** - * @var Zend_Tool_Framework_Client_Storage - */ - protected $_storage = null; - - /** - * @var string - */ - protected $_contentPrefix = null; - - /** - * __construct() - * - * @param Zend_Tool_Framework_Client_Storage $storage - * @param string $contentPrefix - */ - public function __construct(Zend_Tool_Framework_Client_Storage $storage, $contentPrefix) - { - $this->_storage = $storage; - $this->_contentPrefix = $contentPrefix; - } - - /** - * hasContext() - * - * @param Zend_Tool_Project_Context_Interface $context - * @param string $method - * @return string - */ - public function hasContent(Zend_Tool_Project_Context_Interface $context, $method) - { - return $this->_storage->has($this->_contentPrefix . '/' . $context . '/' . $method . '.phtml'); - } - - /** - * getContent() - * - * @param Zend_Tool_Project_Context_Interface $context - * @param string $method - * @param mixed $parameters - */ - public function getContent(Zend_Tool_Project_Context_Interface $context, $method, $parameters) - { - $streamUri = $this->_storage->getStreamUri($this->_contentPrefix . '/' . $context->getName() . '/' . $method . '.phtml'); - - ob_start(); - include $streamUri; - $content = ob_get_clean(); - - return $content; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Exception.php b/lib/Zend/Tool/Project/Context/Exception.php deleted file mode 100644 index 373722b5907..00000000000 --- a/lib/Zend/Tool/Project/Context/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Project/Exception.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Exception extends Zend_Tool_Project_Exception -{ - -} diff --git a/lib/Zend/Tool/Project/Context/Filesystem/Abstract.php b/lib/Zend/Tool/Project/Context/Filesystem/Abstract.php deleted file mode 100644 index cb11c6da712..00000000000 --- a/lib/Zend/Tool/Project/Context/Filesystem/Abstract.php +++ /dev/null @@ -1,165 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Interface - */ -#require_once 'Zend/Tool/Project/Context/Interface.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tool_Project_Context_Filesystem_Abstract implements Zend_Tool_Project_Context_Interface -{ - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_resource = null; - - /** - * @var string - */ - protected $_baseDirectory = null; - - /** - * @var string - */ - protected $_filesystemName = null; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Filesystem_Abstract - */ - public function init() - { - $parentBaseDirectory = $this->_resource->getParentResource()->getContext()->getPath(); - $this->_baseDirectory = $parentBaseDirectory; - return $this; - } - - /** - * setResource() - * - * @param Zend_Tool_Project_Profile_Resource $resource - * @return Zend_Tool_Project_Context_Filesystem_Abstract - */ - public function setResource(Zend_Tool_Project_Profile_Resource $resource) - { - $this->_resource = $resource; - return $this; - } - - /** - * setBaseDirectory() - * - * @param string $baseDirectory - * @return Zend_Tool_Project_Context_Filesystem_Abstract - */ - public function setBaseDirectory($baseDirectory) - { - $this->_baseDirectory = rtrim(str_replace('\\', '/', $baseDirectory), '/'); - return $this; - } - - /** - * getBaseDirectory() - * - * @return string - */ - public function getBaseDirectory() - { - return $this->_baseDirectory; - } - - /** - * setFilesystemName() - * - * @param string $filesystemName - * @return Zend_Tool_Project_Context_Filesystem_Abstract - */ - public function setFilesystemName($filesystemName) - { - $this->_filesystemName = $filesystemName; - return $this; - } - - /** - * getFilesystemName() - * - * @return string - */ - public function getFilesystemName() - { - return $this->_filesystemName; - } - - /** - * getPath() - * - * @return string - */ - public function getPath() - { - $path = $this->_baseDirectory; - if ($this->_filesystemName) { - $path .= '/' . $this->_filesystemName; - } - return $path; - } - - /** - * exists() - * - * @return bool - */ - public function exists() - { - return file_exists($this->getPath()); - } - - /** - * create() - * - * Create this resource/context - * - */ - abstract public function create(); - - /** - * delete() - * - * Delete this resouce/context - * - */ - abstract public function delete(); - -} diff --git a/lib/Zend/Tool/Project/Context/Filesystem/Directory.php b/lib/Zend/Tool/Project/Context/Filesystem/Directory.php deleted file mode 100644 index aaf188762d9..00000000000 --- a/lib/Zend/Tool/Project/Context/Filesystem/Directory.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Abstract - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Abstract.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Filesystem_Directory extends Zend_Tool_Project_Context_Filesystem_Abstract -{ - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'directory'; - } - - /** - * create() - * - * @return Zend_Tool_Project_Context_Filesystem_Directory; - */ - public function create() - { - // check to ensure the parent exists, if not, call it and create it - if (($parentResource = $this->_resource->getParentResource()) instanceof Zend_Tool_Project_Profile_Resource) { - if ((($parentContext = $parentResource->getContext()) instanceof Zend_Tool_Project_Context_Filesystem_Abstract) - && (!$parentContext->exists())) { - $parentResource->create(); - } - } - - if (!file_exists($this->getPath())) { - mkdir($this->getPath()); - } - - return $this; - } - - /** - * delete() - * - * @return Zend_Tool_Project_Context_Filesystem_Directory - */ - public function delete() - { - $this->_resource->setDeleted(true); - rmdir($this->getPath()); - - return $this; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Filesystem/File.php b/lib/Zend/Tool/Project/Context/Filesystem/File.php deleted file mode 100644 index 129fc64ec58..00000000000 --- a/lib/Zend/Tool/Project/Context/Filesystem/File.php +++ /dev/null @@ -1,174 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Abstract - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Abstract.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Filesystem_File extends Zend_Tool_Project_Context_Filesystem_Abstract -{ - - protected $_fileOnlyContext = null; - - protected $_filesystemName = null; - - protected $_content = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'file'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Filesystem_File - */ - public function init() - { - if ($this->_resource->hasAttribute('filesystemName')) { - $this->_filesystemName = $this->_resource->getAttribute('filesystemName'); - } - - // check to see if this file is - if ($this->getName() == 'file') { - $this->_initFileOnlyContext(); - } - - // @potential-todo check to ensure that this 'file' resource has no children - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - $returnAttrs = array(); - if ($this->_filesystemName !== null) { - $returnAttrs['filesystemName'] = $this->_filesystemName; - } - return $returnAttrs; - } - - /** - * setResource() - * - * @param unknown_type $resource - */ - public function setResource(Zend_Tool_Project_Profile_Resource $resource) - { - $this->_resource = $resource; - $this->_resource->setAppendable(false); - return $this; - } - - /** - * getResource() - * - * @return Zend_Tool_Project_Profile_Resource - */ - public function getResource() - { - return $this->_resource; - } - - /** - * create() - * - * @return Zend_Tool_Project_Context_Filesystem_File - */ - public function create() - { - // check to ensure the parent exists, if not, call it and create it - if (($parentResource = $this->_resource->getParentResource()) instanceof Zend_Tool_Project_Profile_Resource) { - if ((($parentContext = $parentResource->getContext()) instanceof Zend_Tool_Project_Context_Filesystem_Abstract) - && (!$parentContext->exists())) { - $parentResource->create(); - } - } - - - if (file_exists($this->getPath())) { - // @todo propt user to determine if its ok to overwrite file - } - - file_put_contents($this->getPath(), $this->getContents()); - return $this; - } - - /** - * delete() - * - * @return Zend_Tool_Project_Context_Filesystem_File - */ - public function delete() - { - unlink($this->getPath()); - $this->_resource->setDeleted(true); - return $this; - } - - /** - * getContents() - * - * @return null - */ - public function getContents() - { - return $this->_content; - } - - protected function _initFileOnlyContext() - { - if ($this->_resource->hasAttribute('defaultContentCallback')) { - $contentFunc = $this->_resource->getAttribute('defaultContentCallback'); - if (is_callable($contentFunc)) { - $this->_content = call_user_func_array($contentFunc, array($this)); - } - } - if ($this->_filesystemName == null) { - $this->_filesystemName = 'file.txt'; - } - } - -} diff --git a/lib/Zend/Tool/Project/Context/Interface.php b/lib/Zend/Tool/Project/Context/Interface.php deleted file mode 100644 index 6eb2af6f5dd..00000000000 --- a/lib/Zend/Tool/Project/Context/Interface.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Interface for contexts - * - * setResource() is an optional method that if the context supports - * will be set with the resource at construction time - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Project_Context_Interface -{ - - public function getName(); - -} diff --git a/lib/Zend/Tool/Project/Context/Repository.php b/lib/Zend/Tool/Project/Context/Repository.php deleted file mode 100644 index 92d816f630d..00000000000 --- a/lib/Zend/Tool/Project/Context/Repository.php +++ /dev/null @@ -1,189 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -#require_once 'Zend/Tool/Project/Context/System/Interface.php'; -#require_once 'Zend/Tool/Project/Context/System/TopLevelRestrictable.php'; -#require_once 'Zend/Tool/Project/Context/System/NotOverwritable.php'; - -/** - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Repository implements Countable -{ - - protected static $_instance = null; - protected static $_isInitialized = false; - - protected $_shortContextNames = array(); - protected $_contexts = array(); - - /** - * Enter description here... - * - * @return Zend_Tool_Project_Context_Repository - */ - public static function getInstance() - { - if (self::$_instance == null) { - self::$_instance = new self(); - } - - return self::$_instance; - } - - public static function resetInstance() - { - self::$_instance = null; - self::$_isInitialized = false; - } - - protected function __construct() - { - if (self::$_isInitialized == false) { - $this->addContextClass('Zend_Tool_Project_Context_System_ProjectDirectory') - ->addContextClass('Zend_Tool_Project_Context_System_ProjectProfileFile') - ->addContextClass('Zend_Tool_Project_Context_System_ProjectProvidersDirectory'); - self::$_isInitialized = true; - } - } - - public function addContextsFromDirectory($directory, $prefix) - { - $prefix = trim($prefix, '_') . '_'; - foreach (new DirectoryIterator($directory) as $directoryItem) { - if ($directoryItem->isDot() || (substr($directoryItem->getFilename(), -4) !== '.php')) { - continue; - } - $class = $prefix . substr($directoryItem->getFilename(), 0, -4); - $this->addContextClass($class); - } - } - - - public function addContextClass($contextClass) - { - if (!class_exists($contextClass)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($contextClass); - } - $reflectionContextClass = new ReflectionClass($contextClass); - if ($reflectionContextClass->isInstantiable()) { - $context = new $contextClass(); - return $this->addContext($context); - } - return $this; - } - - /** - * Enter description here... - * - * @param Zend_Tool_Project_Context_Interface $context - * @return Zend_Tool_Project_Context_Repository - */ - public function addContext(Zend_Tool_Project_Context_Interface $context) - { - $isSystem = ($context instanceof Zend_Tool_Project_Context_System_Interface); - $isTopLevel = ($context instanceof Zend_Tool_Project_Context_System_TopLevelRestrictable); - $isOverwritable = !($context instanceof Zend_Tool_Project_Context_System_NotOverwritable); - - $index = (count($this->_contexts)) ? max(array_keys($this->_contexts)) + 1 : 1; - - $normalName = $this->_normalizeName($context->getName()); - - if (isset($this->_shortContextNames[$normalName]) && ($this->_contexts[$this->_shortContextNames[$normalName]]['isOverwritable'] === false) ) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('Context ' . $context->getName() . ' is not overwriteable.'); - } - - $this->_shortContextNames[$normalName] = $index; - $this->_contexts[$index] = array( - 'isTopLevel' => $isTopLevel, - 'isSystem' => $isSystem, - 'isOverwritable' => $isOverwritable, - 'normalName' => $normalName, - 'context' => $context - ); - - return $this; - } - - public function getContext($name) - { - if (!$this->hasContext($name)) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('Context by name ' . $name . ' does not exist in the registry.'); - } - - $name = $this->_normalizeName($name); - return clone $this->_contexts[$this->_shortContextNames[$name]]['context']; - } - - public function hasContext($name) - { - $name = $this->_normalizeName($name); - return (isset($this->_shortContextNames[$name]) ? true : false); - } - - public function isSystemContext($name) - { - if (!$this->hasContext($name)) { - return false; - } - - $name = $this->_normalizeName($name); - $index = $this->_shortContextNames[$name]; - return $this->_contexts[$index]['isSystemContext']; - } - - public function isTopLevelContext($name) - { - if (!$this->hasContext($name)) { - return false; - } - $name = $this->_normalizeName($name); - $index = $this->_shortContextNames[$name]; - return $this->_contexts[$index]['isTopLevel']; - } - - public function isOverwritableContext($name) - { - if (!$this->hasContext($name)) { - return false; - } - $name = $this->_normalizeName($name); - $index = $this->_shortContextNames[$name]; - return $this->_contexts[$index]['isOverwritable']; - } - - public function count() - { - return count($this->_contexts); - } - - protected function _normalizeName($name) - { - return strtolower($name); - } - -} diff --git a/lib/Zend/Tool/Project/Context/System/Interface.php b/lib/Zend/Tool/Project/Context/System/Interface.php deleted file mode 100644 index f79faa973e7..00000000000 --- a/lib/Zend/Tool/Project/Context/System/Interface.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Project_Context_System_Interface -{ - -} diff --git a/lib/Zend/Tool/Project/Context/System/NotOverwritable.php b/lib/Zend/Tool/Project/Context/System/NotOverwritable.php deleted file mode 100644 index 19f7e89d4c6..00000000000 --- a/lib/Zend/Tool/Project/Context/System/NotOverwritable.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Project_Context_System_NotOverwritable -{ - -} diff --git a/lib/Zend/Tool/Project/Context/System/ProjectDirectory.php b/lib/Zend/Tool/Project/Context/System/ProjectDirectory.php deleted file mode 100644 index 5be8a2ceead..00000000000 --- a/lib/Zend/Tool/Project/Context/System/ProjectDirectory.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * @see Zend_Tool_Project_Context_System_Interface - */ -#require_once 'Zend/Tool/Project/Context/System/Interface.php'; - -/** - * @see Zend_Tool_Project_Context_System_TopLevelRestrictable - */ -#require_once 'Zend/Tool/Project/Context/System/TopLevelRestrictable.php'; - -/** - * @see Zend_Tool_Project_Context_System_NotOverwritable - */ -#require_once 'Zend/Tool/Project/Context/System/NotOverwritable.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_System_ProjectDirectory - extends Zend_Tool_Project_Context_Filesystem_Directory - implements Zend_Tool_Project_Context_System_Interface, - Zend_Tool_Project_Context_System_NotOverwritable, - Zend_Tool_Project_Context_System_TopLevelRestrictable -{ - - /** - * @var string - */ - protected $_filesystemName = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ProjectDirectory'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_System_ProjectDirectory - */ - public function init() - { - // get base path from attributes (would be in path attribute) - $projectDirectory = $this->_resource->getAttribute('path'); - - // if not, get from profile - if ($projectDirectory == null) { - $projectDirectory = $this->_resource->getProfile()->getAttribute('projectDirectory'); - } - - // if not, exception. - if ($projectDirectory == null) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('projectDirectory cannot find the directory for this project.'); - } - - $this->_baseDirectory = rtrim($projectDirectory, '\\/'); - return $this; - } - - /** - * create() - * - * @return Zend_Tool_Project_Context_System_ProjectDirectory - */ - public function create() - { - if (file_exists($this->getPath())) { - /* - foreach (new DirectoryIterator($this->getPath()) as $item) { - if (!$item->isDot()) { - if ($registry->getClient()->isInteractive()) { - // @todo prompt for override - } else { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('This directory is not empty, project creation aborted.'); - } - break; - } - } - */ - } - - parent::create(); - return $this; - } - -} diff --git a/lib/Zend/Tool/Project/Context/System/ProjectProfileFile.php b/lib/Zend/Tool/Project/Context/System/ProjectProfileFile.php deleted file mode 100644 index 90c1b7b1bfd..00000000000 --- a/lib/Zend/Tool/Project/Context/System/ProjectProfileFile.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * @see Zend_Tool_Project_Context_System_Interface - */ -#require_once 'Zend/Tool/Project/Context/System/Interface.php'; - -/** - * @see Zend_Tool_Project_Context_System_NotOverwritable - */ -#require_once 'Zend/Tool/Project/Context/System/NotOverwritable.php'; - -/** - * @see Zend_Tool_Project_Profile_FileParser_Xml - */ -#require_once 'Zend/Tool/Project/Profile/FileParser/Xml.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_System_ProjectProfileFile - extends Zend_Tool_Project_Context_Filesystem_File - implements Zend_Tool_Project_Context_System_Interface, - Zend_Tool_Project_Context_System_NotOverwritable -{ - - /** - * @var string - */ - protected $_filesystemName = '.zfproject.xml'; - - /** - * @var Zend_Tool_Project_Profile - */ - protected $_profile = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ProjectProfileFile'; - } - - /** - * setProfile() - * - * @param Zend_Tool_Project_Profile $profile - * @return Zend_Tool_Project_Context_System_ProjectProfileFile - */ - public function setProfile($profile) - { - $this->_profile = $profile; - return $this; - } - - /** - * save() - * - * Proxy to create - * - * @return Zend_Tool_Project_Context_System_ProjectProfileFile - */ - public function save() - { - parent::create(); - return $this; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $parser = new Zend_Tool_Project_Profile_FileParser_Xml(); - $profile = $this->_resource->getProfile(); - $xml = $parser->serialize($profile); - return $xml; - } - -} diff --git a/lib/Zend/Tool/Project/Context/System/ProjectProvidersDirectory.php b/lib/Zend/Tool/Project/Context/System/ProjectProvidersDirectory.php deleted file mode 100644 index e1126bc09e7..00000000000 --- a/lib/Zend/Tool/Project/Context/System/ProjectProvidersDirectory.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * @see Zend_Tool_Project_Context_System_Interface - */ -#require_once 'Zend/Tool/Project/Context/System/Interface.php'; - -/** - * @see Zend_Tool_Project_Context_System_NotOverwritable - */ -#require_once 'Zend/Tool/Project/Context/System/NotOverwritable.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_System_ProjectProvidersDirectory - extends Zend_Tool_Project_Context_Filesystem_Directory - implements Zend_Tool_Project_Context_System_Interface, - Zend_Tool_Project_Context_System_NotOverwritable -{ - - /** - * @var string - */ - protected $_filesystemName = 'providers'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ProjectProvidersDirectory'; - } - - public function loadProviders(Zend_Tool_Framework_Registry_Interface $registry) - { - if (file_exists($this->getPath())) { - - $providerRepository = $registry->getProviderRepository(); - - foreach (new DirectoryIterator($this->getPath()) as $item) { - if ($item->isFile() && (($suffixStart = strpos($item->getFilename(), 'Provider.php')) !== false)) { - $className = substr($item->getFilename(), 0, $suffixStart+8); - // $loadableFiles[$className] = $item->getPathname(); - include_once $item->getPathname(); - $providerRepository->addProvider(new $className()); - } - } - } - } - -} diff --git a/lib/Zend/Tool/Project/Context/System/TopLevelRestrictable.php b/lib/Zend/Tool/Project/Context/System/TopLevelRestrictable.php deleted file mode 100644 index 5680bb25397..00000000000 --- a/lib/Zend/Tool/Project/Context/System/TopLevelRestrictable.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Tool_Project_Context_System_TopLevelRestrictable -{ - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/AbstractClassFile.php b/lib/Zend/Tool/Project/Context/Zf/AbstractClassFile.php deleted file mode 100644 index f0432c5658e..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/AbstractClassFile.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Tool_Project_Context_Zf_AbstractClassFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * getFullClassName() - * - * @param string $localClassName - * @param string $classContextName - */ - public function getFullClassName($localClassName, $classContextName = null) - { - - // find the ApplicationDirectory OR ModuleDirectory - $currentResource = $this->_resource; - do { - $resourceName = $currentResource->getName(); - if ($resourceName == 'ApplicationDirectory' || $resourceName == 'ModuleDirectory') { - $containingResource = $currentResource; - break; - } - } while ($currentResource instanceof Zend_Tool_Project_Profile_Resource - && $currentResource = $currentResource->getParentResource()); - - $fullClassName = ''; - - // go find the proper prefix - if (isset($containingResource)) { - if ($containingResource->getName() == 'ApplicationDirectory') { - $prefix = $containingResource->getAttribute('classNamePrefix'); - $fullClassName = $prefix; - } elseif ($containingResource->getName() == 'ModuleDirectory') { - $filter = new Zend_Filter_Word_DashToCamelCase(); - $prefix = $filter->filter(ucfirst($containingResource->getAttribute('moduleName'))) . '_'; - $fullClassName = $prefix; - } - } - - if ($classContextName) { - $fullClassName .= rtrim($classContextName, '_') . '_'; - } - $fullClassName .= $localClassName; - - return $fullClassName; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ActionMethod.php b/lib/Zend/Tool/Project/Context/Zf/ActionMethod.php deleted file mode 100644 index dc77f0f7a6e..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ActionMethod.php +++ /dev/null @@ -1,224 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Interface - */ -#require_once 'Zend/Tool/Project/Context/Interface.php'; - -/** - * @see Zend_Reflection_File - */ -#require_once 'Zend/Reflection/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ActionMethod implements Zend_Tool_Project_Context_Interface -{ - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_resource = null; - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_controllerResource = null; - - /** - * @var string - */ - protected $_controllerPath = ''; - - /** - * @var string - */ - protected $_actionName = null; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function init() - { - $this->_actionName = $this->_resource->getAttribute('actionName'); - - $this->_resource->setAppendable(false); - $this->_controllerResource = $this->_resource->getParentResource(); - if (!$this->_controllerResource->getContext() instanceof Zend_Tool_Project_Context_Zf_ControllerFile) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('ActionMethod must be a sub resource of a ControllerFile'); - } - // make the ControllerFile node appendable so we can tack on the actionMethod. - $this->_resource->getParentResource()->setAppendable(true); - - $this->_controllerPath = $this->_controllerResource->getContext()->getPath(); - - /* - * This code block is now commented, its doing to much for init() - * - if ($this->_controllerPath != '' && self::hasActionMethod($this->_controllerPath, $this->_actionName)) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('An action named ' . $this->_actionName . 'Action already exists in this controller'); - } - */ - - return $this; - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'actionName' => $this->getActionName() - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ActionMethod'; - } - - /** - * setResource() - * - * @param Zend_Tool_Project_Profile_Resource $resource - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function setResource(Zend_Tool_Project_Profile_Resource $resource) - { - $this->_resource = $resource; - return $this; - } - - /** - * setActionName() - * - * @param string $actionName - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function setActionName($actionName) - { - $this->_actionName = $actionName; - return $this; - } - - /** - * getActionName() - * - * @return string - */ - public function getActionName() - { - return $this->_actionName; - } - - /** - * create() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function create() - { - if (self::createActionMethod($this->_controllerPath, $this->_actionName) === false) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception( - 'Could not create action within controller ' . $this->_controllerPath - . ' with action name ' . $this->_actionName - ); - } - return $this; - } - - /** - * delete() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function delete() - { - // @todo do this - return $this; - } - - /** - * createAcionMethod() - * - * @param string $controllerPath - * @param string $actionName - * @param string $body - * @return true - */ - public static function createActionMethod($controllerPath, $actionName, $body = ' // action body') - { - if (!file_exists($controllerPath)) { - return false; - } - - $controllerCodeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($controllerPath, true, true); - $controllerCodeGenFile->getClass()->setMethod(array( - 'name' => $actionName . 'Action', - 'body' => $body - )); - - file_put_contents($controllerPath, $controllerCodeGenFile->generate()); - return true; - } - - /** - * hasActionMethod() - * - * @param string $controllerPath - * @param string $actionName - * @return bool - */ - public static function hasActionMethod($controllerPath, $actionName) - { - if (!file_exists($controllerPath)) { - return false; - } - - $controllerCodeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($controllerPath, true, true); - return $controllerCodeGenFile->getClass()->hasMethod($actionName . 'Action'); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ApisDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ApisDirectory.php deleted file mode 100644 index 83fa5b96403..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ApisDirectory.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ApisDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - /** - * @var string - */ - protected $_filesystemName = 'apis'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ApisDirectory'; - } -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ApplicationConfigFile.php b/lib/Zend/Tool/Project/Context/Zf/ApplicationConfigFile.php deleted file mode 100644 index fb8d209b49c..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ApplicationConfigFile.php +++ /dev/null @@ -1,285 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ApplicationConfigFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'application.ini'; - - /** - * @var string - */ - protected $_content = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ApplicationConfigFile'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ApplicationConfigFile - */ - public function init() - { - $this->_type = $this->_resource->getAttribute('type'); - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - return array('type' => $this->_type); - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - if ($this->_content === null) { - if (file_exists($this->getPath())) { - $this->_content = file_get_contents($this->getPath()); - } else { - $this->_content = $this->_getDefaultContents(); - } - - } - - return $this->_content; - } - - public function getAsZendConfig($section = 'production') - { - return new Zend_Config_Ini($this->getPath(), $section); - } - - /** - * addStringItem() - * - * @param string $key - * @param string $value - * @param string $section - * @param bool $quoteValue - * @return Zend_Tool_Project_Context_Zf_ApplicationConfigFile - */ - public function addStringItem($key, $value, $section = 'production', $quoteValue = true) - { - // null quote value means to auto-detect - if ($quoteValue === null) { - $quoteValue = preg_match('#[\"\']#', $value) ? false : true; - } - - if ($quoteValue == true) { - $value = '"' . $value . '"'; - } - - $contentLines = preg_split('#[\n\r]#', $this->getContents()); - - $newLines = array(); - $insideSection = false; - - foreach ($contentLines as $contentLineIndex => $contentLine) { - - if ($insideSection === false && preg_match('#^\[' . $section . '#', $contentLine)) { - $insideSection = true; - } - - $newLines[] = $contentLine; - if ($insideSection) { - // if its blank, or a section heading - if (isset($contentLines[$contentLineIndex + 1][0]) && $contentLines[$contentLineIndex + 1][0] == '[') { - $newLines[] = $key . ' = ' . $value; - $insideSection = null; - } else if (!isset($contentLines[$contentLineIndex + 1])){ - $newLines[] = $key . ' = ' . $value; - $insideSection = null; - } - } - } - - $this->_content = implode("\n", $newLines); - return $this; - } - - /** - * - * @param array $item - * @param string $section - * @param bool $quoteValue - * @return Zend_Tool_Project_Context_Zf_ApplicationConfigFile - */ - public function addItem($item, $section = 'production', $quoteValue = true) - { - $stringItems = array(); - $stringValues = array(); - $configKeyNames = array(); - - $rii = new RecursiveIteratorIterator( - new RecursiveArrayIterator($item), - RecursiveIteratorIterator::SELF_FIRST - ); - - $lastDepth = 0; - - // loop through array structure recursively to create proper keys - foreach ($rii as $name => $value) { - $lastDepth = $rii->getDepth(); - - if (is_array($value)) { - array_push($configKeyNames, $name); - } else { - $stringItems[] = implode('.', $configKeyNames) . '.' . $name; - $stringValues[] = $value; - } - } - - foreach ($stringItems as $stringItemIndex => $stringItem) { - $this->addStringItem($stringItem, $stringValues[$stringItemIndex], $section, $quoteValue); - } - - return $this; - } - - public function removeStringItem($key, $section = 'production') - { - $contentLines = file($this->getPath()); - - $newLines = array(); - $insideSection = false; - - foreach ($contentLines as $contentLineIndex => $contentLine) { - - if ($insideSection === false && preg_match('#^\[' . $section . '#', $contentLine)) { - $insideSection = true; - } - - if ($insideSection) { - // if its blank, or a section heading - if ((trim($contentLine) == null) || ($contentLines[$contentLineIndex + 1][0] == '[')) { - $insideSection = null; - } - } - - if (!preg_match('#' . $key . '\s?=.*#', $contentLine)) { - $newLines[] = $contentLine; - } - } - - $this->_content = implode('', $newLines); - } - - public function removeItem($item, $section = 'production') - { - $stringItems = array(); - $stringValues = array(); - $configKeyNames = array(); - - $rii = new RecursiveIteratorIterator( - new RecursiveArrayIterator($item), - RecursiveIteratorIterator::SELF_FIRST - ); - - $lastDepth = 0; - - // loop through array structure recursively to create proper keys - foreach ($rii as $name => $value) { - $lastDepth = $rii->getDepth(); - - if (is_array($value)) { - array_push($configKeyNames, $name); - } else { - $stringItems[] = implode('.', $configKeyNames) . '.' . $name; - $stringValues[] = $value; - } - } - - foreach ($stringItems as $stringItemIndex => $stringItem) { - $this->removeStringItem($stringItem, $section); - } - - return $this; - } - - protected function _getDefaultContents() - { - - $contents =<<<EOS -[production] -phpSettings.display_startup_errors = 0 -phpSettings.display_errors = 0 -includePaths.library = APPLICATION_PATH "/../library" -bootstrap.path = APPLICATION_PATH "/Bootstrap.php" -bootstrap.class = "Bootstrap" -appnamespace = "Application" -resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" -resources.frontController.params.displayExceptions = 0 - -[staging : production] - -[testing : production] -phpSettings.display_startup_errors = 1 -phpSettings.display_errors = 1 - -[development : production] -phpSettings.display_startup_errors = 1 -phpSettings.display_errors = 1 -resources.frontController.params.displayExceptions = 1 - -EOS; - - return $contents; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ApplicationDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ApplicationDirectory.php deleted file mode 100644 index 2a9ce5b5e94..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ApplicationDirectory.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ApplicationDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - protected $_filesystemName = 'application'; - - protected $_classNamePrefix = 'Application_'; - - public function init() - { - if ($this->_resource->hasAttribute('classNamePrefix')) { - $this->_classNamePrefix = $this->_resource->getAttribute('classNamePrefix'); - } - parent::init(); - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'classNamePrefix' => $this->getClassNamePrefix() - ); - } - - public function getName() - { - return 'ApplicationDirectory'; - } - - public function setClassNamePrefix($classNamePrefix) - { - $this->_classNamePrefix = $classNamePrefix; - } - - public function getClassNamePrefix() - { - return $this->_classNamePrefix; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/BootstrapFile.php b/lib/Zend/Tool/Project/Context/Zf/BootstrapFile.php deleted file mode 100644 index e815c9deb19..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/BootstrapFile.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_BootstrapFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'Bootstrap.php'; - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_applicationConfigFile = null; - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_applicationDirectory = null; - - /** - * @var Zend_Application - */ - protected $_applicationInstance = null; - - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'BootstrapFile'; - } - - public function init() - { - parent::init(); - - $this->_applicationConfigFile = $this->_resource->getProfile()->search('ApplicationConfigFile'); - $this->_applicationDirectory = $this->_resource->getProfile()->search('ApplicationDirectory'); - - if (($this->_applicationConfigFile === false) || ($this->_applicationDirectory === false)) { - throw new Exception('To use the BootstrapFile context, your project requires the use of both the "ApplicationConfigFile" and "ApplicationDirectory" contexts.'); - } - - - } - - /** - * getContents() - * - * @return array - */ - public function getContents() - { - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => 'Bootstrap', - 'extendedClass' => 'Zend_Application_Bootstrap_Bootstrap', - )), - ) - )); - - return $codeGenFile->generate(); - } - - public function getApplicationInstance() - { - if ($this->_applicationInstance == null) { - if ($this->_applicationConfigFile->getContext()->exists()) { - define('APPLICATION_PATH', $this->_applicationDirectory->getPath()); - $applicationOptions = array(); - $applicationOptions['config'] = $this->_applicationConfigFile->getPath(); - - $this->_applicationInstance = new Zend_Application( - 'development', - $applicationOptions - ); - } - } - - return $this->_applicationInstance; - } -} diff --git a/lib/Zend/Tool/Project/Context/Zf/CacheDirectory.php b/lib/Zend/Tool/Project/Context/Zf/CacheDirectory.php deleted file mode 100644 index 369d98abea7..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/CacheDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_CacheDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'cache'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'CacheDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ConfigFile.php b/lib/Zend/Tool/Project/Context/Zf/ConfigFile.php deleted file mode 100644 index 38b0b647390..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ConfigFile.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ConfigFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'bootstrap.php'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ConfigFile'; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - return ''; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ConfigsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ConfigsDirectory.php deleted file mode 100644 index 2068b2a1d34..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ConfigsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ConfigsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'configs'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ConfigsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ControllerFile.php b/lib/Zend/Tool/Project/Context/Zf/ControllerFile.php deleted file mode 100644 index 45bf8518677..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ControllerFile.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ControllerFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_controllerName = 'index'; - - /** - * @var string - */ - protected $_moduleName = null; - - /** - * @var string - */ - protected $_filesystemName = 'controllerName'; - - /** - * init() - * - */ - public function init() - { - $this->_controllerName = $this->_resource->getAttribute('controllerName'); - $this->_moduleName = $this->_resource->getAttribute('moduleName'); - $this->_filesystemName = ucfirst($this->_controllerName) . 'Controller.php'; - parent::init(); - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'controllerName' => $this->getControllerName() - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ControllerFile'; - } - - /** - * getControllerName() - * - * @return string - */ - public function getControllerName() - { - return $this->_controllerName; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $filter = new Zend_Filter_Word_DashToCamelCase(); - - $className = ($this->_moduleName) ? $filter->filter(ucfirst($this->_moduleName)) . '_' : ''; - $className .= ucfirst($this->_controllerName) . 'Controller'; - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'fileName' => $this->getPath(), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Controller_Action', - 'methods' => array( - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'init', - 'body' => '/* Initialize action controller here */', - )) - ) - )) - ) - )); - - - if ($className == 'ErrorController') { - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'fileName' => $this->getPath(), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Controller_Action', - 'methods' => array( - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'errorAction', - 'body' => <<<EOS -\$errors = \$this->_getParam('error_handler'); - -if (!\$errors || !\$errors instanceof ArrayObject) { - \$this->view->message = 'You have reached the error page'; - return; -} - -switch (\$errors->type) { - case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: - case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: - case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: - // 404 error -- controller or action not found - \$this->getResponse()->setHttpResponseCode(404); - \$priority = Zend_Log::NOTICE; - \$this->view->message = 'Page not found'; - break; - default: - // application error - \$this->getResponse()->setHttpResponseCode(500); - \$priority = Zend_Log::CRIT; - \$this->view->message = 'Application error'; - break; -} - -// Log exception, if logger available -if (\$log = \$this->getLog()) { - \$log->log(\$this->view->message, \$priority, \$errors->exception); - \$log->log('Request Parameters', \$priority, \$errors->request->getParams()); -} - -// conditionally display exceptions -if (\$this->getInvokeArg('displayExceptions') == true) { - \$this->view->exception = \$errors->exception; -} - -\$this->view->request = \$errors->request; -EOS - )), - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'getLog', - 'body' => <<<EOS -\$bootstrap = \$this->getInvokeArg('bootstrap'); -if (!\$bootstrap->hasResource('Log')) { - return false; -} -\$log = \$bootstrap->getResource('Log'); -return \$log; -EOS - )), - ) - )) - ) - )); - - } - - // store the generator into the registry so that the addAction command can use the same object later - Zend_CodeGenerator_Php_File::registerFileCodeGenerator($codeGenFile); // REQUIRES filename to be set - return $codeGenFile->generate(); - } - - /** - * addAction() - * - * @param string $actionName - */ - public function addAction($actionName) - { - $classCodeGen = $this->getCodeGenerator(); - $classCodeGen->setMethod(array('name' => $actionName . 'Action', 'body' => ' // action body here')); - file_put_contents($this->getPath(), $classCodeGen->generate()); - } - - /** - * getCodeGenerator() - * - * @return Zend_CodeGenerator_Php_Class - */ - public function getCodeGenerator() - { - $codeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($this->getPath()); - $codeGenFileClasses = $codeGenFile->getClasses(); - $class = array_shift($codeGenFileClasses); - return $class; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ControllersDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ControllersDirectory.php deleted file mode 100644 index 99b4adf09ca..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ControllersDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ControllersDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'controllers'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ControllersDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/DataDirectory.php b/lib/Zend/Tool/Project/Context/Zf/DataDirectory.php deleted file mode 100644 index 91b2d19bfaf..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/DataDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_DataDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'data'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'DataDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/DbTableDirectory.php b/lib/Zend/Tool/Project/Context/Zf/DbTableDirectory.php deleted file mode 100644 index a89bd7bad6a..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/DbTableDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_DbTableDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'DbTable'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'DbTableDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/DbTableFile.php b/lib/Zend/Tool/Project/Context/Zf/DbTableFile.php deleted file mode 100644 index 306ae80d3e5..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/DbTableFile.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_DbTableFile extends Zend_Tool_Project_Context_Zf_AbstractClassFile -{ - - protected $_dbTableName = null; - - protected $_actualTableName = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'DbTableFile'; - } - - /** - * init() - * - */ - public function init() - { - $this->_dbTableName = $this->_resource->getAttribute('dbTableName'); - $this->_actualTableName = $this->_resource->getAttribute('actualTableName'); - $this->_filesystemName = ucfirst($this->_dbTableName) . '.php'; - parent::init(); - } - - public function getPersistentAttributes() - { - return array('dbTableName' => $this->_dbTableName); - } - - public function getContents() - { - $className = $this->getFullClassName($this->_dbTableName, 'Model_DbTable'); - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'fileName' => $this->getPath(), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Db_Table_Abstract', - 'properties' => array( - new Zend_CodeGenerator_Php_Property(array( - 'name' => '_name', - 'visibility' => Zend_CodeGenerator_Php_Property::VISIBILITY_PROTECTED, - 'defaultValue' => $this->_actualTableName - )) - ), - - )) - ) - )); - return $codeGenFile->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/DocsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/DocsDirectory.php deleted file mode 100644 index 65f626ddaef..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/DocsDirectory.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: DataDirectory.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_DocsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'docs'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'DocsDirectory'; - } - - public function create(){ - parent::create(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/FormFile.php b/lib/Zend/Tool/Project/Context/Zf/FormFile.php deleted file mode 100644 index b630f28606e..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/FormFile.php +++ /dev/null @@ -1,113 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Zf_AbstractClassFile - */ -#require_once 'Zend/Tool/Project/Context/Zf/AbstractClassFile.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_FormFile extends Zend_Tool_Project_Context_Zf_AbstractClassFile -{ - - /** - * @var string - */ - protected $_formName = 'Base'; - - /** - * @var string - */ - protected $_filesystemName = 'formName'; - - /** - * init() - * - */ - public function init() - { - $this->_formName = $this->_resource->getAttribute('formName'); - $this->_filesystemName = ucfirst($this->_formName) . '.php'; - parent::init(); - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'formName' => $this->getFormName() - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'FormFile'; - } - - public function getFormName() - { - return $this->_formName; - } - - public function getContents() - { - - $className = $this->getFullClassName($this->_formName, 'Form'); - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'fileName' => $this->getPath(), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Form', - 'methods' => array( - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'init', - 'body' => '/* Form Elements & Other Definitions Here ... */', - )) - ) - - )) - ) - )); - return $codeGenFile->generate(); - } -} diff --git a/lib/Zend/Tool/Project/Context/Zf/FormsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/FormsDirectory.php deleted file mode 100644 index 4b02a362093..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/FormsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_FormsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'forms'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'FormsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/HtaccessFile.php b/lib/Zend/Tool/Project/Context/Zf/HtaccessFile.php deleted file mode 100644 index 3714504a96c..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/HtaccessFile.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_HtaccessFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = '.htaccess'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'HtaccessFile'; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $output = <<<EOS - -RewriteEngine On -# The following rule tells Apache that if the requested filename -# exists, simply serve it. -RewriteCond %{REQUEST_FILENAME} -s [OR] -RewriteCond %{REQUEST_FILENAME} -l [OR] -RewriteCond %{REQUEST_FILENAME} -d -RewriteRule ^.*$ - [NC,L] -# The following rewrites all other queries to index.php. The -# condition ensures that if you are using Apache aliases to do -# mass virtual hosting, the base path will be prepended to -# allow proper resolution of the index.php file; it will work -# in non-aliased environments as well, providing a safe, one-size -# fits all solution. -RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ -RewriteRule ^(.*)$ - [E=BASE:%1] -RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L] - -EOS; - return $output; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LayoutScriptFile.php b/lib/Zend/Tool/Project/Context/Zf/LayoutScriptFile.php deleted file mode 100644 index 9e596d3b7c4..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LayoutScriptFile.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LayoutScriptFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'layout.phtml'; - - /** - * @var string - */ - protected $_layoutName = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LayoutScriptFile'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ViewScriptFile - */ - public function init() - { - if ($layoutName = $this->_resource->getAttribute('layoutName')) { - $this->_layoutName = $layoutName; - } else { - throw new Exception('Either a forActionName or scriptName is required.'); - } - - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return unknown - */ - public function getPersistentAttributes() - { - $attributes = array(); - - if ($this->_layoutName) { - $attributes['layoutName'] = $this->_layoutName; - } - - return $attributes; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $contents = <<<EOS -<?php echo \$this->layout()->content; ?> -EOS; - - return $contents; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LayoutScriptsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/LayoutScriptsDirectory.php deleted file mode 100644 index 31fea88a0bd..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LayoutScriptsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LayoutScriptsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'scripts'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LayoutScriptsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LayoutsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/LayoutsDirectory.php deleted file mode 100644 index f3d2429f496..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LayoutsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LayoutsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'layouts'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LayoutsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LibraryDirectory.php b/lib/Zend/Tool/Project/Context/Zf/LibraryDirectory.php deleted file mode 100644 index bb7629f0ec1..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LibraryDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LibraryDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'library'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LibraryDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LocalesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/LocalesDirectory.php deleted file mode 100644 index 1310be7d2ff..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LocalesDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LocalesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'locales'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LocalesDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/LogsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/LogsDirectory.php deleted file mode 100644 index 1f54d72e39f..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/LogsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_LogsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'logs'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'LogsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ModelFile.php b/lib/Zend/Tool/Project/Context/Zf/ModelFile.php deleted file mode 100644 index 7e0b12e0f02..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ModelFile.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * Zend_Tool_Project_Context_Zf_AbstractClassFile - */ -#require_once 'Zend/Tool/Project/Context/Zf/AbstractClassFile.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ModelFile extends Zend_Tool_Project_Context_Zf_AbstractClassFile -{ - - /** - * @var string - */ - protected $_modelName = 'Base'; - - /** - * @var string - */ - protected $_filesystemName = 'modelName'; - - /** - * init() - * - */ - public function init() - { - $this->_modelName = $this->_resource->getAttribute('modelName'); - $this->_filesystemName = ucfirst($this->_modelName) . '.php'; - parent::init(); - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'modelName' => $this->getModelName() - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ModelFile'; - } - - public function getModelName() - { - return $this->_modelName; - } - - public function getContents() - { - - $className = $this->getFullClassName($this->_modelName, 'Model'); - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'fileName' => $this->getPath(), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - )) - ) - )); - return $codeGenFile->generate(); - } - - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ModelsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ModelsDirectory.php deleted file mode 100644 index d813adbc3a6..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ModelsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ModelsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'models'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ModelsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ModuleDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ModuleDirectory.php deleted file mode 100644 index 21aa3dc0d67..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ModuleDirectory.php +++ /dev/null @@ -1,97 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ModuleDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_moduleName = null; - - /** - * @var string - */ - protected $_filesystemName = 'moduleDirectory'; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ControllerFile - */ - public function init() - { - $this->_filesystemName = $this->_moduleName = $this->_resource->getAttribute('moduleName'); - parent::init(); - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ModuleDirectory'; - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'moduleName' => $this->getModuleName() - ); - } - - /** - * getModuleName() - * - * @return string - */ - public function getModuleName() - { - return $this->_moduleName; - } - - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ModulesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ModulesDirectory.php deleted file mode 100644 index 482b1f3c69f..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ModulesDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ModulesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'modules'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'modulesDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ProjectProviderFile.php b/lib/Zend/Tool/Project/Context/Zf/ProjectProviderFile.php deleted file mode 100644 index 5448bcea5d2..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ProjectProviderFile.php +++ /dev/null @@ -1,152 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * @see Zend_CodeGenerator_Php_File - */ -#require_once 'Zend/CodeGenerator/Php/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ProjectProviderFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_projectProviderName = null; - - /** - * @var array - */ - protected $_actionNames = array(); - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ProjectProviderFile - */ - public function init() - { - - $this->_projectProviderName = $this->_resource->getAttribute('projectProviderName'); - $this->_actionNames = $this->_resource->getAttribute('actionNames'); - $this->_filesystemName = ucfirst($this->_projectProviderName) . 'Provider.php'; - - if (strpos($this->_actionNames, ',')) { - $this->_actionNames = explode(',', $this->_actionNames); - } else { - $this->_actionNames = ($this->_actionNames) ? array($this->_actionNames) : array(); - } - - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'projectProviderName' => $this->getProjectProviderName(), - 'actionNames' => implode(',', $this->_actionNames) - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ProjectProviderFile'; - } - - /** - * getProjectProviderName() - * - * @return string - */ - public function getProjectProviderName() - { - return $this->_projectProviderName; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - - $filter = new Zend_Filter_Word_DashToCamelCase(); - - $className = $filter->filter($this->_projectProviderName) . 'Provider'; - - $class = new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Tool_Project_Provider_Abstract' - )); - - $methods = array(); - foreach ($this->_actionNames as $actionName) { - $methods[] = new Zend_CodeGenerator_Php_Method(array( - 'name' => $actionName, - 'body' => ' /** @todo Implementation */' - )); - } - - if ($methods) { - $class->setMethods($methods); - } - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'requiredFiles' => array( - 'Zend/Tool/Project/Provider/Abstract.php', - 'Zend/Tool/Project/Provider/Exception.php' - ), - 'classes' => array($class) - )); - - return $codeGenFile->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/PublicDirectory.php b/lib/Zend/Tool/Project/Context/Zf/PublicDirectory.php deleted file mode 100644 index 0f5b38703d4..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/PublicDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_PublicDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'public'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'PublicDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/PublicImagesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/PublicImagesDirectory.php deleted file mode 100644 index 9f2fafebc82..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/PublicImagesDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_PublicImagesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'images'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'PublicImagesDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/PublicIndexFile.php b/lib/Zend/Tool/Project/Context/Zf/PublicIndexFile.php deleted file mode 100644 index 14419b1a298..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/PublicIndexFile.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_PublicIndexFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'index.php'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'PublicIndexFile'; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $codeGenerator = new Zend_CodeGenerator_Php_File(array( - 'body' => <<<EOS -// Define path to application directory -defined('APPLICATION_PATH') - || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); - -// Define application environment -defined('APPLICATION_ENV') - || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); - -// Ensure library/ is on include_path -set_include_path(implode(PATH_SEPARATOR, array( - realpath(APPLICATION_PATH . '/../library'), - get_include_path(), -))); - -/** Zend_Application */ -#require_once 'Zend/Application.php'; - -// Create application, bootstrap, and run -\$application = new Zend_Application( - APPLICATION_ENV, - APPLICATION_PATH . '/configs/application.ini' -); -\$application->bootstrap() - ->run(); -EOS - )); - return $codeGenerator->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/PublicScriptsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/PublicScriptsDirectory.php deleted file mode 100644 index a4954206344..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/PublicScriptsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_PublicScriptsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'js'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'PublicScriptsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/PublicStylesheetsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/PublicStylesheetsDirectory.php deleted file mode 100644 index 7456d5681e1..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/PublicStylesheetsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_PublicStylesheetsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'styles'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'PublicStylesheetsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/SearchIndexesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/SearchIndexesDirectory.php deleted file mode 100644 index da06fa7bd38..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/SearchIndexesDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_SearchIndexesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'search-indexes'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'SearchIndexesDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ServicesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ServicesDirectory.php deleted file mode 100644 index ef52ea933e8..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ServicesDirectory.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ServicesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - /** - * @var string - */ - protected $_filesystemName = 'services'; - - /** - * Defined by Zend_Tool_Project_Context_Interface - * - * @return string - */ - public function getName() - { - return 'ServicesDirectory'; - } -} diff --git a/lib/Zend/Tool/Project/Context/Zf/SessionsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/SessionsDirectory.php deleted file mode 100644 index 21275e1c594..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/SessionsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_SessionsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'sessions'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'SessionsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TemporaryDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TemporaryDirectory.php deleted file mode 100644 index 7850a308e98..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TemporaryDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TemporaryDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'temp'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TemporaryDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationActionMethod.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationActionMethod.php deleted file mode 100644 index d51f2879fed..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationActionMethod.php +++ /dev/null @@ -1,229 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: ActionMethod.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @see Zend_Tool_Project_Context_Interface - */ -#require_once 'Zend/Tool/Project/Context/Interface.php'; - -/** - * @see Zend_Reflection_File - */ -#require_once 'Zend/Reflection/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationActionMethod implements Zend_Tool_Project_Context_Interface -{ - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_resource = null; - - /** - * @var Zend_Tool_Project_Profile_Resource - */ - protected $_testApplicationControllerResource = null; - - /** - * @var string - */ - protected $_testApplicationControllerPath = ''; - - /** - * @var string - */ - protected $_forActionName = null; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function init() - { - $this->_forActionName = $this->_resource->getAttribute('forActionName'); - - $this->_resource->setAppendable(false); - $this->_testApplicationControllerResource = $this->_resource->getParentResource(); - if (!$this->_testApplicationControllerResource->getContext() instanceof Zend_Tool_Project_Context_Zf_TestApplicationControllerFile) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception('ActionMethod must be a sub resource of a TestApplicationControllerFile'); - } - // make the ControllerFile node appendable so we can tack on the actionMethod. - $this->_resource->getParentResource()->setAppendable(true); - - $this->_testApplicationControllerPath = $this->_testApplicationControllerResource->getContext()->getPath(); - - return $this; - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'forActionName' => $this->getForActionName() - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationActionMethod'; - } - - /** - * setResource() - * - * @param Zend_Tool_Project_Profile_Resource $resource - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function setResource(Zend_Tool_Project_Profile_Resource $resource) - { - $this->_resource = $resource; - return $this; - } - - /** - * getActionName() - * - * @return string - */ - public function getForActionName() - { - return $this->_forActionName; - } - - /** - * create() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function create() - { - $file = $this->_testApplicationControllerPath; - - if (!file_exists($file)) { - #require_once 'Zend/Tool/Project/Context/Exception.php'; - throw new Zend_Tool_Project_Context_Exception( - 'Could not create action within test controller ' . $file - . ' with action name ' . $this->_forActionName - ); - } - - $actionParam = $this->getForActionName(); - $controllerParam = $this->_resource->getParentResource()->getForControllerName(); - //$moduleParam = null;// - - /* @var $controllerDirectoryResource Zend_Tool_Project_Profile_Resource */ - $controllerDirectoryResource = $this->_resource->getParentResource()->getParentResource(); - if ($controllerDirectoryResource->getParentResource()->getName() == 'TestApplicationModuleDirectory') { - $moduleParam = $controllerDirectoryResource->getParentResource()->getForModuleName(); - } else { - $moduleParam = 'default'; - } - - - - if ($actionParam == 'index' && $controllerParam == 'Index' && $moduleParam == 'default') { - $assert = '$this->assertQueryContentContains("div#welcome h3", "This is your project\'s main page");'; - } else { - $assert = <<<EOS -\$this->assertQueryContentContains( - 'div#view-content p', - 'View script for controller <b>' . \$params['controller'] . '</b> and script/action name <b>' . \$params['action'] . '</b>' - ); -EOS; - } - - $codeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($file, true, true); - $codeGenFile->getClass()->setMethod(array( - 'name' => 'test' . ucfirst($actionParam) . 'Action', - 'body' => <<<EOS -\$params = array('action' => '$actionParam', 'controller' => '$controllerParam', 'module' => '$moduleParam'); -\$urlParams = \$this->urlizeOptions(\$params); -\$url = \$this->url(\$urlParams); -\$this->dispatch(\$url); - -// assertions -\$this->assertModule(\$urlParams['module']); -\$this->assertController(\$urlParams['controller']); -\$this->assertAction(\$urlParams['action']); -$assert - -EOS - )); - - file_put_contents($file, $codeGenFile->generate()); - - return $this; - } - - /** - * delete() - * - * @return Zend_Tool_Project_Context_Zf_ActionMethod - */ - public function delete() - { - // @todo do this - return $this; - } - - /** - * hasActionMethod() - * - * @param string $controllerPath - * @param string $actionName - * @return bool - */ - /* - public static function hasActionMethod($controllerPath, $actionName) - { - if (!file_exists($controllerPath)) { - return false; - } - - $controllerCodeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($controllerPath, true, true); - return $controllerCodeGenFile->getClass()->hasMethod('test' . $actionName . 'Action'); - } - */ - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationBootstrapFile.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationBootstrapFile.php deleted file mode 100644 index 24da6fdcc9b..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationBootstrapFile.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationBootstrapFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'bootstrap.php'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationBootstrapFile'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerDirectory.php deleted file mode 100644 index 352727b7a99..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationControllerDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'controllers'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationControllerDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerFile.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerFile.php deleted file mode 100644 index f0eb72e0956..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationControllerFile.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationControllerFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_forControllerName = ''; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationControllerFile'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_TestApplicationControllerFile - */ - public function init() - { - $this->_forControllerName = $this->_resource->getAttribute('forControllerName'); - $this->_filesystemName = ucfirst($this->_forControllerName) . 'ControllerTest.php'; - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return unknown - */ - public function getPersistentAttributes() - { - $attributes = array(); - - if ($this->_forControllerName) { - $attributes['forControllerName'] = $this->getForControllerName(); - } - - return $attributes; - } - - public function getForControllerName() - { - return $this->_forControllerName; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - - $filter = new Zend_Filter_Word_DashToCamelCase(); - - $className = $filter->filter($this->_forControllerName) . 'ControllerTest'; - - /* @var $controllerDirectoryResource Zend_Tool_Project_Profile_Resource */ - $controllerDirectoryResource = $this->_resource->getParentResource(); - if ($controllerDirectoryResource->getParentResource()->getName() == 'TestApplicationModuleDirectory') { - $className = $filter->filter(ucfirst($controllerDirectoryResource->getParentResource()->getForModuleName())) - . '_' . $className; - } - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'Zend_Test_PHPUnit_ControllerTestCase', - 'methods' => array( - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'setUp', - 'body' => <<<EOS -\$this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini'); -parent::setUp(); -EOS - )) - ) - )) - ) - )); - - return $codeGenFile->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationDirectory.php deleted file mode 100644 index f886b04b188..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'application'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationModuleDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationModuleDirectory.php deleted file mode 100644 index 148689c87fa..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationModuleDirectory.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: TestApplicationControllerDirectory.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationModuleDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - - /** - * @var string - */ - protected $_forModuleName = null; - - /** - * @var string - */ - protected $_filesystemName = 'moduleDirectory'; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ControllerFile - */ - public function init() - { - $this->_filesystemName = $this->_forModuleName = $this->_resource->getAttribute('forModuleName'); - parent::init(); - return $this; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationModuleDirectory'; - } - - /** - * getPersistentAttributes - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'forModuleName' => $this->getForModuleName() - ); - } - - /** - * getModuleName() - * - * @return string - */ - public function getForModuleName() - { - return $this->_forModuleName; - } - - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestApplicationModulesDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestApplicationModulesDirectory.php deleted file mode 100644 index 6d907cd0447..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestApplicationModulesDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: TestApplicationControllerDirectory.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestApplicationModulesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'modules'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestApplicationModulesDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestLibraryBootstrapFile.php b/lib/Zend/Tool/Project/Context/Zf/TestLibraryBootstrapFile.php deleted file mode 100644 index ea9c583b7b7..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestLibraryBootstrapFile.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestLibraryBootstrapFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'bootstrap.php'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestLibraryBootstrapFile'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestLibraryDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestLibraryDirectory.php deleted file mode 100644 index 251868470e0..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestLibraryDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestLibraryDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'library'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestLibraryDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestLibraryFile.php b/lib/Zend/Tool/Project/Context/Zf/TestLibraryFile.php deleted file mode 100644 index 1350d0f1f71..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestLibraryFile.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestLibraryFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_forClassName = ''; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestLibraryFile'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_TestLibraryFile - */ - public function init() - { - $this->_forClassName = $this->_resource->getAttribute('forClassName'); - $this->_filesystemName = ucfirst(ltrim(strrchr($this->_forClassName, '_'), '_')) . 'Test.php'; - parent::init(); - return $this; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - - $filter = new Zend_Filter_Word_DashToCamelCase(); - - $className = $filter->filter($this->_forClassName) . 'Test'; - - $codeGenFile = new Zend_CodeGenerator_Php_File(array( - 'requiredFiles' => array( - 'PHPUnit/Framework/TestCase.php' - ), - 'classes' => array( - new Zend_CodeGenerator_Php_Class(array( - 'name' => $className, - 'extendedClass' => 'PHPUnit_Framework_TestCase', - 'methods' => array( - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'setUp', - 'body' => ' /* Setup Routine */' - )), - new Zend_CodeGenerator_Php_Method(array( - 'name' => 'tearDown', - 'body' => ' /* Tear Down Routine */' - )) - ) - )) - ) - )); - - return $codeGenFile->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestLibraryNamespaceDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestLibraryNamespaceDirectory.php deleted file mode 100644 index 5e87e9e5299..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestLibraryNamespaceDirectory.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestLibraryNamespaceDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_namespaceName = ''; - - /** - * @var string - */ - protected $_filesystemName = 'library'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestLibraryNamespaceDirectory'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_TestLibraryNamespaceDirectory - */ - public function init() - { - $this->_namespaceName = $this->_resource->getAttribute('namespaceName'); - $this->_filesystemName = $this->_namespaceName; - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - $attributes = array(); - $attributes['namespaceName'] = $this->_namespaceName; - - return $attributes; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitBootstrapFile.php b/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitBootstrapFile.php deleted file mode 100644 index da953fe8867..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitBootstrapFile.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: TestApplicationBootstrapFile.php 20096 2010-01-06 02:05:09Z bkarwin $ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestPHPUnitBootstrapFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'bootstrap.php'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestPHPUnitBootstrapFile'; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $codeGenerator = new Zend_CodeGenerator_Php_File(array( - 'body' => <<<EOS -// Define path to application directory -defined('APPLICATION_PATH') - || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); - -// Define application environment -defined('APPLICATION_ENV') - || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing')); - -// Ensure library/ is on include_path -set_include_path(implode(PATH_SEPARATOR, array( - realpath(APPLICATION_PATH . '/../library'), - get_include_path(), -))); - -#require_once 'Zend/Loader/Autoloader.php'; -Zend_Loader_Autoloader::getInstance(); - -EOS - )); - return $codeGenerator->generate(); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitConfigFile.php b/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitConfigFile.php deleted file mode 100644 index 48faaa9996d..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestPHPUnitConfigFile.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestPHPUnitConfigFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'phpunit.xml'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestPHPUnitConfigFile'; - } - - public function getContents() - { - return <<<EOS -<phpunit bootstrap="./bootstrap.php"> - <testsuite name="Application Test Suite"> - <directory>./application</directory> - </testsuite> - <testsuite name="Library Test Suite"> - <directory>./library</directory> - </testsuite> - - <filter> - <!-- If Zend Framework is inside your project's library, uncomment this filter --> - <!-- - <whitelist> - <directory suffix=".php">../../library/Zend</directory> - </whitelist> - --> - </filter> -</phpunit> - -EOS; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/TestsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/TestsDirectory.php deleted file mode 100644 index b198268195b..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/TestsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_TestsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'tests'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'TestsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/UploadsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/UploadsDirectory.php deleted file mode 100644 index a6bd06db403..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/UploadsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_UploadsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'uploads'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'UploadsDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ViewControllerScriptsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ViewControllerScriptsDirectory.php deleted file mode 100644 index bcfd98284cc..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ViewControllerScriptsDirectory.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * @see Zend_Filter - */ -#require_once 'Zend/Filter.php'; - -/** - * @see Zend_Filter_Word_CamelCaseToDash - */ -#require_once 'Zend/Filter/Word/CamelCaseToDash.php'; - -/** - * @see Zend_Filter_StringToLower - */ -#require_once 'Zend/Filter/StringToLower.php'; - - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ViewControllerScriptsDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'controllerName'; - - /** - * @var name - */ - protected $_forControllerName = null; - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ViewControllerScriptsDirectory - */ - public function init() - { - $this->_forControllerName = $this->_resource->getAttribute('forControllerName'); - $this->_filesystemName = $this->_convertControllerNameToFilesystemName($this->_forControllerName); - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - return array( - 'forControllerName' => $this->_forControllerName - ); - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ViewControllerScriptsDirectory'; - } - - protected function _convertControllerNameToFilesystemName($controllerName) - { - $filter = new Zend_Filter(); - $filter->addFilter(new Zend_Filter_Word_CamelCaseToDash()) - ->addFilter(new Zend_Filter_StringToLower()); - return $filter->filter($controllerName); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ViewFiltersDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ViewFiltersDirectory.php deleted file mode 100644 index cb49b3b14e7..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ViewFiltersDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ViewFiltersDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'filters'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ViewFiltersDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ViewHelpersDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ViewHelpersDirectory.php deleted file mode 100644 index e63fe96e7f8..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ViewHelpersDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_Directory - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php'; - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ViewHelpersDirectory extends Zend_Tool_Project_Context_Filesystem_Directory -{ - - /** - * @var string - */ - protected $_filesystemName = 'helpers'; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ViewHelpersDirectory'; - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ViewScriptFile.php b/lib/Zend/Tool/Project/Context/Zf/ViewScriptFile.php deleted file mode 100644 index 724702a3442..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ViewScriptFile.php +++ /dev/null @@ -1,247 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Tool - * @subpackage Framework - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id$ - */ - -/** - * @see Zend_Tool_Project_Context_Filesystem_File - */ -#require_once 'Zend/Tool/Project/Context/Filesystem/File.php'; - -/** - * @see Zend_Filter - */ -#require_once 'Zend/Filter.php'; - -/** - * @see Zend_Filter_Word_CamelCaseToDash - */ -#require_once 'Zend/Filter/Word/CamelCaseToDash.php'; - -/** - * @see Zend_Filter_StringToLower - */ -#require_once 'Zend/Filter/StringToLower.php'; - - -/** - * This class is the front most class for utilizing Zend_Tool_Project - * - * A profile is a hierarchical set of resources that keep track of - * items within a specific project. - * - * @category Zend - * @package Zend_Tool - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Tool_Project_Context_Zf_ViewScriptFile extends Zend_Tool_Project_Context_Filesystem_File -{ - - /** - * @var string - */ - protected $_filesystemName = 'view.phtml'; - - /** - * @var string - */ - protected $_forActionName = null; - - /** - * @var string - */ - protected $_scriptName = null; - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ViewScriptFile'; - } - - /** - * init() - * - * @return Zend_Tool_Project_Context_Zf_ViewScriptFile - */ - public function init() - { - if ($forActionName = $this->_resource->getAttribute('forActionName')) { - $this->_forActionName = $forActionName; - $this->_filesystemName = $this->_convertActionNameToFilesystemName($forActionName) . '.phtml'; - } elseif ($scriptName = $this->_resource->getAttribute('scriptName')) { - $this->_scriptName = $scriptName; - $this->_filesystemName = $scriptName . '.phtml'; - } else { - throw new Exception('Either a forActionName or scriptName is required.'); - } - - parent::init(); - return $this; - } - - /** - * getPersistentAttributes() - * - * @return unknown - */ - public function getPersistentAttributes() - { - $attributes = array(); - - if ($this->_forActionName) { - $attributes['forActionName'] = $this->_forActionName; - } - - if ($this->_scriptName) { - $attributes['scriptName'] = $this->_scriptName; - } - - return $attributes; - } - - /** - * getContents() - * - * @return string - */ - public function getContents() - { - $contents = ''; - - $controllerName = $this->_resource->getParentResource()->getAttribute('forControllerName'); - - $viewsDirectoryResource = $this->_resource - ->getParentResource() // view script - ->getParentResource() // view controller dir - ->getParentResource(); // views dir - if ($viewsDirectoryResource->getParentResource()->getName() == 'ModuleDirectory') { - $moduleName = $viewsDirectoryResource->getParentResource()->getModuleName(); - } else { - $moduleName = 'default'; - } - - if ($this->_filesystemName == 'error.phtml') { // should also check that the above directory is forController=error - $contents .= <<<EOS -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Zend Framework Default Application - - -

An error occurred

-

message ?>

- - exception)): ?> - -

Exception information:

-

- Message: exception->getMessage() ?> -

- -

Stack trace:

-
exception->getTraceAsString() ?>
-  
- -

Request Parameters:

-
escape(var_export(\$this->request->getParams(), true)) ?>
-  
- - - - - - -EOS; - } elseif ($this->_forActionName == 'index' && $controllerName == 'Index' && $moduleName == 'default') { - - $contents =<< - a:link, - a:visited - { - color: #0398CA; - } - - span#zf-name - { - color: #91BE3F; - } - - div#welcome - { - color: #FFFFFF; - background-image: url(http://framework.zend.com/images/bkg_header.jpg); - width: 600px; - height: 400px; - border: 2px solid #444444; - overflow: hidden; - text-align: center; - } - - div#more-information - { - background-image: url(http://framework.zend.com/images/bkg_body-bottom.gif); - height: 100%; - } - -
-EOS; - - } else { - $controllerName = $this->_resource->getParentResource()->getAttribute('forControllerName'); - $actionName = $this->_forActionName; - $contents = <<
-
-

View script for controller $controllerName and script/action name $actionName

-
-EOS; - } - return $contents; - } - - protected function _convertActionNameToFilesystemName($actionName) - { - $filter = new Zend_Filter(); - $filter->addFilter(new Zend_Filter_Word_CamelCaseToDash()) - ->addFilter(new Zend_Filter_StringToLower()); - return $filter->filter($actionName); - } - -} diff --git a/lib/Zend/Tool/Project/Context/Zf/ViewScriptsDirectory.php b/lib/Zend/Tool/Project/Context/Zf/ViewScriptsDirectory.php deleted file mode 100644 index 7ab508a0e05..00000000000 --- a/lib/Zend/Tool/Project/Context/Zf/ViewScriptsDirectory.php +++ /dev/null @@ -1,57 +0,0 @@ -_getZfPath(); - if ($zfPath != false) { - $zfIterator = new RecursiveDirectoryIterator($zfPath); - foreach ($rii = new RecursiveIteratorIterator($zfIterator, RecursiveIteratorIterator::SELF_FIRST) as $file) { - $relativePath = preg_replace('#^'.preg_quote(realpath($zfPath), '#').'#', '', realpath($file->getPath())) . DIRECTORY_SEPARATOR . $file->getFilename(); - if (strpos($relativePath, DIRECTORY_SEPARATOR . '.') !== false) { - continue; - } - - if ($file->isDir()) { - mkdir($this->getBaseDirectory() . DIRECTORY_SEPARATOR . $this->getFilesystemName() . $relativePath); - } else { - copy($file->getPathname(), $this->getBaseDirectory() . DIRECTORY_SEPARATOR . $this->getFilesystemName() . $relativePath); - } - - } - } - } - - /** - * _getZfPath() - * - * @return string|false - */ - protected function _getZfPath() - { - #require_once 'Zend/Loader.php'; - foreach (Zend_Loader::explodeIncludePath() as $includePath) { - if (!file_exists($includePath) || $includePath[0] == '.') { - continue; - } - - if (realpath($checkedPath = rtrim($includePath, '\\/') . '/Zend/Loader.php') !== false && file_exists($checkedPath)) { - return dirname($checkedPath); - } - } - - return false; - } - -} diff --git a/lib/Zend/Tool/Project/Exception.php b/lib/Zend/Tool/Project/Exception.php deleted file mode 100644 index c9fe2991ffb..00000000000 --- a/lib/Zend/Tool/Project/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -setOptions($options); - } - - $this->_topResources = new Zend_Tool_Project_Profile_Resource_Container(); - } - - /** - * Process options and either set a profile property or - * set a profile 'attribute' - * - * @param array $options - */ - public function setOptions(Array $options) - { - $this->setAttributes($options); - } - - /** - * getIterator() - reqruied by the RecursiveIterator interface - * - * @return RecursiveIteratorIterator - */ - public function getIterator() - { - #require_once 'Zend/Tool/Project/Profile/Iterator/EnabledResourceFilter.php'; - - return new RecursiveIteratorIterator( - new Zend_Tool_Project_Profile_Iterator_EnabledResourceFilter($this), - RecursiveIteratorIterator::SELF_FIRST - ); - } - - /** - * loadFromData() - Load a profile from data provided by the - * 'profilData' attribute - * - */ - public function loadFromData() - { - if (!isset($this->_attributes['profileData'])) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('loadFromData() must have "profileData" set.'); - } - - $profileFileParser = new Zend_Tool_Project_Profile_FileParser_Xml(); - $profileFileParser->unserialize($this->_attributes['profileData'], $this); - - $this->rewind(); - } - - /** - * isLoadableFromFile() - can a profile be loaded from a file - * - * wether or not a profile can be loaded from the - * file in attribute 'projectProfileFile', or from a file named - * '.zfproject.xml' inside a directory in key 'projectDirectory' - * - * @return bool - */ - public function isLoadableFromFile() - { - if (!isset($this->_attributes['projectProfileFile']) && !isset($this->_attributes['projectDirectory'])) { - return false; - } - - if (isset($this->_attributes['projectProfileFile'])) { - $projectProfileFilePath = $this->_attributes['projectProfileFile']; - if (!file_exists($projectProfileFilePath)) { - return false; - } - } else { - $projectProfileFilePath = rtrim($this->_attributes['projectDirectory'], '/\\') . '/.zfproject.xml'; - if (!file_exists($projectProfileFilePath)) { - return false; - } - } - - return true; - } - - /** - * loadFromFile() - Load data from file - * - * this attempts to load a project profile file from a variety of locations depending - * on what information the user provided vie $options or attributes, specifically the - * 'projectDirectory' or 'projectProfileFile' - * - */ - public function loadFromFile() - { - // if no data is supplied, need either a projectProfileFile or a projectDirectory - if (!isset($this->_attributes['projectProfileFile']) && !isset($this->_attributes['projectDirectory'])) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('loadFromFile() must have at least "projectProfileFile" or "projectDirectory" set.'); - } - - if (isset($this->_attributes['projectProfileFile'])) { - $projectProfileFilePath = $this->_attributes['projectProfileFile']; - if (!file_exists($projectProfileFilePath)) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('"projectProfileFile" was supplied but file was not found at location ' . $projectProfileFilePath); - } - $this->_attributes['projectDirectory'] = dirname($projectProfileFilePath); - } else { - $projectProfileFilePath = rtrim($this->_attributes['projectDirectory'], '/\\') . '/.zfproject.xml'; - if (!file_exists($projectProfileFilePath)) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('"projectDirectory" was supplied but no profile file file was not found at location ' . $projectProfileFilePath); - } - $this->_attributes['projectProfileFile'] = $projectProfileFilePath; - } - - $profileData = file_get_contents($projectProfileFilePath); - - $profileFileParser = new Zend_Tool_Project_Profile_FileParser_Xml(); - $profileFileParser->unserialize($profileData, $this); - - $this->rewind(); - } - - /** - * storeToFile() - store the current profile to file - * - * This will store the profile in memory to a place on disk determined by the attributes - * available, specifically if the key 'projectProfileFile' is available - * - */ - public function storeToFile() - { - $file = null; - - if (isset($this->_attributes['projectProfileFile'])) { - $file = $this->_attributes['projectProfileFile']; - } - - if ($file == null) { - #require_once 'Zend/Tool/Project/Exception.php'; - throw new Zend_Tool_Project_Exception('storeToFile() must have a "projectProfileFile" attribute set.'); - } - - $parser = new Zend_Tool_Project_Profile_FileParser_Xml(); - $xml = $parser->serialize($this); - file_put_contents($file, $xml); - } - - /** - * storeToData() - create a string representation of the profile in memory - * - * @return string - */ - public function storeToData() - { - $parser = new Zend_Tool_Project_Profile_FileParser_Xml(); - $xml = $parser->serialize($this); - return $xml; - } - - /** - * __toString() - cast this profile to string to be able to view it. - * - * @return string - */ - public function __toString() - { - $string = ''; - foreach ($this as $resource) { - $string .= $resource->getName() . PHP_EOL; - $rii = new RecursiveIteratorIterator($resource, RecursiveIteratorIterator::SELF_FIRST); - foreach ($rii as $item) { - $string .= str_repeat(' ', $rii->getDepth()+1) . $item->getName() - . ((count($attributes = $item->getAttributes()) > 0) ? ' [' . http_build_query($attributes) . ']' : '') - . PHP_EOL; - } - } - return $string; - } -} diff --git a/lib/Zend/Tool/Project/Profile/Exception.php b/lib/Zend/Tool/Project/Profile/Exception.php deleted file mode 100644 index b89fcd44048..00000000000 --- a/lib/Zend/Tool/Project/Profile/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_contextRepository = Zend_Tool_Project_Context_Repository::getInstance(); - } - - /** - * serialize() - * - * create an xml string from the provided profile - * - * @param Zend_Tool_Project_Profile $profile - * @return string - */ - public function serialize(Zend_Tool_Project_Profile $profile) - { - - $profile = clone $profile; - - $this->_profile = $profile; - $xmlElement = new SimpleXMLElement(''); - - if ($profile->hasAttribute('type')) { - $xmlElement->addAttribute('type', $profile->getAttribute('type')); - } - - if ($profile->hasAttribute('version')) { - $xmlElement->addAttribute('version', $profile->getAttribute('version')); - } - - self::_serializeRecurser($profile, $xmlElement); - - $doc = new DOMDocument('1.0'); - $doc->formatOutput = true; - $domnode = dom_import_simplexml($xmlElement); - $domnode = $doc->importNode($domnode, true); - $domnode = $doc->appendChild($domnode); - - return $doc->saveXML(); - } - - /** - * unserialize() - * - * Create a structure in the object $profile from the structure specficied - * in the xml string provided - * - * @param string xml data - * @param Zend_Tool_Project_Profile The profile to use as the top node - * @return Zend_Tool_Project_Profile - */ - public function unserialize($data, Zend_Tool_Project_Profile $profile) - { - if ($data == null) { - throw new Exception('contents not available to unserialize.'); - } - - $this->_profile = $profile; - - $xmlDataIterator = new SimpleXMLIterator($data); - - if ($xmlDataIterator->getName() != 'projectProfile') { - throw new Exception('Profiles must start with a projectProfile node'); - } - - if (isset($xmlDataIterator['type'])) { - $this->_profile->setAttribute('type', (string) $xmlDataIterator['type']); - } - - if (isset($xmlDataIterator['version'])) { - $this->_profile->setAttribute('version', (string) $xmlDataIterator['version']); - } - - // start un-serialization of the xml doc - $this->_unserializeRecurser($xmlDataIterator); - - // contexts should be initialized after the unwinding of the profile structure - $this->_lazyLoadContexts(); - - return $this->_profile; - - } - - /** - * _serializeRecurser() - * - * This method will be used to traverse the depths of the structure - * when *serializing* an xml structure into a string - * - * @param array $resources - * @param SimpleXmlElement $xmlNode - */ - protected function _serializeRecurser($resources, SimpleXmlElement $xmlNode) - { - // @todo find a better way to handle concurrency.. if no clone, _position in node gets messed up - //if ($resources instanceof Zend_Tool_Project_Profile_Resource) { - // $resources = clone $resources; - //} - - foreach ($resources as $resource) { - - if ($resource->isDeleted()) { - continue; - } - - $resourceName = $resource->getContext()->getName(); - $resourceName[0] = strtolower($resourceName[0]); - - $newNode = $xmlNode->addChild($resourceName); - - //$reflectionClass = new ReflectionClass($resource->getContext()); - - if ($resource->isEnabled() == false) { - $newNode->addAttribute('enabled', 'false'); - } - - foreach ($resource->getPersistentAttributes() as $paramName => $paramValue) { - $newNode->addAttribute($paramName, $paramValue); - } - - if ($resource->hasChildren()) { - self::_serializeRecurser($resource, $newNode); - } - - } - - } - - - /** - * _unserializeRecurser() - * - * This method will be used to traverse the depths of the structure - * as needed to *unserialize* the profile from an xmlIterator - * - * @param SimpleXMLIterator $xmlIterator - * @param Zend_Tool_Project_Profile_Resource $resource - */ - protected function _unserializeRecurser(SimpleXMLIterator $xmlIterator, Zend_Tool_Project_Profile_Resource $resource = null) - { - - foreach ($xmlIterator as $resourceName => $resourceData) { - - $contextName = $resourceName; - $subResource = new Zend_Tool_Project_Profile_Resource($contextName); - $subResource->setProfile($this->_profile); - - if ($resourceAttributes = $resourceData->attributes()) { - $attributes = array(); - foreach ($resourceAttributes as $attrName => $attrValue) { - $attributes[$attrName] = (string) $attrValue; - } - $subResource->setAttributes($attributes); - } - - if ($resource) { - $resource->append($subResource, false); - } else { - $this->_profile->append($subResource); - } - - if ($this->_contextRepository->isOverwritableContext($contextName) == false) { - $subResource->initializeContext(); - } - - if ($xmlIterator->hasChildren()) { - self::_unserializeRecurser($xmlIterator->getChildren(), $subResource); - } - } - } - - /** - * _lazyLoadContexts() - * - * This method will call initializeContext on the resources in a profile - * @todo determine if this method belongs inside the profile - * - */ - protected function _lazyLoadContexts() - { - - foreach ($this->_profile as $topResource) { - $rii = new RecursiveIteratorIterator($topResource, RecursiveIteratorIterator::SELF_FIRST); - foreach ($rii as $resource) { - $resource->initializeContext(); - } - } - - } - -} diff --git a/lib/Zend/Tool/Project/Profile/Iterator/ContextFilter.php b/lib/Zend/Tool/Project/Profile/Iterator/ContextFilter.php deleted file mode 100644 index 392d564dbb8..00000000000 --- a/lib/Zend/Tool/Project/Profile/Iterator/ContextFilter.php +++ /dev/null @@ -1,213 +0,0 @@ -_rawOptions = $options; - if ($options) { - $this->setOptions($options); - } - } - - /** - * setOptions() - * - * @param array $options - */ - public function setOptions(Array $options) - { - foreach ($options as $optionName => $optionValue) { - if (substr($optionName, -1, 1) != 's') { - $optionName .= 's'; - } - if (method_exists($this, 'set' . $optionName)) { - $this->{'set' . $optionName}($optionValue); - } - } - } - - /** - * setAcceptTypes() - * - * @param array|string $acceptTypes - * @return Zend_Tool_Project_Profile_Iterator_ContextFilter - */ - public function setAcceptTypes($acceptTypes) - { - if (!is_array($acceptTypes)) { - $acceptTypes = array($acceptTypes); - } - - $this->_acceptTypes = $acceptTypes; - return $this; - } - - /** - * setDenyTypes() - * - * @param array|string $denyTypes - * @return Zend_Tool_Project_Profile_Iterator_ContextFilter - */ - public function setDenyTypes($denyTypes) - { - if (!is_array($denyTypes)) { - $denyTypes = array($denyTypes); - } - - $this->_denyTypes = $denyTypes; - return $this; - } - - /** - * setAcceptNames() - * - * @param array|string $acceptNames - * @return Zend_Tool_Project_Profile_Iterator_ContextFilter - */ - public function setAcceptNames($acceptNames) - { - if (!is_array($acceptNames)) { - $acceptNames = array($acceptNames); - } - - foreach ($acceptNames as $n => $v) { - $acceptNames[$n] = strtolower($v); - } - - $this->_acceptNames = $acceptNames; - return $this; - } - - /** - * setDenyNames() - * - * @param array|string $denyNames - * @return Zend_Tool_Project_Profile_Iterator_ContextFilter - */ - public function setDenyNames($denyNames) - { - if (!is_array($denyNames)) { - $denyNames = array($denyNames); - } - - foreach ($denyNames as $n => $v) { - $denyNames[$n] = strtolower($v); - } - - $this->_denyNames = $denyNames; - return $this; - } - - /** - * accept() is required by teh RecursiveFilterIterator - * - * @return bool - */ - #[ReturnTypeWillChange] - public function accept() - { - $currentItem = $this->current(); - - if (in_array(strtolower($currentItem->getName()), $this->_acceptNames)) { - return true; - } elseif (in_array(strtolower($currentItem->getName()), $this->_denyNames)) { - return false; - } - - foreach ($this->_acceptTypes as $acceptType) { - if ($currentItem->getContent() instanceof $acceptType) { - return true; - } - } - - foreach ($this->_denyTypes as $denyType) { - if ($currentItem->getContext() instanceof $denyType) { - return false; - } - } - - return true; - } - - /** - * getChildren() - * - * This is here due to a bug/design issue in PHP - * @link - * - * @return unknown - */ - #[ReturnTypeWillChange] - function getChildren() - { - - if (empty($this->ref)) { - $this->ref = new ReflectionClass($this); - } - - return $this->ref->newInstance($this->getInnerIterator()->getChildren(), $this->_rawOptions); - } - -} diff --git a/lib/Zend/Tool/Project/Profile/Iterator/EnabledResourceFilter.php b/lib/Zend/Tool/Project/Profile/Iterator/EnabledResourceFilter.php deleted file mode 100644 index ff7dfe5a0bd..00000000000 --- a/lib/Zend/Tool/Project/Profile/Iterator/EnabledResourceFilter.php +++ /dev/null @@ -1,44 +0,0 @@ -current()->isEnabled(); - } -} diff --git a/lib/Zend/Tool/Project/Profile/Resource.php b/lib/Zend/Tool/Project/Profile/Resource.php deleted file mode 100644 index 27bef92bfc1..00000000000 --- a/lib/Zend/Tool/Project/Profile/Resource.php +++ /dev/null @@ -1,262 +0,0 @@ -setContext($context); - } - - /** - * setContext() - * - * @param string|Zend_Tool_Project_Context_Interface $context - * @return Zend_Tool_Project_Profile_Resource - */ - public function setContext($context) - { - $this->_context = $context; - return $this; - } - - /** - * getContext() - * - * @return Zend_Tool_Project_Context_Interface - */ - public function getContext() - { - return $this->_context; - } - - /** - * getName() - Get the resource name - * - * Name is derived from the context name - * - * @return string - */ - public function getName() - { - if (is_string($this->_context)) { - return $this->_context; - } elseif ($this->_context instanceof Zend_Tool_Project_Context_Interface) { - return $this->_context->getName(); - } else { - throw new Zend_Tool_Project_Exception('Invalid context in resource'); - } - } - - /** - * setProfile() - * - * @param Zend_Tool_Project_Profile $profile - * @return Zend_Tool_Project_Profile_Resource - */ - public function setProfile(Zend_Tool_Project_Profile $profile) - { - $this->_profile = $profile; - return $this; - } - - /** - * getProfile - * - * @return Zend_Tool_Project_Profile - */ - public function getProfile() - { - return $this->_profile; - } - - /** - * getPersistentAttributes() - * - * @return array - */ - public function getPersistentAttributes() - { - if (method_exists($this->_context, 'getPersistentAttributes')) { - return $this->_context->getPersistentAttributes(); - } - - return array(); - } - - /** - * setEnabled() - * - * @param bool $enabled - * @return Zend_Tool_Project_Profile_Resource - */ - public function setEnabled($enabled = true) - { - // convert fuzzy types to bool - $this->_enabled = (!in_array($enabled, array('false', 'disabled', 0, -1, false), true)) ? true : false; - return $this; - } - - /** - * isEnabled() - * - * @return bool - */ - public function isEnabled() - { - return $this->_enabled; - } - - /** - * setDeleted() - * - * @param bool $deleted - * @return Zend_Tool_Project_Profile_Resource - */ - public function setDeleted($deleted = true) - { - $this->_deleted = (bool) $deleted; - return $this; - } - - /** - * isDeleted() - * - * @return Zend_Tool_Project_Profile_Resource - */ - public function isDeleted() - { - return $this->_deleted; - } - - /** - * initializeContext() - * - * @return Zend_Tool_Project_Profile_Resource - */ - public function initializeContext() - { - if ($this->_isContextInitialized) { - return; - } - if (is_string($this->_context)) { - $this->_context = Zend_Tool_Project_Context_Repository::getInstance()->getContext($this->_context); - } - - if (method_exists($this->_context, 'setResource')) { - $this->_context->setResource($this); - } - - if (method_exists($this->_context, 'init')) { - $this->_context->init(); - } - - $this->_isContextInitialized = true; - return $this; - } - - /** - * __toString() - * - * @return string - */ - public function __toString() - { - return $this->_context->getName(); - } - - /** - * __call() - * - * @param string $method - * @param array $arguments - * @return Zend_Tool_Project_Profile_Resource - */ - public function __call($method, $arguments) - { - if (method_exists($this->_context, $method)) { - if (!$this->isEnabled()) { - $this->setEnabled(true); - } - return call_user_func_array(array($this->_context, $method), $arguments); - } else { - throw new Zend_Tool_Project_Profile_Exception('cannot call ' . $method); - } - } - -} diff --git a/lib/Zend/Tool/Project/Profile/Resource/Container.php b/lib/Zend/Tool/Project/Profile/Resource/Container.php deleted file mode 100644 index 04d3d51a72c..00000000000 --- a/lib/Zend/Tool/Project/Profile/Resource/Container.php +++ /dev/null @@ -1,421 +0,0 @@ - - * - * - * - * @param Zend_Tool_Project_Profile_Resource_SearchConstraints|string|array $searchParameters - * @return Zend_Tool_Project_Profile_Resource - */ - public function search($matchSearchConstraints, $nonMatchSearchConstraints = null) - { - if (!$matchSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_SearchConstraints) { - $matchSearchConstraints = new Zend_Tool_Project_Profile_Resource_SearchConstraints($matchSearchConstraints); - } - - $this->rewind(); - - /** - * @todo This should be re-written with better support for a filter iterator, its the way to go - */ - - if ($nonMatchSearchConstraints) { - $filterIterator = new Zend_Tool_Project_Profile_Iterator_ContextFilter($this, array('denyNames' => $nonMatchSearchConstraints)); - $riIterator = new RecursiveIteratorIterator($filterIterator, RecursiveIteratorIterator::SELF_FIRST); - } else { - $riIterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST); - } - - $foundResource = false; - $currentConstraint = $matchSearchConstraints->getConstraint(); - $foundDepth = 0; - - foreach ($riIterator as $currentResource) { - - // if current depth is less than found depth, end - if ($riIterator->getDepth() < $foundDepth) { - break; - } - - if (strtolower($currentResource->getName()) == strtolower($currentConstraint->name)) { - - $paramsMatch = true; - - // @todo check to ensure params match (perhaps) - if (count($currentConstraint->params) > 0) { - $currentResourceAttributes = $currentResource->getAttributes(); - if (!is_array($currentConstraint->params)) { - #require_once 'Zend/Tool/Project/Profile/Exception.php'; - throw new Zend_Tool_Project_Profile_Exception('Search parameter specifics must be in the form of an array for key "' - . $currentConstraint->name .'"'); - } - foreach ($currentConstraint->params as $paramName => $paramValue) { - if (!isset($currentResourceAttributes[$paramName]) || $currentResourceAttributes[$paramName] != $paramValue) { - $paramsMatch = false; - break; - } - } - } - - if ($paramsMatch) { - $foundDepth = $riIterator->getDepth(); - - if (($currentConstraint = $matchSearchConstraints->getConstraint()) == null) { - $foundResource = $currentResource; - break; - } - } - - } - - } - - return $foundResource; - } - - /** - * createResourceAt() - * - * @param array|Zend_Tool_Project_Profile_Resource_SearchConstraints $appendResourceOrSearchConstraints - * @param string $context - * @param array $attributes - * @return Zend_Tool_Project_Profile_Resource - */ - public function createResourceAt($appendResourceOrSearchConstraints, $context, Array $attributes = array()) - { - if (!$appendResourceOrSearchConstraints instanceof Zend_Tool_Project_Profile_Resource_Container) { - if (($parentResource = $this->search($appendResourceOrSearchConstraints)) == false) { - #require_once 'Zend/Tool/Project/Profile/Exception.php'; - throw new Zend_Tool_Project_Profile_Exception('No node was found to append to.'); - } - } else { - $parentResource = $appendResourceOrSearchConstraints; - } - - return $parentResource->createResource($context, $attributes); - } - - /** - * createResource() - * - * Method to create a resource with a given context with specific attributes - * - * @param string $context - * @param array $attributes - * @return Zend_Tool_Project_Profile_Resource - */ - public function createResource($context, Array $attributes = array()) - { - if (is_string($context)) { - $contextRegistry = Zend_Tool_Project_Context_Repository::getInstance(); - if ($contextRegistry->hasContext($context)) { - $context = $contextRegistry->getContext($context); - } else { - #require_once 'Zend/Tool/Project/Profile/Exception.php'; - throw new Zend_Tool_Project_Profile_Exception('Context by name ' . $context . ' was not found in the context registry.'); - } - } elseif (!$context instanceof Zend_Tool_Project_Context_Interface) { - #require_once 'Zend/Tool/Project/Profile/Exception.php'; - throw new Zend_Tool_Project_Profile_Exception('Context must be of type string or Zend_Tool_Project_Context_Interface.'); - } - - $newResource = new Zend_Tool_Project_Profile_Resource($context); - - if ($attributes) { - $newResource->setAttributes($attributes); - } - - /** - * Interesting logic here: - * - * First set the parentResource (this will also be done inside append). This will allow - * the initialization routine to change the appendability of the parent resource. This - * is important to allow specific resources to be appendable by very specific sub-resources. - */ - $newResource->setParentResource($this); - $newResource->initializeContext(); - $this->append($newResource); - - return $newResource; - } - - /** - * setAttributes() - * - * persist the attributes if the resource will accept them - * - * @param array $attributes - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function setAttributes(Array $attributes) - { - foreach ($attributes as $attrName => $attrValue) { - $setMethod = 'set' . $attrName; - if (method_exists($this, $setMethod)) { - $this->{$setMethod}($attrValue); - } else { - $this->setAttribute($attrName, $attrValue); - } - } - return $this; - } - - /** - * getAttributes() - * - * @return array - */ - public function getAttributes() - { - return $this->_attributes; - } - - /** - * setAttribute() - * - * @param string $name - * @param mixed $value - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function setAttribute($name, $value) - { - $this->_attributes[$name] = $value; - return $this; - } - - /** - * getAttribute() - * - * @param string $name - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function getAttribute($name) - { - return (array_key_exists($name, $this->_attributes)) ? $this->_attributes[$name] : null; - } - - /** - * hasAttribute() - * - * @param string $name - * @return bool - */ - public function hasAttribute($name) - { - return array_key_exists($name, $this->_attributes); - } - - /** - * setAppendable() - * - * @param bool $appendable - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function setAppendable($appendable) - { - $this->_appendable = (bool) $appendable; - return $this; - } - - /** - * isAppendable() - * - * @return bool - */ - public function isAppendable() - { - return $this->_appendable; - } - - /** - * setParentResource() - * - * @param Zend_Tool_Project_Profile_Resource_Container $parentResource - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function setParentResource(Zend_Tool_Project_Profile_Resource_Container $parentResource) - { - $this->_parentResource = $parentResource; - return $this; - } - - /** - * getParentResource() - * - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function getParentResource() - { - return $this->_parentResource; - } - - /** - * append() - * - * @param Zend_Tool_Project_Profile_Resource_Container $resource - * @return Zend_Tool_Project_Profile_Resource_Container - */ - public function append(Zend_Tool_Project_Profile_Resource_Container $resource) - { - if (!$this->isAppendable()) { - throw new Exception('Resource by name ' . (string) $this . ' is not appendable'); - } - array_push($this->_subResources, $resource); - $resource->setParentResource($this); - - return $this; - } - - /** - * current() - required by RecursiveIterator - * - * @return Zend_Tool_Project_Profile_Resource - */ - public function current() - { - return current($this->_subResources); - } - - /** - * key() - required by RecursiveIterator - * - * @return int - */ - public function key() - { - return key($this->_subResources); - } - - /** - * next() - required by RecursiveIterator - * - * @return bool - */ - public function next() - { - return next($this->_subResources); - } - - /** - * rewind() - required by RecursiveIterator - * - * @return bool - */ - public function rewind() - { - return reset($this->_subResources); - } - - /** - * valid() - - required by RecursiveIterator - * - * @return bool - */ - public function valid() - { - return (bool) $this->current(); - } - - /** - * hasChildren() - * - * @return bool - */ - public function hasChildren() - { - return (count($this->_subResources > 0)) ? true : false; - } - - /** - * getChildren() - * - * @return array - */ - public function getChildren() - { - return $this->current(); - } - - /** - * count() - * - * @return int - */ - public function count() - { - return count($this->_subResources); - } - - /** - * __clone() - * - */ - public function __clone() - { - $this->rewind(); - foreach ($this->_subResources as $index => $resource) { - $this->_subResources[$index] = clone $resource; - } - } - -} diff --git a/lib/Zend/Tool/Project/Profile/Resource/SearchConstraints.php b/lib/Zend/Tool/Project/Profile/Resource/SearchConstraints.php deleted file mode 100644 index e43bbeb77f2..00000000000 --- a/lib/Zend/Tool/Project/Profile/Resource/SearchConstraints.php +++ /dev/null @@ -1,117 +0,0 @@ -addConstraint($options); - } elseif (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * setOptions() - * - * @param array $option - * @return Zend_Tool_Project_Profile_Resource_SearchConstraints - */ - public function setOptions(Array $option) - { - foreach ($option as $optionName => $optionValue) { - if (is_int($optionName)) { - $this->addConstraint($optionValue); - } elseif (is_string($optionName)) { - $this->addConstraint(array('name' => $optionName, 'params' => $optionValue)); - } - } - - return $this; - } - - /** - * addConstraint() - * - * @param string|array $constraint - * @return Zend_Tool_Project_Profile_Resource_SearchConstraints - */ - public function addConstraint($constraint) - { - if (is_string($constraint)) { - $name = $constraint; - $params = array(); - } elseif (is_array($constraint)) { - $name = $constraint['name']; - $params = $constraint['params']; - } - - $constraint = $this->_makeConstraint($name, $params); - - array_push($this->_constraints, $constraint); - return $this; - } - - /** - * getConstraint() - * - * @return ArrayObject - */ - public function getConstraint() - { - return array_shift($this->_constraints); - } - - /** - * _makeConstraint - * - * @param string $name - * @param mixed $params - * @return ArrayObject - */ - protected function _makeConstraint($name, $params) - { - $value = array('name' => $name, 'params' => $params); - return new ArrayObject($value, ArrayObject::ARRAY_AS_PROPS); - } - -} diff --git a/lib/Zend/Tool/Project/Provider/Abstract.php b/lib/Zend/Tool/Project/Provider/Abstract.php deleted file mode 100644 index 3a85cb61f53..00000000000 --- a/lib/Zend/Tool/Project/Provider/Abstract.php +++ /dev/null @@ -1,279 +0,0 @@ -addContextsFromDirectory( - dirname(dirname(__FILE__)) . '/Context/Zf/', 'Zend_Tool_Project_Context_Zf_' - ); - $contextRegistry->addContextsFromDirectory( - dirname(dirname(__FILE__)) . '/Context/Filesystem/', 'Zend_Tool_Project_Context_Filesystem_' - ); - - // determine if there are project specfic providers ONCE - $profilePath = $this->_findProfileDirectory(); - if ($this->_hasProjectProviderDirectory($profilePath . DIRECTORY_SEPARATOR . '.zfproject.xml')) { - $profile = $this->_loadProfile(); - // project providers directory resource - $ppd = $profile->search('ProjectProvidersDirectory'); - $ppd->loadProviders($this->_registry); - } - - self::$_isInitialized = true; - } - - // load up the extending providers required context classes - if ($contextClasses = $this->getContextClasses()) { - $this->_loadContextClassesIntoRegistry($contextClasses); - } - - } - - public function getContextClasses() - { - return array(); - } - - /** - * _getProject is designed to find if there is project file in the context of where - * the client has been called from.. The search order is as follows.. - * - traversing downwards from (PWD) - current working directory - * - if an enpoint variable has been registered in teh client registry - key=workingDirectory - * - if an ENV variable with the key ZFPROJECT_PATH is found - * - * @param bool $loadProfileFlag Whether or not to throw an exception when no profile is found - * @param string $projectDirectory The project directory to use to search - * @param bool $searchParentDirectories Whether or not to search upper level direcotries - * @return Zend_Tool_Project_Profile - */ - protected function _loadProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION, $projectDirectory = null, $searchParentDirectories = true) - { - $foundPath = $this->_findProfileDirectory($projectDirectory, $searchParentDirectories); - - if ($foundPath == false) { - if ($loadProfileFlag == self::NO_PROFILE_THROW_EXCEPTION) { - throw new Zend_Tool_Project_Provider_Exception('A project profile was not found.'); - } else { - return false; - } - } - - $profile = new Zend_Tool_Project_Profile(); - $profile->setAttribute('projectDirectory', $foundPath); - $profile->loadFromFile(); - $this->_loadedProfile = $profile; - return $profile; - } - - protected function _findProfileDirectory($projectDirectory = null, $searchParentDirectories = true) - { - // use the cwd if no directory was provided - if ($projectDirectory == null) { - $projectDirectory = getcwd(); - } elseif (realpath($projectDirectory) == false) { - throw new Zend_Tool_Project_Provider_Exception('The $projectDirectory supplied does not exist.'); - } - - $profile = new Zend_Tool_Project_Profile(); - - $parentDirectoriesArray = explode(DIRECTORY_SEPARATOR, ltrim($projectDirectory, DIRECTORY_SEPARATOR)); - while ($parentDirectoriesArray) { - $projectDirectoryAssembled = implode(DIRECTORY_SEPARATOR, $parentDirectoriesArray); - - if (DIRECTORY_SEPARATOR !== "\\") { - $projectDirectoryAssembled = DIRECTORY_SEPARATOR . $projectDirectoryAssembled; - } - - $profile->setAttribute('projectDirectory', $projectDirectoryAssembled); - if ($profile->isLoadableFromFile()) { - unset($profile); - return $projectDirectoryAssembled; - } - - // break after first run if we are not to check upper directories - if ($searchParentDirectories == false) { - break; - } - - array_pop($parentDirectoriesArray); - } - - return false; - } - - /** - * Load the project profile from the current working directory, if not throw exception - * - * @return Zend_Tool_Project_Profile - */ - protected function _loadProfileRequired() - { - $profile = $this->_loadProfile(); - if ($profile === false) { - #require_once 'Zend/Tool/Project/Provider/Exception.php'; - throw new Zend_Tool_Project_Provider_Exception('A project profile was not found in the current working directory.'); - } - return $profile; - } - - /** - * Return the currently loaded profile - * - * @return Zend_Tool_Project_Profile - */ - protected function _getProfile($loadProfileFlag = self::NO_PROFILE_THROW_EXCEPTION) - { - if (!$this->_loadedProfile) { - if (($this->_loadProfile($loadProfileFlag) === false) && ($loadProfileFlag === self::NO_PROFILE_RETURN_FALSE)) { - return false; - } - } - - return $this->_loadedProfile; - } - - /** - * _storeProfile() - * - * This method will store the profile into its proper location - * - */ - protected function _storeProfile() - { - $projectProfileFile = $this->_loadedProfile->search('ProjectProfileFile'); - - $name = $projectProfileFile->getContext()->getPath(); - - $this->_registry->getResponse()->appendContent('Updating project profile \'' . $name . '\''); - - $projectProfileFile->getContext()->save(); - } - - protected function _getContentForContext(Zend_Tool_Project_Context_Interface $context, $methodName, $parameters) - { - $storage = $this->_registry->getStorage(); - if (!$storage->isEnabled()) { - return false; - } - - if (!class_exists('Zend_Tool_Project_Context_Content_Engine')) { - #require_once 'Zend/Tool/Project/Context/Content/Engine.php'; - } - - $engine = new Zend_Tool_Project_Context_Content_Engine($storage); - return $engine->getContent($context, $methodName, $parameters); - } - - protected function _hasProjectProviderDirectory($pathToProfileFile) - { - // do some static analysis of the file so that we can determin whether or not to incure - // the cost of loading the profile before the system is fully bootstrapped - if (!file_exists($pathToProfileFile)) { - return false; - } - - $contents = file_get_contents($pathToProfileFile); - if (strstr($contents, 'addContextClass($contextClass); - } - } -} diff --git a/lib/Zend/Tool/Project/Provider/Action.php b/lib/Zend/Tool/Project/Provider/Action.php deleted file mode 100644 index a9a90e89021..00000000000 --- a/lib/Zend/Tool/Project/Provider/Action.php +++ /dev/null @@ -1,242 +0,0 @@ -createResource('ActionMethod', array('actionName' => $actionName)); - - return $actionMethod; - } - - /** - * hasResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $actionName - * @param string $controllerName - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - public static function hasResource(Zend_Tool_Project_Profile $profile, $actionName, $controllerName, $moduleName = null) - { - if (!is_string($actionName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_Action::createResource() expects \"actionName\" is the name of a action resource to create.'); - } - - if (!is_string($controllerName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_Action::createResource() expects \"controllerName\" is the name of a controller resource to create.'); - } - - $controllerFile = self::_getControllerFileResource($profile, $controllerName, $moduleName); - - if ($controllerFile == null) { - throw new Zend_Tool_Project_Provider_Exception('Controller ' . $controllerName . ' was not found.'); - } - - return (($controllerFile->search(array('actionMethod' => array('actionName' => $actionName)))) instanceof Zend_Tool_Project_Profile_Resource); - } - - /** - * _getControllerFileResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $controllerName - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - protected static function _getControllerFileResource(Zend_Tool_Project_Profile $profile, $controllerName, $moduleName = null) - { - $profileSearchParams = array(); - - if ($moduleName != null && is_string($moduleName)) { - $profileSearchParams = array('modulesDirectory', 'moduleDirectory' => array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'controllersDirectory'; - $profileSearchParams['controllerFile'] = array('controllerName' => $controllerName); - - return $profile->search($profileSearchParams); - } - - /** - * create() - * - * @param string $name Action name for controller, in camelCase format. - * @param string $controllerName Controller name action should be applied to. - * @param bool $viewIncluded Whether the view should the view be included. - * @param string $module Module name action should be applied to. - */ - public function create($name, $controllerName = 'Index', $viewIncluded = true, $module = null) - { - - $this->_loadProfile(); - - // get request/response object - $request = $this->_registry->getRequest(); - $response = $this->_registry->getResponse(); - - // determine if testing is enabled in the project - #require_once 'Zend/Tool/Project/Provider/Test.php'; - $testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - - if ($testingEnabled && !Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) { - $testingEnabled = false; - $response->appendContent( - 'Note: PHPUnit is required in order to generate controller test stubs.', - array('color' => array('yellow')) - ); - } - - // Check that there is not a dash or underscore, return if doesnt match regex - if (preg_match('#[_-]#', $name)) { - throw new Zend_Tool_Project_Provider_Exception('Action names should be camel cased.'); - } - - $originalName = $name; - $originalControllerName = $controllerName; - - // ensure it is camelCase (lower first letter) - $name = strtolower(substr($name, 0, 1)) . substr($name, 1); - - // ensure controller is MixedCase - $controllerName = ucfirst($controllerName); - - if (self::hasResource($this->_loadedProfile, $name, $controllerName, $module)) { - throw new Zend_Tool_Project_Provider_Exception('This controller (' . $controllerName . ') already has an action named (' . $name . ')'); - } - - $actionMethodResource = self::createResource($this->_loadedProfile, $name, $controllerName, $module); - - $testActionMethodResource = null; - if ($testingEnabled) { - $testActionMethodResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $controllerName, $name, $module); - } - - // alert the user about inline converted names - $tense = (($request->isPretend()) ? 'would be' : 'is'); - - if ($name !== $originalName) { - $response->appendContent( - 'Note: The canonical action name that ' . $tense - . ' used with other providers is "' . $name . '";' - . ' not "' . $originalName . '" as supplied', - array('color' => array('yellow')) - ); - } - - if ($controllerName !== $originalControllerName) { - $response->appendContent( - 'Note: The canonical controller name that ' . $tense - . ' used with other providers is "' . $controllerName . '";' - . ' not "' . $originalControllerName . '" as supplied', - array('color' => array('yellow')) - ); - } - - unset($tense); - - if ($request->isPretend()) { - $response->appendContent( - 'Would create an action named ' . $name . - ' inside controller at ' . $actionMethodResource->getParentResource()->getContext()->getPath() - ); - - if ($testActionMethodResource) { - $response->appendContent('Would create an action test in ' . $testActionMethodResource->getParentResource()->getContext()->getPath()); - } - - } else { - $response->appendContent( - 'Creating an action named ' . $name . - ' inside controller at ' . $actionMethodResource->getParentResource()->getContext()->getPath() - ); - $actionMethodResource->create(); - - if ($testActionMethodResource) { - $response->appendContent('Creating an action test in ' . $testActionMethodResource->getParentResource()->getContext()->getPath()); - $testActionMethodResource->create(); - } - - $this->_storeProfile(); - } - - if ($viewIncluded) { - $viewResource = Zend_Tool_Project_Provider_View::createResource($this->_loadedProfile, $name, $controllerName, $module); - - if ($this->_registry->getRequest()->isPretend()) { - $response->appendContent( - 'Would create a view script for the ' . $name . ' action method at ' . $viewResource->getContext()->getPath() - ); - } else { - $response->appendContent( - 'Creating a view script for the ' . $name . ' action method at ' . $viewResource->getContext()->getPath() - ); - $viewResource->create(); - $this->_storeProfile(); - } - - } - - } - -} diff --git a/lib/Zend/Tool/Project/Provider/Application.php b/lib/Zend/Tool/Project/Provider/Application.php deleted file mode 100644 index d65f7feba88..00000000000 --- a/lib/Zend/Tool/Project/Provider/Application.php +++ /dev/null @@ -1,87 +0,0 @@ -_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $originalClassNamePrefix = $classNamePrefix; - - if (substr($classNamePrefix, -1) != '_') { - $classNamePrefix .= '_'; - } - - $configFileResource = $profile->search('ApplicationConfigFile'); - $zc = $configFileResource->getAsZendConfig('production'); - if ($zc->appnamespace == $classNamePrefix) { - throw new Zend_Tool_Project_Exception('The requested name ' . $classNamePrefix . ' is already the prefix.'); - } - - // remove the old - $configFileResource->removeStringItem('appnamespace', 'production'); - $configFileResource->create(); - - // add the new - $configFileResource->addStringItem('appnamespace', $classNamePrefix, 'production', true); - $configFileResource->create(); - - // update the project profile - $applicationDirectory = $profile->search('ApplicationDirectory'); - $applicationDirectory->setClassNamePrefix($classNamePrefix); - - $response = $this->_registry->getResponse(); - - if ($originalClassNamePrefix !== $classNamePrefix) { - $response->appendContent( - 'Note: the name provided "' . $originalClassNamePrefix . '" was' - . ' altered to "' . $classNamePrefix . '" for correctness.', - array('color' => 'yellow') - ); - } - - // note to the user - $response->appendContent('Note: All existing models will need to be altered to this new namespace by hand', array('color' => 'yellow')); - $response->appendContent('application.ini updated with new appnamespace ' . $classNamePrefix); - - // store profile - $this->_storeProfile(); - } - -} diff --git a/lib/Zend/Tool/Project/Provider/Controller.php b/lib/Zend/Tool/Project/Provider/Controller.php deleted file mode 100644 index 5c8bf44a0c2..00000000000 --- a/lib/Zend/Tool/Project/Provider/Controller.php +++ /dev/null @@ -1,209 +0,0 @@ -createResource( - 'controllerFile', - array('controllerName' => $controllerName, 'moduleName' => $moduleName) - ); - - return $newController; - } - - /** - * hasResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $controllerName - * @param string $moduleName - * @return boolean - */ - public static function hasResource(Zend_Tool_Project_Profile $profile, $controllerName, $moduleName = null) - { - if (!is_string($controllerName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_Controller::createResource() expects \"controllerName\" is the name of a controller resource to create.'); - } - - $controllersDirectory = self::_getControllersDirectoryResource($profile, $moduleName); - return ($controllersDirectory &&($controllersDirectory->search(array('controllerFile' => array('controllerName' => $controllerName)))) instanceof Zend_Tool_Project_Profile_Resource); - } - - /** - * _getControllersDirectoryResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - protected static function _getControllersDirectoryResource(Zend_Tool_Project_Profile $profile, $moduleName = null) - { - $profileSearchParams = array(); - - if ($moduleName != null && is_string($moduleName)) { - $profileSearchParams = array('modulesDirectory', 'moduleDirectory' => array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'controllersDirectory'; - - return $profile->search($profileSearchParams); - } - - /** - * Create a new controller - * - * @param string $name The name of the controller to create, in camelCase. - * @param bool $indexActionIncluded Whether or not to create the index action. - */ - public function create($name, $indexActionIncluded = true, $module = null) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - // get request & response - $request = $this->_registry->getRequest(); - $response = $this->_registry->getResponse(); - - // determine if testing is enabled in the project - #require_once 'Zend/Tool/Project/Provider/Test.php'; - $testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - - if ($testingEnabled && !Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) { - $testingEnabled = false; - $response->appendContent( - 'Note: PHPUnit is required in order to generate controller test stubs.', - array('color' => array('yellow')) - ); - } - - $originalName = $name; - $name = ucfirst($name); - - if (self::hasResource($this->_loadedProfile, $name, $module)) { - throw new Zend_Tool_Project_Provider_Exception('This project already has a controller named ' . $name); - } - - // Check that there is not a dash or underscore, return if doesnt match regex - if (preg_match('#[_-]#', $name)) { - throw new Zend_Tool_Project_Provider_Exception('Controller names should be camel cased.'); - } - - try { - $controllerResource = self::createResource($this->_loadedProfile, $name, $module); - if ($indexActionIncluded) { - $indexActionResource = Zend_Tool_Project_Provider_Action::createResource($this->_loadedProfile, 'index', $name, $module); - $indexActionViewResource = Zend_Tool_Project_Provider_View::createResource($this->_loadedProfile, 'index', $name, $module); - } - if ($testingEnabled) { - $testActionResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $name, 'index', $module); - } - - } catch (Exception $e) { - $response->setException($e); - return; - } - - // determime if we need to note to the user about the name - if (($name !== $originalName)) { - $tense = (($request->isPretend()) ? 'would be' : 'is'); - $response->appendContent( - 'Note: The canonical controller name that ' . $tense - . ' used with other providers is "' . $name . '";' - . ' not "' . $originalName . '" as supplied', - array('color' => array('yellow')) - ); - unset($tense); - } - - // do the creation - if ($request->isPretend()) { - - $response->appendContent('Would create a controller at ' . $controllerResource->getContext()->getPath()); - - if (isset($indexActionResource)) { - $response->appendContent('Would create an index action method in controller ' . $name); - $response->appendContent('Would create a view script for the index action method at ' . $indexActionViewResource->getContext()->getPath()); - } - - if ($testingEnabled) { - $response->appendContent('Would create a controller test file at ' . $testActionResource->getParentResource()->getContext()->getPath()); - } - - } else { - - $response->appendContent('Creating a controller at ' . $controllerResource->getContext()->getPath()); - $controllerResource->create(); - - if (isset($indexActionResource)) { - $response->appendContent('Creating an index action method in controller ' . $name); - $indexActionResource->create(); - $response->appendContent('Creating a view script for the index action method at ' . $indexActionViewResource->getContext()->getPath()); - $indexActionViewResource->create(); - } - - if ($testingEnabled) { - $response->appendContent('Creating a controller test file at ' . $testActionResource->getParentResource()->getContext()->getPath()); - $testActionResource->getParentResource()->create(); - $testActionResource->create(); - } - - $this->_storeProfile(); - } - - } - - - -} diff --git a/lib/Zend/Tool/Project/Provider/DbAdapter.php b/lib/Zend/Tool/Project/Provider/DbAdapter.php deleted file mode 100644 index 069b35f2670..00000000000 --- a/lib/Zend/Tool/Project/Provider/DbAdapter.php +++ /dev/null @@ -1,139 +0,0 @@ -_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $appConfigFileResource = $profile->search('applicationConfigFile'); - - if ($appConfigFileResource == false) { - throw new Zend_Tool_Project_Exception('A project with an application config file is required to use this provider.'); - } - - $this->_appConfigFilePath = $appConfigFileResource->getPath(); - - $this->_config = new Zend_Config_Ini($this->_appConfigFilePath, null, array('skipExtends' => true, 'allowModifications' => true)); - - if ($sectionName != 'production') { - $this->_sectionName = $sectionName; - } - - if (!isset($this->_config->{$this->_sectionName})) { - throw new Zend_Tool_Project_Exception('The config does not have a ' . $this->_sectionName . ' section.'); - } - - if (isset($this->_config->{$this->_sectionName}->resources->db)) { - throw new Zend_Tool_Project_Exception('The config already has a db resource configured in section ' . $this->_sectionName . '.'); - } - - if ($dsn) { - $this->_configureViaDSN($dsn); - //} elseif ($interactivelyPrompt) { - // $this->_promptForConfig(); - } else { - $this->_registry->getResponse()->appendContent('Nothing to do!'); - } - - - } - - protected function _configureViaDSN($dsn) - { - $dsnVars = array(); - - if (strpos($dsn, '=') === false) { - throw new Zend_Tool_Project_Provider_Exception('At least one name value pair is expected, typcially ' - . 'in the format of "adapter=Mysqli&username=uname&password=mypass&dbname=mydb"' - ); - } - - parse_str($dsn, $dsnVars); - - // parse_str suffers when magic_quotes is enabled - if (get_magic_quotes_gpc()) { - array_walk_recursive($dsnVars, array($this, '_cleanMagicQuotesInValues')); - } - - $dbConfigValues = array('resources' => array('db' => null)); - - if (isset($dsnVars['adapter'])) { - $dbConfigValues['resources']['db']['adapter'] = $dsnVars['adapter']; - unset($dsnVars['adapter']); - } - - $dbConfigValues['resources']['db']['params'] = $dsnVars; - - $isPretend = $this->_registry->getRequest()->isPretend(); - - // get the config resource - $applicationConfig = $this->_loadedProfile->search('ApplicationConfigFile'); - $applicationConfig->addItem($dbConfigValues, $this->_sectionName, null); - - $response = $this->_registry->getResponse(); - - if ($isPretend) { - $response->appendContent('A db configuration for the ' . $this->_sectionName - . ' section would be written to the application config file with the following contents: ' - ); - $response->appendContent($applicationConfig->getContents()); - } else { - $applicationConfig->create(); - $response->appendContent('A db configuration for the ' . $this->_sectionName - . ' section has been written to the application config file.' - ); - } - } - - protected function _cleanMagicQuotesInValues(&$value, $key) - { - $value = stripslashes($value); - } - -} diff --git a/lib/Zend/Tool/Project/Provider/DbTable.php b/lib/Zend/Tool/Project/Provider/DbTable.php deleted file mode 100644 index 9996f8b6b9f..00000000000 --- a/lib/Zend/Tool/Project/Provider/DbTable.php +++ /dev/null @@ -1,225 +0,0 @@ - array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'modelsDirectory'; - - $modelsDirectory = $profile->search($profileSearchParams); - - if (!($modelsDirectory instanceof Zend_Tool_Project_Profile_Resource)) { - throw new Zend_Tool_Project_Provider_Exception( - 'A models directory was not found' . - (($moduleName) ? ' for module ' . $moduleName . '.' : '.') - ); - } - - if (!($dbTableDirectory = $modelsDirectory->search('DbTableDirectory'))) { - $dbTableDirectory = $modelsDirectory->createResource('DbTableDirectory'); - } - - $dbTableFile = $dbTableDirectory->createResource('DbTableFile', array('dbTableName' => $dbTableName, 'actualTableName' => $actualTableName)); - - return $dbTableFile; - } - - public static function hasResource(Zend_Tool_Project_Profile $profile, $dbTableName, $moduleName = null) - { - $profileSearchParams = array(); - - if ($moduleName != null && is_string($moduleName)) { - $profileSearchParams = array('modulesDirectory', 'moduleDirectory' => array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'modelsDirectory'; - - $modelsDirectory = $profile->search($profileSearchParams); - - if (!($modelsDirectory instanceof Zend_Tool_Project_Profile_Resource) - || !($dbTableDirectory = $modelsDirectory->search('DbTableDirectory'))) { - return false; - } - - $dbTableFile = $dbTableDirectory->search(array('DbTableFile' => array('dbTableName' => $dbTableName))); - - return ($dbTableFile instanceof Zend_Tool_Project_Profile_Resource) ? true : false; - } - - - public function create($name, $actualTableName, $module = null, $forceOverwrite = false) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - // Check that there is not a dash or underscore, return if doesnt match regex - if (preg_match('#[_-]#', $name)) { - throw new Zend_Tool_Project_Provider_Exception('DbTable names should be camel cased.'); - } - - $originalName = $name; - $name = ucfirst($name); - - if ($actualTableName == '') { - throw new Zend_Tool_Project_Provider_Exception('You must provide both the DbTable name as well as the actual db table\'s name.'); - } - - if (self::hasResource($this->_loadedProfile, $name, $module)) { - throw new Zend_Tool_Project_Provider_Exception('This project already has a DbTable named ' . $name); - } - - // get request/response object - $request = $this->_registry->getRequest(); - $response = $this->_registry->getResponse(); - - // alert the user about inline converted names - $tense = (($request->isPretend()) ? 'would be' : 'is'); - - if ($name !== $originalName) { - $response->appendContent( - 'Note: The canonical model name that ' . $tense - . ' used with other providers is "' . $name . '";' - . ' not "' . $originalName . '" as supplied', - array('color' => array('yellow')) - ); - } - - try { - $tableResource = self::createResource($this->_loadedProfile, $name, $actualTableName, $module); - } catch (Exception $e) { - $response = $this->_registry->getResponse(); - $response->setException($e); - return; - } - - // do the creation - if ($request->isPretend()) { - $response->appendContent('Would create a DbTable at ' . $tableResource->getContext()->getPath()); - } else { - $response->appendContent('Creating a DbTable at ' . $tableResource->getContext()->getPath()); - $tableResource->create(); - $this->_storeProfile(); - } - } - - /** - * @param string $module Module name action should be applied to. - * @param bool $forceOverwrite Whether should force overwriting previous classes generated - * @return void - */ - public function createFromDatabase($module = null, $forceOverwrite = false) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $bootstrapResource = $this->_loadedProfile->search('BootstrapFile'); - - /* @var $zendApp Zend_Application */ - $zendApp = $bootstrapResource->getApplicationInstance(); - - try { - $zendApp->bootstrap('db'); - } catch (Zend_Application_Exception $e) { - throw new Zend_Tool_Project_Provider_Exception('Db resource not available, you might need to configure a DbAdapter.'); - return; - } - - /* @var $db Zend_Db_Adapter_Abstract */ - $db = $zendApp->getBootstrap()->getResource('db'); - - $tableResources = array(); - foreach ($db->listTables() as $actualTableName) { - - $dbTableName = $this->_convertTableNameToClassName($actualTableName); - - if (!$forceOverwrite && self::hasResource($this->_loadedProfile, $dbTableName, $module)) { - throw new Zend_Tool_Project_Provider_Exception( - 'This DbTable resource already exists, if you wish to overwrite it, ' - . 'pass the "forceOverwrite" flag to this provider.' - ); - } - - $tableResources[] = self::createResource( - $this->_loadedProfile, - $dbTableName, - $actualTableName, - $module - ); - } - - if (count($tableResources) == 0) { - $this->_registry->getResponse()->appendContent('There are no tables in the selected database to write.'); - } - - // do the creation - if ($this->_registry->getRequest()->isPretend()) { - - foreach ($tableResources as $tableResource) { - $this->_registry->getResponse()->appendContent('Would create a DbTable at ' . $tableResource->getContext()->getPath()); - } - - } else { - - foreach ($tableResources as $tableResource) { - $this->_registry->getResponse()->appendContent('Creating a DbTable at ' . $tableResource->getContext()->getPath()); - $tableResource->create(); - } - - $this->_storeProfile(); - } - - - } - - protected function _convertTableNameToClassName($tableName) - { - if ($this->_nameFilter == null) { - $this->_nameFilter = new Zend_Filter(); - $this->_nameFilter - ->addFilter(new Zend_Filter_Word_UnderscoreToCamelCase()); - } - - return $this->_nameFilter->filter($tableName); - } - -} diff --git a/lib/Zend/Tool/Project/Provider/Exception.php b/lib/Zend/Tool/Project/Provider/Exception.php deleted file mode 100644 index d7c6ad7a6a0..00000000000 --- a/lib/Zend/Tool/Project/Provider/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -createResource( - 'formFile', - array('formName' => $formName, 'moduleName' => $moduleName) - ); - - return $newForm; - } - - /** - * hasResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $formName - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - public static function hasResource(Zend_Tool_Project_Profile $profile, $formName, $moduleName = null) - { - if (!is_string($formName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_Form::createResource() expects \"formName\" is the name of a form resource to check for existence.'); - } - - $formsDirectory = self::_getFormsDirectoryResource($profile, $moduleName); - return (($formsDirectory->search(array('formFile' => array('formName' => $formName)))) instanceof Zend_Tool_Project_Profile_Resource); - } - - /** - * _getFormsDirectoryResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - protected static function _getFormsDirectoryResource(Zend_Tool_Project_Profile $profile, $moduleName = null) - { - $profileSearchParams = array(); - - if ($moduleName != null && is_string($moduleName)) { - $profileSearchParams = array('modulesDirectory', 'moduleDirectory' => array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'formsDirectory'; - - return $profile->search($profileSearchParams); - } - - public function enable($module = null) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - // determine if testing is enabled in the project - $testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - - $formDirectoryResource = self::_getFormsDirectoryResource($this->_loadedProfile, $module); - - if ($formDirectoryResource->isEnabled()) { - throw new Zend_Tool_Project_Provider_Exception('This project already has forms enabled.'); - } else { - if ($this->_registry->getRequest()->isPretend()) { - $this->_registry->getResponse()->appendContent('Would enable forms directory at ' . $formDirectoryResource->getContext()->getPath()); - } else { - $this->_registry->getResponse()->appendContent('Enabling forms directory at ' . $formDirectoryResource->getContext()->getPath()); - $formDirectoryResource->setEnabled(true); - $formDirectoryResource->create(); - $this->_storeProfile(); - } - - } - } - - /** - * Create a new form - * - * @param string $name - * @param string $module - */ - public function create($name, $module = null) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - // determine if testing is enabled in the project - $testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - - if (self::hasResource($this->_loadedProfile, $name, $module)) { - throw new Zend_Tool_Project_Provider_Exception('This project already has a form named ' . $name); - } - - // Check that there is not a dash or underscore, return if doesnt match regex - if (preg_match('#[_-]#', $name)) { - throw new Zend_Tool_Project_Provider_Exception('Form names should be camel cased.'); - } - - $name = ucwords($name); - - try { - $formResource = self::createResource($this->_loadedProfile, $name, $module); - - if ($testingEnabled) { - $testFormResource = null; - // $testFormResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $name, 'index', $module); - } - - } catch (Exception $e) { - $response = $this->_registry->getResponse(); - $response->setException($e); - return; - } - - // do the creation - if ($this->_registry->getRequest()->isPretend()) { - - $this->_registry->getResponse()->appendContent('Would create a form at ' . $formResource->getContext()->getPath()); - - if ($testFormResource) { - $this->_registry->getResponse()->appendContent('Would create a form test file at ' . $testFormResource->getContext()->getPath()); - } - - } else { - - $this->_registry->getResponse()->appendContent('Creating a form at ' . $formResource->getContext()->getPath()); - $formResource->create(); - - if ($testFormResource) { - $this->_registry->getResponse()->appendContent('Creating a form test file at ' . $testFormResource->getContext()->getPath()); - $testFormResource->create(); - } - - $this->_storeProfile(); - } - - } - - -} diff --git a/lib/Zend/Tool/Project/Provider/Layout.php b/lib/Zend/Tool/Project/Provider/Layout.php deleted file mode 100644 index b0d0c20231e..00000000000 --- a/lib/Zend/Tool/Project/Provider/Layout.php +++ /dev/null @@ -1,140 +0,0 @@ -search('applicationDirectory'); - $layoutDirectory = $applicationDirectory->search('layoutsDirectory'); - - if ($layoutDirectory == false) { - $layoutDirectory = $applicationDirectory->createResource('layoutsDirectory'); - } - - $layoutScriptsDirectory = $layoutDirectory->search('layoutScriptsDirectory'); - - if ($layoutScriptsDirectory == false) { - $layoutScriptsDirectory = $layoutDirectory->createResource('layoutScriptsDirectory'); - } - - $layoutScriptFile = $layoutScriptsDirectory->search('layoutScriptFile', array('layoutName' => 'layout')); - - if ($layoutScriptFile == false) { - $layoutScriptFile = $layoutScriptsDirectory->createResource('layoutScriptFile', array('layoutName' => 'layout')); - } - - return $layoutScriptFile; - } - - public function enable() - { - $profile = $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $applicationConfigResource = $profile->search('ApplicationConfigFile'); - - if (!$applicationConfigResource) { - throw new Zend_Tool_Project_Exception('A project with an application config file is required to use this provider.'); - } - - $zc = $applicationConfigResource->getAsZendConfig(); - - if (isset($zc->resources) && isset($zc->resources->layout)) { - $this->_registry->getResponse()->appendContent('A layout resource already exists in this project\'s application configuration file.'); - return; - } - - if ($this->_registry->getRequest()->isPretend()) { - $this->_registry->getResponse()->appendContent('Would add "resources.layout.layoutPath" key to the application config file.'); - } else { - $applicationConfigResource->addStringItem('resources.layout.layoutPath', $this->_layoutPath, 'production', false); - $applicationConfigResource->create(); - - $this->_registry->getResponse()->appendContent('A layout entry has been added to the application config file.'); - - $layoutScriptFile = self::createResource($profile); - if (!$layoutScriptFile->exists()) { - $layoutScriptFile->create(); - $this->_registry->getResponse()->appendContent( - 'A default layout has been created at ' - . $layoutScriptFile->getPath() - ); - - } - - $this->_storeProfile(); - } - } - - public function disable() - { - $profile = $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $applicationConfigResource = $this->_getApplicationConfigResource($profile); - $zc = $applicationConfigResource->getAsZendConfig(); - - if (isset($zc->resources) && !isset($zc->resources->layout)) { - $this->_registry->getResponse()->appendContent('No layout configuration exists in application config file.'); - return; - } - - if ($this->_registry->getRequest()->isPretend()) { - $this->_registry->getResponse()->appendContent('Would remove "resources.layout.layoutPath" key from the application config file.'); - } else { - - // Remove the resources.layout.layoutPath directive from application config - $applicationConfigResource->removeStringItem('resources.layout.layoutPath', $this->_layoutPath, 'production', false); - $applicationConfigResource->create(); - - // Tell the user about the good work we've done - $this->_registry->getResponse()->appendContent('Layout entry has been removed from the application config file.'); - - $this->_storeProfile(); - } - } - - protected function _getApplicationConfigResource(Zend_Tool_Project_Profile $profile) - { - $applicationConfigResource = $profile->search('ApplicationConfigFile'); - if (!$applicationConfigResource) { - throw new Zend_Tool_Project_Exception('A project with an application config file is required to use this provider.'); - } - - return $applicationConfigResource; - } -} diff --git a/lib/Zend/Tool/Project/Provider/Manifest.php b/lib/Zend/Tool/Project/Provider/Manifest.php deleted file mode 100644 index 4ca948acdbc..00000000000 --- a/lib/Zend/Tool/Project/Provider/Manifest.php +++ /dev/null @@ -1,75 +0,0 @@ -createResource( - 'modelFile', - array('modelName' => $modelName, 'moduleName' => $moduleName) - ); - - return $newModel; - } - - /** - * hasResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $modelName - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - public static function hasResource(Zend_Tool_Project_Profile $profile, $modelName, $moduleName = null) - { - if (!is_string($modelName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_Model::createResource() expects \"modelName\" is the name of a model resource to check for existence.'); - } - - $modelsDirectory = self::_getModelsDirectoryResource($profile, $moduleName); - - if (!$modelsDirectory instanceof Zend_Tool_Project_Profile_Resource) { - return false; - } - - return (($modelsDirectory->search(array('modelFile' => array('modelName' => $modelName)))) instanceof Zend_Tool_Project_Profile_Resource); - } - - /** - * _getModelsDirectoryResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - protected static function _getModelsDirectoryResource(Zend_Tool_Project_Profile $profile, $moduleName = null) - { - $profileSearchParams = array(); - - if ($moduleName != null && is_string($moduleName)) { - $profileSearchParams = array('modulesDirectory', 'moduleDirectory' => array('moduleName' => $moduleName)); - } - - $profileSearchParams[] = 'modelsDirectory'; - - return $profile->search($profileSearchParams); - } - - /** - * Create a new model - * - * @param string $name - * @param string $module - */ - public function create($name, $module = null) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - $originalName = $name; - - $name = ucwords($name); - - // determine if testing is enabled in the project - $testingEnabled = false; //Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - $testModelResource = null; - - // Check that there is not a dash or underscore, return if doesnt match regex - if (preg_match('#[_-]#', $name)) { - throw new Zend_Tool_Project_Provider_Exception('Model names should be camel cased.'); - } - - if (self::hasResource($this->_loadedProfile, $name, $module)) { - throw new Zend_Tool_Project_Provider_Exception('This project already has a model named ' . $name); - } - - // get request/response object - $request = $this->_registry->getRequest(); - $response = $this->_registry->getResponse(); - - // alert the user about inline converted names - $tense = (($request->isPretend()) ? 'would be' : 'is'); - - if ($name !== $originalName) { - $response->appendContent( - 'Note: The canonical model name that ' . $tense - . ' used with other providers is "' . $name . '";' - . ' not "' . $originalName . '" as supplied', - array('color' => array('yellow')) - ); - } - - try { - $modelResource = self::createResource($this->_loadedProfile, $name, $module); - - if ($testingEnabled) { - // $testModelResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $name, 'index', $module); - } - - } catch (Exception $e) { - $response->setException($e); - return; - } - - // do the creation - if ($request->isPretend()) { - - $response->appendContent('Would create a model at ' . $modelResource->getContext()->getPath()); - - if ($testModelResource) { - $response->appendContent('Would create a model test file at ' . $testModelResource->getContext()->getPath()); - } - - } else { - - $response->appendContent('Creating a model at ' . $modelResource->getContext()->getPath()); - $modelResource->create(); - - if ($testModelResource) { - $response->appendContent('Creating a model test file at ' . $testModelResource->getContext()->getPath()); - $testModelResource->create(); - } - - $this->_storeProfile(); - } - - } - - -} diff --git a/lib/Zend/Tool/Project/Provider/Module.php b/lib/Zend/Tool/Project/Provider/Module.php deleted file mode 100644 index 4405bc8a1a2..00000000000 --- a/lib/Zend/Tool/Project/Provider/Module.php +++ /dev/null @@ -1,181 +0,0 @@ -search('applicationDirectory'); - $targetModuleEnabledResources = array( - 'ControllersDirectory', 'ModelsDirectory', 'ViewsDirectory', - 'ViewScriptsDirectory', 'ViewHelpersDirectory', 'ViewFiltersDirectory' - ); - } - - // find the actual modules directory we will use to house our module - $modulesDirectory = $profile->search('modulesDirectory'); - - // if there is a module directory already, except - if ($modulesDirectory->search(array('moduleDirectory' => array('moduleName' => $moduleName)))) { - throw new Zend_Tool_Project_Provider_Exception('A module named "' . $moduleName . '" already exists.'); - } - - // create the module directory - $moduleDirectory = $modulesDirectory->createResource('moduleDirectory', array('moduleName' => $moduleName)); - - // create a context filter so that we can pull out only what we need from the module skeleton - $moduleContextFilterIterator = new Zend_Tool_Project_Profile_Iterator_ContextFilter( - $targetModuleResource, - array( - 'denyNames' => array('ModulesDirectory', 'ViewControllerScriptsDirectory'), - 'denyType' => 'Zend_Tool_Project_Context_Filesystem_File' - ) - ); - - // the iterator for the module skeleton - $targetIterator = new RecursiveIteratorIterator($moduleContextFilterIterator, RecursiveIteratorIterator::SELF_FIRST); - - // initialize some loop state information - $currentDepth = 0; - $parentResources = array(); - $currentResource = $moduleDirectory; - - // loop through the target module skeleton - foreach ($targetIterator as $targetSubResource) { - - $depthDifference = $targetIterator->getDepth() - $currentDepth; - $currentDepth = $targetIterator->getDepth(); - - if ($depthDifference === 1) { - // if we went down into a child, make note - array_push($parentResources, $currentResource); - // this will have always been set previously by another loop - $currentResource = $currentChildResource; - } elseif ($depthDifference < 0) { - // if we went up to a parent, make note - $i = $depthDifference; - do { - // if we went out more than 1 parent, get to the correct parent - $currentResource = array_pop($parentResources); - } while ($i-- > 0); - } - - // get parameters for the newly created module resource - $params = $targetSubResource->getAttributes(); - $currentChildResource = $currentResource->createResource($targetSubResource->getName(), $params); - - // based of the provided list (Currently up top), enable specific resources - if (isset($targetModuleEnabledResources)) { - $currentChildResource->setEnabled(in_array($targetSubResource->getName(), $targetModuleEnabledResources)); - } else { - $currentChildResource->setEnabled($targetSubResource->isEnabled()); - } - - } - - return $moduleDirectory; - } - - /** - * create() - * - * @param string $name - */ - public function create($name) //, $moduleProfile = null) - { - $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); - - // determine if testing is enabled in the project - #require_once 'Zend/Tool/Project/Provider/Test.php'; - //$testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile); - - $resources = self::createResources($this->_loadedProfile, $name); - - $response = $this->_registry->getResponse(); - - if ($this->_registry->getRequest()->isPretend()) { - $response->appendContent('I would create the following module and artifacts:'); - foreach (new RecursiveIteratorIterator($resources, RecursiveIteratorIterator::SELF_FIRST) as $resource) { - if (is_callable(array($resource->getContext(), 'getPath'))) { - $response->appendContent($resource->getContext()->getPath()); - } - } - } else { - $response->appendContent('Creating the following module and artifacts:'); - $enabledFilter = new Zend_Tool_Project_Profile_Iterator_EnabledResourceFilter($resources); - foreach (new RecursiveIteratorIterator($enabledFilter, RecursiveIteratorIterator::SELF_FIRST) as $resource) { - $response->appendContent($resource->getContext()->getPath()); - $resource->create(); - } - - $response->appendContent('Added a key for path module directory to the application.ini file'); - $appConfigFile = $this->_loadedProfile->search('ApplicationConfigFile'); - $appConfigFile->removeStringItem('resources.frontController.moduleDirectory', 'production'); - $appConfigFile->addStringItem('resources.frontController.moduleDirectory', 'APPLICATION_PATH "/modules"', 'production', false); - - if (strtolower($name) == 'default') { - $response->appendContent('Added a key for the default module to the application.ini file'); - $appConfigFile->addStringItem('resources.frontController.params.prefixDefaultModule', '1', 'production'); - } - - $appConfigFile->create(); - - // store changes to the profile - $this->_storeProfile(); - } - - } - -} - diff --git a/lib/Zend/Tool/Project/Provider/Profile.php b/lib/Zend/Tool/Project/Provider/Profile.php deleted file mode 100644 index ecdf7ddc02a..00000000000 --- a/lib/Zend/Tool/Project/Provider/Profile.php +++ /dev/null @@ -1,54 +0,0 @@ -_loadProfile(); - - $profileIterator = $this->_loadedProfile->getIterator(); - - foreach ($profileIterator as $profileItem) { - $this->_registry->getResponse()->appendContent( - str_repeat(' ', $profileIterator->getDepth()) . $profileItem - ); - } - - } -} diff --git a/lib/Zend/Tool/Project/Provider/Project.php b/lib/Zend/Tool/Project/Provider/Project.php deleted file mode 100644 index f148983d1d7..00000000000 --- a/lib/Zend/Tool/Project/Provider/Project.php +++ /dev/null @@ -1,254 +0,0 @@ -_loadProfile(self::NO_PROFILE_RETURN_FALSE, $path); - - if ($profile !== false) { - #require_once 'Zend/Tool/Framework/Client/Exception.php'; - throw new Zend_Tool_Framework_Client_Exception('A project already exists here'); - } - - $profileData = null; - - if ($fileOfProfile != null && file_exists($fileOfProfile)) { - $profileData = file_get_contents($fileOfProfile); - } - - $storage = $this->_registry->getStorage(); - if ($profileData == '' && $nameOfProfile != null && $storage->isEnabled()) { - $profileData = $storage->get('project/profiles/' . $nameOfProfile . '.xml'); - } - - if ($profileData == '') { - $profileData = $this->_getDefaultProfile(); - } - - $newProfile = new Zend_Tool_Project_Profile(array( - 'projectDirectory' => $path, - 'profileData' => $profileData - )); - - $newProfile->loadFromData(); - - $response = $this->_registry->getResponse(); - - $response->appendContent('Creating project at ' . $path); - $response->appendContent('Note: ', array('separator' => false, 'color' => 'yellow')); - $response->appendContent( - 'This command created a web project, ' - . 'for more information setting up your VHOST, please see docs/README'); - - if (!Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) { - $response->appendContent('Testing Note: ', array('separator' => false, 'color' => 'yellow')); - $response->appendContent('PHPUnit was not found in your include_path, therefore no testing actions will be created.'); - } - - foreach ($newProfile->getIterator() as $resource) { - $resource->create(); - } - } - - public function show() - { - $this->_registry->getResponse()->appendContent('You probably meant to run "show project.info".', array('color' => 'yellow')); - } - - public function showInfo() - { - $profile = $this->_loadProfile(self::NO_PROFILE_RETURN_FALSE); - if (!$profile) { - $this->_registry->getResponse()->appendContent('No project found.'); - } else { - $this->_registry->getResponse()->appendContent('Working with project located at: ' . $profile->getAttribute('projectDirectory')); - } - } - - protected function _getDefaultProfile() - { - $testAction = ''; - if (Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) { - $testAction = ' '; - } - - $version = Zend_Version::VERSION; - - $data = << - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$testAction - - - - - - - -EOS; - return $data; - } - - public static function getDefaultReadmeContents($caller = null) - { - $projectDirResource = $caller->getResource()->getProfile()->search('projectDirectory'); - if ($projectDirResource) { - $name = ltrim(strrchr($projectDirResource->getPath(), DIRECTORY_SEPARATOR), DIRECTORY_SEPARATOR); - $path = $projectDirResource->getPath() . '/public'; - } else { - $path = '/path/to/public'; - } - - return <<< EOS -README -====== - -This directory should be used to place project specfic documentation including -but not limited to project notes, generated API/phpdoc documentation, or -manual files generated or hand written. Ideally, this directory would remain -in your development environment only and should not be deployed with your -application to it's final production location. - - -Setting Up Your VHOST -===================== - -The following is a sample VHOST you might want to consider for your project. - - - DocumentRoot "$path" - ServerName $name.local - - # This should be omitted in the production environment - SetEnv APPLICATION_ENV development - - - Options Indexes MultiViews FollowSymLinks - AllowOverride All - Order allow,deny - Allow from all - - - - -EOS; - } -} diff --git a/lib/Zend/Tool/Project/Provider/ProjectProvider.php b/lib/Zend/Tool/Project/Provider/ProjectProvider.php deleted file mode 100644 index 54a3dd46da5..00000000000 --- a/lib/Zend/Tool/Project/Provider/ProjectProvider.php +++ /dev/null @@ -1,97 +0,0 @@ -createResourceAt($profileSearchParams, 'projectProviderFile', array('projectProviderName' => $projectProviderName, 'actionNames' => $actionNames)); - - return $projectProvider; - } - - /** - * getName() - * - * @return string - */ - public function getName() - { - return 'ProjectProvider'; - } - - /** - * Create stub for Zend_Tool Project Provider - * - * @var string $name class name for new Zend_Tool Project Provider - * @var array|string $actions list of provider methods - * @throws Zend_Tool_Project_Provider_Exception - */ - public function create($name, $actions = null) - { - $profile = $this->_loadProfileRequired(); - - $projectProvider = self::createResource($profile, $name, $actions); - - if ($this->_registry->getRequest()->isPretend()) { - $this->_registry->getResponse()->appendContent('Would create a project provider named ' . $name - . ' in location ' . $projectProvider->getPath() - ); - } else { - $this->_registry->getResponse()->appendContent('Creating a project provider named ' . $name - . ' in location ' . $projectProvider->getPath() - ); - $projectProvider->create(); - $this->_storeProfile(); - } - - } -} diff --git a/lib/Zend/Tool/Project/Provider/Test.php b/lib/Zend/Tool/Project/Provider/Test.php deleted file mode 100644 index 768e9e9bff0..00000000000 --- a/lib/Zend/Tool/Project/Provider/Test.php +++ /dev/null @@ -1,198 +0,0 @@ -search($profileSearchParams); - - return $testsDirectory->isEnabled(); - } - - public static function isPHPUnitAvailable() - { - if (class_exists('PHPUnit_Runner_Version', false)) { - return true; - } - - $included = @include 'PHPUnit/Runner/Version.php'; - - if ($included === false) { - return false; - } else { - return true; - } - } - - /** - * createApplicationResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $controllerName - * @param string $actionName - * @param string $moduleName - * @return Zend_Tool_Project_Profile_Resource - */ - public static function createApplicationResource(Zend_Tool_Project_Profile $profile, $controllerName, $actionName, $moduleName = null) - { - if (!is_string($controllerName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_View::createApplicationResource() expects \"controllerName\" is the name of a controller resource to create.'); - } - - if (!is_string($actionName)) { - throw new Zend_Tool_Project_Provider_Exception('Zend_Tool_Project_Provider_View::createApplicationResource() expects \"actionName\" is the name of a controller resource to create.'); - } - - $testsDirectoryResource = $profile->search('testsDirectory'); - - // parentOfController could either be application/ or a particular module folder, which is why we use this name - if (($testParentOfControllerDirectoryResource = $testsDirectoryResource->search('testApplicationDirectory')) === false) { - $testParentOfControllerDirectoryResource = $testsDirectoryResource->createResource('testApplicationDirectory'); - } - - if ($moduleName) { - if (($testAppModulesDirectoryResource = $testParentOfControllerDirectoryResource->search('testApplicationModulesDirectory')) === false) { - $testAppModulesDirectoryResource = $testParentOfControllerDirectoryResource->createResource('testApplicationModulesDirectory'); - } - - if (($testAppModuleDirectoryResource = $testAppModulesDirectoryResource->search(array('testApplicationModuleDirectory' => array('forModuleName' => $moduleName)))) === false) { - $testAppModuleDirectoryResource = $testAppModulesDirectoryResource->createResource('testApplicationModuleDirectory', array('forModuleName' => $moduleName)); - } - - $testParentOfControllerDirectoryResource = $testAppModuleDirectoryResource; - } - - if (($testAppControllerDirectoryResource = $testParentOfControllerDirectoryResource->search('testApplicationControllerDirectory', 'testApplicationModuleDirectory')) === false) { - $testAppControllerDirectoryResource = $testParentOfControllerDirectoryResource->createResource('testApplicationControllerDirectory'); - } - - if (($testAppControllerFileResource = $testAppControllerDirectoryResource->search(array('testApplicationControllerFile' => array('forControllerName' => $controllerName)))) === false) { - $testAppControllerFileResource = $testAppControllerDirectoryResource->createResource('testApplicationControllerFile', array('forControllerName' => $controllerName)); - } - - return $testAppControllerFileResource->createResource('testApplicationActionMethod', array('forActionName' => $actionName)); - } - - /** - * createLibraryResource() - * - * @param Zend_Tool_Project_Profile $profile - * @param string $libraryClassName - * @return Zend_Tool_Project_Profile_Resource - */ - public static function createLibraryResource(Zend_Tool_Project_Profile $profile, $libraryClassName) - { - $testLibraryDirectoryResource = $profile->search(array('TestsDirectory', 'TestLibraryDirectory')); - - - $fsParts = explode('_', $libraryClassName); - - $currentDirectoryResource = $testLibraryDirectoryResource; - - while ($nameOrNamespacePart = array_shift($fsParts)) { - - if (count($fsParts) > 0) { - - if (($libraryDirectoryResource = $currentDirectoryResource->search(array('TestLibraryNamespaceDirectory' => array('namespaceName' => $nameOrNamespacePart)))) === false) { - $currentDirectoryResource = $currentDirectoryResource->createResource('TestLibraryNamespaceDirectory', array('namespaceName' => $nameOrNamespacePart)); - } else { - $currentDirectoryResource = $libraryDirectoryResource; - } - - } else { - - if (($libraryFileResource = $currentDirectoryResource->search(array('TestLibraryFile' => array('forClassName' => $libraryClassName)))) === false) { - $libraryFileResource = $currentDirectoryResource->createResource('TestLibraryFile', array('forClassName' => $libraryClassName)); - } - - } - - } - - return $libraryFileResource; - } - - public function enable() - { - - } - - public function disable() - { - - } - - /** - * create() - * - * @param string $libraryClassName - */ - public function create($libraryClassName) - { - $profile = $this->_loadProfile(); - - if (!self::isTestingEnabled($profile)) { - $this->_registry->getResponse()->appendContent('Testing is not enabled for this project.'); - } - - $testLibraryResource = self::createLibraryResource($profile, $libraryClassName); - - $response = $this->_registry->getResponse(); - - if ($this->_registry->getRequest()->isPretend()) { - $response->appendContent('Would create a library stub in location ' . $testLibraryResource->getContext()->getPath()); - } else { - $response->appendContent('Creating a library stub in location ' . $testLibraryResource->getContext()->getPath()); - $testLibraryResource->create(); - $this->_storeProfile(); - } - - } - -} diff --git a/lib/Zend/Tool/Project/Provider/View.php b/lib/Zend/Tool/Project/Provider/View.php deleted file mode 100644 index 9bb0d684b8c..00000000000 --- a/lib/Zend/Tool/Project/Provider/View.php +++ /dev/null @@ -1,118 +0,0 @@ - array('moduleName' => $moduleName)); - $noModuleSearch = null; - } else { - $noModuleSearch = array('modulesDirectory'); - } - - $profileSearchParams[] = 'viewsDirectory'; - $profileSearchParams[] = 'viewScriptsDirectory'; - - if (($viewScriptsDirectory = $profile->search($profileSearchParams, $noModuleSearch)) === false) { - #require_once 'Zend/Tool/Project/Provider/Exception.php'; - throw new Zend_Tool_Project_Provider_Exception('This project does not have a viewScriptsDirectory resource.'); - } - - $profileSearchParams['viewControllerScriptsDirectory'] = array('forControllerName' => $controllerName); - - // @todo check if below is failing b/c of above search params - if (($viewControllerScriptsDirectory = $viewScriptsDirectory->search($profileSearchParams)) === false) { - $viewControllerScriptsDirectory = $viewScriptsDirectory->createResource('viewControllerScriptsDirectory', array('forControllerName' => $controllerName)); - } - - $newViewScriptFile = $viewControllerScriptsDirectory->createResource('ViewScriptFile', array('forActionName' => $actionName)); - - return $newViewScriptFile; - } - - /** - * create() - * - * @param string $controllerName - * @param string $actionNameOrSimpleName - */ - public function create($controllerName, $actionNameOrSimpleName, $module = null) - { - - if ($controllerName == '' || $actionNameOrSimpleName == '') { - #require_once 'Zend/Tool/Project/Provider/Exception.php'; - throw new Zend_Tool_Project_Provider_Exception('ControllerName and/or ActionName are empty.'); - } - - $profile = $this->_loadProfile(); - - $view = self::createResource($profile, $actionNameOrSimpleName, $controllerName, $module); - - if ($this->_registry->getRequest()->isPretend()) { - $this->_registry->getResponse( - 'Would create a view script in location ' . $view->getContext()->getPath() - ); - } else { - $this->_registry->getResponse( - 'Creating a view script in location ' . $view->getContext()->getPath() - ); - $view->create(); - $this->_storeProfile(); - } - - } -} diff --git a/lib/Zend/Translate.php b/lib/Zend/Translate.php deleted file mode 100644 index baf99d0f8e5..00000000000 --- a/lib/Zend/Translate.php +++ /dev/null @@ -1,224 +0,0 @@ -toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options = array(); - $options['adapter'] = array_shift($args); - if (!empty($args)) { - $options['content'] = array_shift($args); - } - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $opt = array_shift($args); - $options = array_merge($opt, $options); - } - } else if (!is_array($options)) { - $options = array('adapter' => $options); - } - - $this->setAdapter($options); - } - - /** - * Sets a new adapter - * - * @param array|Zend_Config|Zend_Translate_Adapter $options Options to use - * @param string|array [$content] Path to content, or content itself - * @param string|Zend_Locale [$locale] - * @throws Zend_Translate_Exception - */ - public function setAdapter($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options = array(); - $options['adapter'] = array_shift($args); - if (!empty($args)) { - $options['content'] = array_shift($args); - } - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $opt = array_shift($args); - $options = array_merge($opt, $options); - } - } else if (!is_array($options)) { - $options = array('adapter' => $options); - } - - if (Zend_Loader::isReadable('Zend/Translate/Adapter/' . ucfirst($options['adapter']). '.php')) { - $options['adapter'] = 'Zend_Translate_Adapter_' . ucfirst($options['adapter']); - } - - if (!class_exists($options['adapter'])) { - Zend_Loader::loadClass($options['adapter']); - } - - if (array_key_exists('cache', $options)) { - Zend_Translate_Adapter::setCache($options['cache']); - } - - $adapter = $options['adapter']; - unset($options['adapter']); - $this->_adapter = new $adapter($options); - if (!$this->_adapter instanceof Zend_Translate_Adapter) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("Adapter " . $adapter . " does not extend Zend_Translate_Adapter"); - } - } - - /** - * Returns the adapters name and it's options - * - * @return Zend_Translate_Adapter - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Returns the set cache - * - * @return Zend_Cache_Core The set cache - */ - public static function getCache() - { - return Zend_Translate_Adapter::getCache(); - } - - /** - * Sets a cache for all instances of Zend_Translate - * - * @param Zend_Cache_Core $cache Cache to store to - * @return void - */ - public static function setCache(Zend_Cache_Core $cache) - { - Zend_Translate_Adapter::setCache($cache); - } - - /** - * Returns true when a cache is set - * - * @return boolean - */ - public static function hasCache() - { - return Zend_Translate_Adapter::hasCache(); - } - - /** - * Removes any set cache - * - * @return void - */ - public static function removeCache() - { - Zend_Translate_Adapter::removeCache(); - } - - /** - * Clears all set cache data - * - * @param string $tag Tag to clear when the default tag name is not used - * @return void - */ - public static function clearCache($tag = null) - { - Zend_Translate_Adapter::clearCache($tag); - } - - /** - * Calls all methods from the adapter - */ - public function __call($method, array $options) - { - if (method_exists($this->_adapter, $method)) { - return call_user_func_array(array($this->_adapter, $method), $options); - } - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("Unknown method '" . $method . "' called!"); - } -} diff --git a/lib/Zend/Translate/Adapter.php b/lib/Zend/Translate/Adapter.php deleted file mode 100644 index 1a7dbb90d7c..00000000000 --- a/lib/Zend/Translate/Adapter.php +++ /dev/null @@ -1,997 +0,0 @@ - when true, clears already loaded translations when adding new files - * 'content' => content to translate or file or directory with content - * 'disableNotices' => when true, omits notices from being displayed - * 'ignore' => a prefix for files and directories which are not being added - * 'locale' => the actual set locale to use - * 'log' => a instance of Zend_Log where logs are written to - * 'logMessage' => message to be logged - * 'logPriority' => priority which is used to write the log message - * 'logUntranslated' => when true, untranslated messages are not logged - * 'reload' => reloads the cache by reading the content again - * 'scan' => searches for translation files using the LOCALE constants - * 'tag' => tag to use for the cache - * - * @var array - */ - protected $_options = array( - 'clear' => false, - 'content' => null, - 'disableNotices' => false, - 'ignore' => '.', - 'locale' => 'auto', - 'log' => null, - 'logMessage' => "Untranslated message within '%locale%': %message%", - 'logPriority' => 5, - 'logUntranslated' => false, - 'reload' => false, - 'route' => null, - 'scan' => null, - 'tag' => 'Zend_Translate' - ); - - /** - * Translation table - * @var array - */ - protected $_translate = array(); - - /** - * Generates the adapter - * - * @param string|array|Zend_Config $options Translation options for this adapter - * @param string|array [$content] - * @param string|Zend_Locale [$locale] - * @throws Zend_Translate_Exception - * @return void - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options = array(); - $options['content'] = array_shift($args); - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $opt = array_shift($args); - $options = array_merge($opt, $options); - } - } else if (!is_array($options)) { - $options = array('content' => $options); - } - - if (array_key_exists('cache', $options)) { - self::setCache($options['cache']); - unset($options['cache']); - } - - if (isset(self::$_cache)) { - $id = 'Zend_Translate_' . $this->toString() . '_Options'; - $result = self::$_cache->load($id); - if ($result) { - $this->_options = $result; - } - } - - if (empty($options['locale']) || ($options['locale'] === "auto")) { - $this->_automatic = true; - } else { - $this->_automatic = false; - } - - $locale = null; - if (!empty($options['locale'])) { - $locale = $options['locale']; - unset($options['locale']); - } - - $this->setOptions($options); - $options['locale'] = $locale; - - if (!empty($options['content'])) { - $this->addTranslation($options); - } - - if ($this->getLocale() !== (string) $options['locale']) { - $this->setLocale($options['locale']); - } - } - - /** - * Add translations - * - * This may be a new language or additional content for an existing language - * If the key 'clear' is true, then translations for the specified - * language will be replaced and added otherwise - * - * @param array|Zend_Config $options Options and translations to be added - * @throws Zend_Translate_Exception - * @return Zend_Translate_Adapter Provides fluent interface - */ - public function addTranslation($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options = array(); - $options['content'] = array_shift($args); - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $opt = array_shift($args); - $options = array_merge($opt, $options); - } - } else if (!is_array($options)) { - $options = array('content' => $options); - } - - if (!isset($options['content']) || empty($options['content'])) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("Required option 'content' is missing"); - } - - $originate = null; - if (!empty($options['locale'])) { - $originate = (string) $options['locale']; - } - - if ((array_key_exists('log', $options)) && !($options['log'] instanceof Zend_Log)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Instance of Zend_Log expected for option log'); - } - - try { - if (!($options['content'] instanceof Zend_Translate) && !($options['content'] instanceof Zend_Translate_Adapter)) { - if (empty($options['locale'])) { - $options['locale'] = null; - } - - $options['locale'] = Zend_Locale::findLocale($options['locale']); - } - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("The given Language '{$options['locale']}' does not exist", 0, $e); - } - - $options = $options + $this->_options; - if (is_string($options['content']) and is_dir($options['content'])) { - $options['content'] = realpath($options['content']); - $prev = ''; - $iterator = new RecursiveIteratorIterator( - new RecursiveRegexIterator( - new RecursiveDirectoryIterator($options['content'], RecursiveDirectoryIterator::KEY_AS_PATHNAME), - '/^(?!.*(\.svn|\.cvs)).*$/', RecursiveRegexIterator::MATCH - ), - RecursiveIteratorIterator::SELF_FIRST - ); - - foreach ($iterator as $directory => $info) { - $file = $info->getFilename(); - if (is_array($options['ignore'])) { - foreach ($options['ignore'] as $key => $ignore) { - if (strpos($key, 'regex') !== false) { - if (preg_match($ignore, $directory)) { - // ignore files matching the given regex from option 'ignore' and all files below - continue 2; - } - } else if (strpos($directory, DIRECTORY_SEPARATOR . $ignore) !== false) { - // ignore files matching first characters from option 'ignore' and all files below - continue 2; - } - } - } else { - if (strpos($directory, DIRECTORY_SEPARATOR . $options['ignore']) !== false) { - // ignore files matching first characters from option 'ignore' and all files below - continue; - } - } - - if ($info->isDir()) { - // pathname as locale - if (($options['scan'] === self::LOCALE_DIRECTORY) and (Zend_Locale::isLocale($file, true, false))) { - $options['locale'] = $file; - $prev = (string) $options['locale']; - } - } else if ($info->isFile()) { - // filename as locale - if ($options['scan'] === self::LOCALE_FILENAME) { - $filename = explode('.', $file); - array_pop($filename); - $filename = implode('.', $filename); - if (Zend_Locale::isLocale((string) $filename, true, false)) { - $options['locale'] = (string) $filename; - } else { - $parts = explode('.', $file); - $parts2 = array(); - foreach($parts as $token) { - $parts2 += explode('_', $token); - } - $parts = array_merge($parts, $parts2); - $parts2 = array(); - foreach($parts as $token) { - $parts2 += explode('-', $token); - } - $parts = array_merge($parts, $parts2); - $parts = array_unique($parts); - $prev = ''; - foreach($parts as $token) { - if (Zend_Locale::isLocale($token, true, false)) { - if (strlen($prev) <= strlen($token)) { - $options['locale'] = $token; - $prev = $token; - } - } - } - } - } - - try { - $options['content'] = $info->getPathname(); - $this->_addTranslationData($options); - } catch (Zend_Translate_Exception $e) { - // ignore failed sources while scanning - } - } - } - - unset($iterator); - } else { - $this->_addTranslationData($options); - } - - if ((isset($this->_translate[$originate]) === true) and (count($this->_translate[$originate]) > 0)) { - $this->setLocale($originate); - } - - return $this; - } - - /** - * Sets new adapter options - * - * @param array $options Adapter options - * @throws Zend_Translate_Exception - * @return Zend_Translate_Adapter Provides fluent interface - */ - public function setOptions(array $options = array()) - { - $change = false; - $locale = null; - foreach ($options as $key => $option) { - if ($key == 'locale') { - $locale = $option; - } else if ((isset($this->_options[$key]) and ($this->_options[$key] != $option)) or - !isset($this->_options[$key])) { - if (($key == 'log') && !($option instanceof Zend_Log)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Instance of Zend_Log expected for option log'); - } - - if ($key == 'cache') { - self::setCache($option); - continue; - } - - $this->_options[$key] = $option; - $change = true; - } - } - - if ($locale !== null) { - $this->setLocale($locale); - } - - if (isset(self::$_cache) and ($change == true)) { - $id = 'Zend_Translate_' . $this->toString() . '_Options'; - if (self::$_cacheTags) { - self::$_cache->save($this->_options, $id, array($this->_options['tag'])); - } else { - self::$_cache->save($this->_options, $id); - } - } - - return $this; - } - - /** - * Returns the adapters name and it's options - * - * @param string|null $optionKey String returns this option - * null returns all options - * @return integer|string|array|null - */ - public function getOptions($optionKey = null) - { - if ($optionKey === null) { - return $this->_options; - } - - if (isset($this->_options[$optionKey]) === true) { - return $this->_options[$optionKey]; - } - - return null; - } - - /** - * Gets locale - * - * @return Zend_Locale|string|null - */ - public function getLocale() - { - return $this->_options['locale']; - } - - /** - * Sets locale - * - * @param string|Zend_Locale $locale Locale to set - * @throws Zend_Translate_Exception - * @return Zend_Translate_Adapter Provides fluent interface - */ - public function setLocale($locale) - { - if (($locale === "auto") || ($locale === null)) { - $this->_automatic = true; - } else { - $this->_automatic = false; - } - - try { - $locale = Zend_Locale::findLocale($locale); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("The given Language ({$locale}) does not exist", 0, $e); - } - - if (!isset($this->_translate[$locale])) { - $temp = explode('_', $locale); - if (!isset($this->_translate[$temp[0]]) and !isset($this->_translate[$locale])) { - if (!$this->_options['disableNotices']) { - if ($this->_options['log']) { - $this->_options['log']->log("The language '{$locale}' has to be added before it can be used.", $this->_options['logPriority']); - } else { - trigger_error("The language '{$locale}' has to be added before it can be used.", E_USER_NOTICE); - } - } - } - - $locale = $temp[0]; - } - - if (empty($this->_translate[$locale])) { - if (!$this->_options['disableNotices']) { - if ($this->_options['log']) { - $this->_options['log']->log("No translation for the language '{$locale}' available.", $this->_options['logPriority']); - } else { - trigger_error("No translation for the language '{$locale}' available.", E_USER_NOTICE); - } - } - } - - if ($this->_options['locale'] != $locale) { - $this->_options['locale'] = $locale; - - if (isset(self::$_cache)) { - $id = 'Zend_Translate_' . $this->toString() . '_Options'; - if (self::$_cacheTags) { - self::$_cache->save($this->_options, $id, array($this->_options['tag'])); - } else { - self::$_cache->save($this->_options, $id); - } - } - } - - return $this; - } - - /** - * Returns the available languages from this adapter - * - * @return array|null - */ - public function getList() - { - $list = array_keys($this->_translate); - $result = null; - foreach($list as $value) { - if (!empty($this->_translate[$value])) { - $result[$value] = $value; - } - } - return $result; - } - - /** - * Returns the message id for a given translation - * If no locale is given, the actual language will be used - * - * @param string $message Message to get the key for - * @param string|Zend_Locale $locale (optional) Language to return the message ids from - * @return string|array|false - */ - public function getMessageId($message, $locale = null) - { - if (empty($locale) || !$this->isAvailable($locale)) { - $locale = $this->_options['locale']; - } - - return array_search($message, $this->_translate[(string) $locale]); - } - - /** - * Returns all available message ids from this adapter - * If no locale is given, the actual language will be used - * - * @param string|Zend_Locale $locale (optional) Language to return the message ids from - * @return array - */ - public function getMessageIds($locale = null) - { - if (empty($locale) || !$this->isAvailable($locale)) { - $locale = $this->_options['locale']; - } - - return array_keys($this->_translate[(string) $locale]); - } - - /** - * Returns all available translations from this adapter - * If no locale is given, the actual language will be used - * If 'all' is given the complete translation dictionary will be returned - * - * @param string|Zend_Locale $locale (optional) Language to return the messages from - * @return array - */ - public function getMessages($locale = null) - { - if ($locale === 'all') { - return $this->_translate; - } - - if ((empty($locale) === true) || ($this->isAvailable($locale) === false)) { - $locale = $this->_options['locale']; - } - - return $this->_translate[(string) $locale]; - } - - /** - * Is the wished language available ? - * - * @see Zend_Locale - * @param string|Zend_Locale $locale Language to search for, identical with locale identifier, - * @see Zend_Locale for more information - * @return boolean - */ - public function isAvailable($locale) - { - $return = isset($this->_translate[(string) $locale]); - return $return; - } - - /** - * Load translation data - * - * @param mixed $data - * @param string|Zend_Locale $locale - * @param array $options (optional) - * @return array - */ - abstract protected function _loadTranslationData($data, $locale, array $options = array()); - - /** - * Internal function for adding translation data - * - * This may be a new language or additional data for an existing language - * If the options 'clear' is true, then the translation data for the specified - * language is replaced and added otherwise - * - * @see Zend_Locale - * @param array|Zend_Config $content Translation data to add - * @throws Zend_Translate_Exception - * @return Zend_Translate_Adapter Provides fluent interface - */ - private function _addTranslationData($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options['content'] = array_shift($args); - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $options += array_shift($args); - } - } - - if (($options['content'] instanceof Zend_Translate) || ($options['content'] instanceof Zend_Translate_Adapter)) { - $options['usetranslateadapter'] = true; - if (!empty($options['locale']) && ($options['locale'] !== 'auto')) { - $options['content'] = $options['content']->getMessages($options['locale']); - } else { - $content = $options['content']; - $locales = $content->getList(); - foreach ($locales as $locale) { - $options['locale'] = $locale; - $options['content'] = $content->getMessages($locale); - $this->_addTranslationData($options); - } - - return $this; - } - } - - try { - $options['locale'] = Zend_Locale::findLocale($options['locale']); - } catch (Zend_Locale_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("The given Language '{$options['locale']}' does not exist", 0, $e); - } - - if ($options['clear'] || !isset($this->_translate[$options['locale']])) { - $this->_translate[$options['locale']] = array(); - } - - $read = true; - if (isset(self::$_cache)) { - $id = 'Zend_Translate_' . md5(serialize($options['content'])) . '_' . $this->toString(); - $temp = self::$_cache->load($id); - if ($temp) { - $read = false; - } - } - - if ($options['reload']) { - $read = true; - } - - if ($read) { - if (!empty($options['usetranslateadapter'])) { - $temp = array($options['locale'] => $options['content']); - } else { - $temp = $this->_loadTranslationData($options['content'], $options['locale'], $options); - } - } - - if (empty($temp)) { - $temp = array(); - } - - $keys = array_keys($temp); - foreach($keys as $key) { - if (!isset($this->_translate[$key])) { - $this->_translate[$key] = array(); - } - - if (array_key_exists($key, $temp) && is_array($temp[$key])) { - $this->_translate[$key] = $temp[$key] + $this->_translate[$key]; - } - } - - if ($this->_automatic === true) { - $find = new Zend_Locale($options['locale']); - $browser = $find->getEnvironment() + $find->getBrowser(); - arsort($browser); - foreach($browser as $language => $quality) { - if (isset($this->_translate[$language])) { - $this->_options['locale'] = $language; - break; - } - } - } - - if (($read) and (isset(self::$_cache))) { - $id = 'Zend_Translate_' . md5(serialize($options['content'])) . '_' . $this->toString(); - if (self::$_cacheTags) { - self::$_cache->save($temp, $id, array($this->_options['tag'])); - } else { - self::$_cache->save($temp, $id); - } - } - - return $this; - } - - /** - * Translates the given string - * returns the translation - * - * @see Zend_Locale - * @param string|array $messageId Translation string, or Array for plural translations - * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with - * locale identifier, @see Zend_Locale for more information - * @return string - */ - public function translate($messageId, $locale = null) - { - if ($locale === null) { - $locale = $this->_options['locale']; - } - - $plural = null; - if (is_array($messageId)) { - if (count($messageId) > 2) { - $number = array_pop($messageId); - if (!is_numeric($number)) { - $plocale = $number; - $number = array_pop($messageId); - } else { - $plocale = 'en'; - } - - $plural = $messageId; - $messageId = $messageId[0]; - } else { - $messageId = $messageId[0]; - } - } - - if (!Zend_Locale::isLocale($locale, true, false)) { - if (!Zend_Locale::isLocale($locale, false, false)) { - // language does not exist, return original string - $this->_log($messageId, $locale); - // use rerouting when enabled - if (!empty($this->_options['route'])) { - if (array_key_exists($locale, $this->_options['route']) && - !array_key_exists($locale, $this->_routed)) { - $this->_routed[$locale] = true; - return $this->translate($messageId, $this->_options['route'][$locale]); - } - } - - $this->_routed = array(); - if ($plural === null) { - return $messageId; - } - - $rule = Zend_Translate_Plural::getPlural($number, $plocale); - if (!isset($plural[$rule])) { - $rule = 0; - } - - return $plural[$rule]; - } - - $locale = new Zend_Locale($locale); - } - - $locale = (string) $locale; - if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) { - // return original translation - if ($plural === null) { - $this->_routed = array(); - return $this->_translate[$locale][$messageId]; - } - - $rule = Zend_Translate_Plural::getPlural($number, $locale); - if (isset($this->_translate[$locale][$plural[0]][$rule])) { - $this->_routed = array(); - return $this->_translate[$locale][$plural[0]][$rule]; - } - } else if (strlen($locale) != 2) { - // faster than creating a new locale and separate the leading part - $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); - - if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) { - // return regionless translation (en_US -> en) - if ($plural === null) { - $this->_routed = array(); - return $this->_translate[$locale][$messageId]; - } - - $rule = Zend_Translate_Plural::getPlural($number, $locale); - if (isset($this->_translate[$locale][$plural[0]][$rule])) { - $this->_routed = array(); - return $this->_translate[$locale][$plural[0]][$rule]; - } - } - } - - $this->_log($messageId, $locale); - // use rerouting when enabled - if (!empty($this->_options['route'])) { - if (array_key_exists($locale, $this->_options['route']) && - !array_key_exists($locale, $this->_routed)) { - $this->_routed[$locale] = true; - return $this->translate($messageId, $this->_options['route'][$locale]); - } - } - - $this->_routed = array(); - if ($plural === null) { - return $messageId; - } - - $rule = Zend_Translate_Plural::getPlural($number, $plocale); - if (!isset($plural[$rule])) { - $rule = 0; - } - - return $plural[$rule]; - } - - /** - * Translates the given string using plural notations - * Returns the translated string - * - * @see Zend_Locale - * @param string $singular Singular translation string - * @param string $plural Plural translation string - * @param integer $number Number for detecting the correct plural - * @param string|Zend_Locale $locale (Optional) Locale/Language to use, identical with - * locale identifier, @see Zend_Locale for more information - * @return string - */ - public function plural($singular, $plural, $number, $locale = null) - { - return $this->translate(array($singular, $plural, $number), $locale); - } - - /** - * Logs a message when the log option is set - * - * @param string $message Message to log - * @param String $locale Locale to log - */ - protected function _log($message, $locale) { - if ($this->_options['logUntranslated']) { - $message = str_replace('%message%', $message, $this->_options['logMessage']); - $message = str_replace('%locale%', $locale, $message); - if ($this->_options['log']) { - $this->_options['log']->log($message, $this->_options['logPriority']); - } else { - trigger_error($message, E_USER_NOTICE); - } - } - } - - /** - * Translates the given string - * returns the translation - * - * @param string $messageId Translation string - * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with locale - * identifier, @see Zend_Locale for more information - * @return string - */ - public function _($messageId, $locale = null) - { - return $this->translate($messageId, $locale); - } - - /** - * Checks if a string is translated within the source or not - * returns boolean - * - * @param string $messageId Translation string - * @param boolean $original (optional) Allow translation only for original language - * when true, a translation for 'en_US' would give false when it can - * be translated with 'en' only - * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with locale identifier, - * see Zend_Locale for more information - * @return boolean - */ - public function isTranslated($messageId, $original = false, $locale = null) - { - if (($original !== false) and ($original !== true)) { - $locale = $original; - $original = false; - } - - if ($locale === null) { - $locale = $this->_options['locale']; - } - - if (!Zend_Locale::isLocale($locale, true, false)) { - if (!Zend_Locale::isLocale($locale, false, false)) { - // language does not exist, return original string - return false; - } - - $locale = new Zend_Locale($locale); - } - - $locale = (string) $locale; - if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) { - // return original translation - return true; - } else if ((strlen($locale) != 2) and ($original === false)) { - // faster than creating a new locale and separate the leading part - $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); - - if ((is_string($messageId) || is_int($messageId)) && isset($this->_translate[$locale][$messageId])) { - // return regionless translation (en_US -> en) - return true; - } - } - - // No translation found, return original - return false; - } - - /** - * Returns the set cache - * - * @return Zend_Cache_Core The set cache - */ - public static function getCache() - { - return self::$_cache; - } - - /** - * Sets a cache for all Zend_Translate_Adapters - * - * @param Zend_Cache_Core $cache Cache to store to - */ - public static function setCache(Zend_Cache_Core $cache) - { - self::$_cache = $cache; - self::_getTagSupportForCache(); - } - - /** - * Returns true when a cache is set - * - * @return boolean - */ - public static function hasCache() - { - if (self::$_cache !== null) { - return true; - } - - return false; - } - - /** - * Removes any set cache - * - * @return void - */ - public static function removeCache() - { - self::$_cache = null; - } - - /** - * Clears all set cache data - * - * @param string $tag Tag to clear when the default tag name is not used - * @return void - */ - public static function clearCache($tag = null) - { - #require_once 'Zend/Cache.php'; - if (self::$_cacheTags) { - if ($tag == null) { - $tag = 'Zend_Translate'; - } - - self::$_cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array($tag)); - } else { - self::$_cache->clean(Zend_Cache::CLEANING_MODE_ALL); - } - } - - /** - * Returns the adapter name - * - * @return string - */ - abstract public function toString(); - - /** - * Internal method to check if the given cache supports tags - * - * @param Zend_Cache $cache - */ - private static function _getTagSupportForCache() - { - $backend = self::$_cache->getBackend(); - if ($backend instanceof Zend_Cache_Backend_ExtendedInterface) { - $cacheOptions = $backend->getCapabilities(); - self::$_cacheTags = $cacheOptions['tags']; - } else { - self::$_cacheTags = false; - } - - return self::$_cacheTags; - } -} diff --git a/lib/Zend/Translate/Adapter/Array.php b/lib/Zend/Translate/Adapter/Array.php deleted file mode 100644 index bc0ae4ff9d8..00000000000 --- a/lib/Zend/Translate/Adapter/Array.php +++ /dev/null @@ -1,81 +0,0 @@ -_data = array(); - if (!is_array($data)) { - if (file_exists($data)) { - ob_start(); - $data = include($data); - ob_end_clean(); - } - } - if (!is_array($data)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("Error including array or file '".$data."'"); - } - - if (!isset($this->_data[$locale])) { - $this->_data[$locale] = array(); - } - - $this->_data[$locale] = $data + $this->_data[$locale]; - return $this->_data; - } - - /** - * returns the adapters name - * - * @return string - */ - public function toString() - { - return "Array"; - } -} diff --git a/lib/Zend/Translate/Adapter/Csv.php b/lib/Zend/Translate/Adapter/Csv.php deleted file mode 100644 index 6bfb635d9db..00000000000 --- a/lib/Zend/Translate/Adapter/Csv.php +++ /dev/null @@ -1,121 +0,0 @@ -_options['delimiter'] = ";"; - $this->_options['length'] = 0; - $this->_options['enclosure'] = '"'; - - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $args = func_get_args(); - $options = array(); - $options['content'] = array_shift($args); - - if (!empty($args)) { - $options['locale'] = array_shift($args); - } - - if (!empty($args)) { - $opt = array_shift($args); - $options = array_merge($opt, $options); - } - } else if (!is_array($options)) { - $options = array('content' => $options); - } - - parent::__construct($options); - } - - /** - * Load translation data - * - * @param string|array $filename Filename and full path to the translation source - * @param string $locale Locale/Language to add data for, identical with locale identifier, - * see Zend_Locale for more information - * @param array $option OPTIONAL Options to use - * @return array - */ - protected function _loadTranslationData($filename, $locale, array $options = array()) - { - $this->_data = array(); - $options = $options + $this->_options; - $this->_file = @fopen($filename, 'rb'); - if (!$this->_file) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Error opening translation file \'' . $filename . '\'.'); - } - - while(($data = fgetcsv($this->_file, $options['length'], $options['delimiter'], $options['enclosure'])) !== false) { - if (substr($data[0], 0, 1) === '#') { - continue; - } - - if (!isset($data[1])) { - continue; - } - - if (count($data) == 2) { - $this->_data[$locale][$data[0]] = $data[1]; - } else { - $singular = array_shift($data); - $this->_data[$locale][$singular] = $data; - } - } - - return $this->_data; - } - - /** - * returns the adapters name - * - * @return string - */ - public function toString() - { - return "Csv"; - } -} diff --git a/lib/Zend/Translate/Adapter/Gettext.php b/lib/Zend/Translate/Adapter/Gettext.php deleted file mode 100644 index bddec6ce50d..00000000000 --- a/lib/Zend/Translate/Adapter/Gettext.php +++ /dev/null @@ -1,169 +0,0 @@ -_bigEndian === false) { - return unpack('V' . $bytes, fread($this->_file, 4 * $bytes)); - } else { - return unpack('N' . $bytes, fread($this->_file, 4 * $bytes)); - } - } - - /** - * Load translation data (MO file reader) - * - * @param string $filename MO file to add, full path must be given for access - * @param string $locale New Locale/Language to set, identical with locale identifier, - * see Zend_Locale for more information - * @param array $option OPTIONAL Options to use - * @throws Zend_Translation_Exception - * @return array - */ - protected function _loadTranslationData($filename, $locale, array $options = array()) - { - $this->_data = array(); - $this->_bigEndian = false; - $this->_file = @fopen($filename, 'rb'); - if (!$this->_file) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Error opening translation file \'' . $filename . '\'.'); - } - if (@filesize($filename) < 10) { - @fclose($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('\'' . $filename . '\' is not a gettext file'); - } - - // get Endian - $input = $this->_readMOData(1); - if (strtolower(substr(dechex($input[1]), -8)) == "950412de") { - $this->_bigEndian = false; - } else if (strtolower(substr(dechex($input[1]), -8)) == "de120495") { - $this->_bigEndian = true; - } else { - @fclose($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('\'' . $filename . '\' is not a gettext file'); - } - // read revision - not supported for now - $input = $this->_readMOData(1); - - // number of bytes - $input = $this->_readMOData(1); - $total = $input[1]; - - // number of original strings - $input = $this->_readMOData(1); - $OOffset = $input[1]; - - // number of translation strings - $input = $this->_readMOData(1); - $TOffset = $input[1]; - - // fill the original table - fseek($this->_file, $OOffset); - $origtemp = $this->_readMOData(2 * $total); - fseek($this->_file, $TOffset); - $transtemp = $this->_readMOData(2 * $total); - - for($count = 0; $count < $total; ++$count) { - if ($origtemp[$count * 2 + 1] != 0) { - fseek($this->_file, $origtemp[$count * 2 + 2]); - $original = @fread($this->_file, $origtemp[$count * 2 + 1]); - $original = explode("\0", $original); - } else { - $original[0] = ''; - } - - if ($transtemp[$count * 2 + 1] != 0) { - fseek($this->_file, $transtemp[$count * 2 + 2]); - $translate = fread($this->_file, $transtemp[$count * 2 + 1]); - $translate = explode("\0", $translate); - if ((count($original) > 1)) { - $this->_data[$locale][$original[0]] = $translate; - array_shift($original); - foreach ($original as $orig) { - $this->_data[$locale][$orig] = ''; - } - } else { - $this->_data[$locale][$original[0]] = $translate[0]; - } - } - } - - @fclose($this->_file); - - $this->_data[$locale][''] = trim($this->_data[$locale]['']); - if (empty($this->_data[$locale][''])) { - $this->_adapterInfo[$filename] = 'No adapter information available'; - } else { - $this->_adapterInfo[$filename] = $this->_data[$locale]['']; - } - - unset($this->_data[$locale]['']); - return $this->_data; - } - - /** - * Returns the adapter informations - * - * @return array Each loaded adapter information as array value - */ - public function getAdapterInfo() - { - return $this->_adapterInfo; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "Gettext"; - } -} diff --git a/lib/Zend/Translate/Adapter/Ini.php b/lib/Zend/Translate/Adapter/Ini.php deleted file mode 100644 index 1f557947299..00000000000 --- a/lib/Zend/Translate/Adapter/Ini.php +++ /dev/null @@ -1,74 +0,0 @@ -_data = array(); - if (!file_exists($data)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception("Ini file '".$data."' not found"); - } - - $inidata = parse_ini_file($data, false); - if (!isset($this->_data[$locale])) { - $this->_data[$locale] = array(); - } - - $this->_data[$locale] = array_merge($this->_data[$locale], $inidata); - return $this->_data; - } - - /** - * returns the adapters name - * - * @return string - */ - public function toString() - { - return "Ini"; - } -} diff --git a/lib/Zend/Translate/Adapter/Qt.php b/lib/Zend/Translate/Adapter/Qt.php deleted file mode 100644 index f89aa9f16cb..00000000000 --- a/lib/Zend/Translate/Adapter/Qt.php +++ /dev/null @@ -1,175 +0,0 @@ -_data = array(); - if (!is_readable($filename)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Translation file \'' . $filename . '\' is not readable.'); - } - - $this->_target = $locale; - - $encoding = $this->_findEncoding($filename); - $this->_file = xml_parser_create($encoding); - xml_set_object($this->_file, $this); - xml_parser_set_option($this->_file, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($this->_file, "_startElement", "_endElement"); - xml_set_character_data_handler($this->_file, "_contentElement"); - - try { - Zend_Xml_Security::scanFile($filename); - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception( - $e->getMessage() - ); - } - - if (!xml_parse($this->_file, file_get_contents($filename))) { - $ex = sprintf('XML error: %s at line %d of file %s', - xml_error_string(xml_get_error_code($this->_file)), - xml_get_current_line_number($this->_file), - $filename); - xml_parser_free($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception($ex); - } - - return $this->_data; - } - - private function _startElement($file, $name, $attrib) - { - switch(strtolower($name)) { - case 'message': - $this->_source = null; - $this->_stag = false; - $this->_ttag = false; - $this->_scontent = null; - $this->_tcontent = null; - break; - case 'source': - $this->_stag = true; - break; - case 'translation': - $this->_ttag = true; - break; - default: - break; - } - } - - private function _endElement($file, $name) - { - switch (strtolower($name)) { - case 'source': - $this->_stag = false; - break; - - case 'translation': - if (!empty($this->_scontent) and !empty($this->_tcontent) or - (isset($this->_data[$this->_target][$this->_scontent]) === false)) { - $this->_data[$this->_target][$this->_scontent] = $this->_tcontent; - } - $this->_ttag = false; - break; - - default: - break; - } - } - - private function _contentElement($file, $data) - { - if ($this->_stag === true) { - $this->_scontent .= $data; - } - - if ($this->_ttag === true) { - $this->_tcontent .= $data; - } - } - - private function _findEncoding($filename) - { - $file = file_get_contents($filename, null, null, 0, 100); - if (strpos($file, "encoding") !== false) { - $encoding = substr($file, strpos($file, "encoding") + 9); - $encoding = substr($encoding, 1, strpos($encoding, $encoding[0], 1) - 1); - return $encoding; - } - return 'UTF-8'; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "Qt"; - } -} diff --git a/lib/Zend/Translate/Adapter/Tbx.php b/lib/Zend/Translate/Adapter/Tbx.php deleted file mode 100644 index a7a7e3e722c..00000000000 --- a/lib/Zend/Translate/Adapter/Tbx.php +++ /dev/null @@ -1,180 +0,0 @@ -_data = array(); - if (!is_readable($filename)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Translation file \'' . $filename . '\' is not readable.'); - } - - $encoding = $this->_findEncoding($filename); - $this->_file = xml_parser_create($encoding); - xml_set_object($this->_file, $this); - xml_parser_set_option($this->_file, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($this->_file, "_startElement", "_endElement"); - xml_set_character_data_handler($this->_file, "_contentElement"); - - try { - Zend_Xml_Security::scanFile($filename); - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception( - $e->getMessage() - ); - } - - if (!xml_parse($this->_file, file_get_contents($filename))) { - $ex = sprintf('XML error: %s at line %d of file %s', - xml_error_string(xml_get_error_code($this->_file)), - xml_get_current_line_number($this->_file), - $filename); - xml_parser_free($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception($ex); - } - - return $this->_data; - } - - private function _startElement($file, $name, $attrib) - { - if ($this->_term !== null) { - $this->_content .= "<".$name; - foreach($attrib as $key => $value) { - $this->_content .= " $key=\"$value\""; - } - $this->_content .= ">"; - } else { - switch(strtolower($name)) { - case 'termentry': - $this->_termentry = null; - break; - case 'langset': - if (isset($attrib['xml:lang']) === true) { - $this->_langset = $attrib['xml:lang']; - if (isset($this->_data[$this->_langset]) === false) { - $this->_data[$this->_langset] = array(); - } - } - break; - case 'term': - $this->_term = true; - $this->_content = null; - break; - default: - break; - } - } - } - - private function _endElement($file, $name) - { - if (($this->_term !== null) and ($name != "term")) { - $this->_content .= ""; - } else { - switch (strtolower($name)) { - case 'langset': - $this->_langset = null; - break; - case 'term': - $this->_term = null; - if (empty($this->_termentry)) { - $this->_termentry = $this->_content; - } - if (!empty($this->_content) || (isset($this->_data[$this->_langset][$this->_termentry]) === false)) { - $this->_data[$this->_langset][$this->_termentry] = $this->_content; - } - break; - default: - break; - } - } - } - - private function _contentElement($file, $data) - { - if ($this->_term !== null) { - $this->_content .= $data; - } - } - - private function _findEncoding($filename) - { - $file = file_get_contents($filename, null, null, 0, 100); - if (strpos($file, "encoding") !== false) { - $encoding = substr($file, strpos($file, "encoding") + 9); - $encoding = substr($encoding, 1, strpos($encoding, $encoding[0], 1) - 1); - return $encoding; - } - return 'UTF-8'; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "Tbx"; - } -} diff --git a/lib/Zend/Translate/Adapter/Tmx.php b/lib/Zend/Translate/Adapter/Tmx.php deleted file mode 100644 index 3ced9ab450c..00000000000 --- a/lib/Zend/Translate/Adapter/Tmx.php +++ /dev/null @@ -1,248 +0,0 @@ -_data = array(); - if (!is_readable($filename)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Translation file \'' . $filename . '\' is not readable.'); - } - - if (isset($options['useId'])) { - $this->_useId = (boolean) $options['useId']; - } - - $encoding = $this->_findEncoding($filename); - $this->_file = xml_parser_create($encoding); - xml_set_object($this->_file, $this); - xml_parser_set_option($this->_file, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($this->_file, "_startElement", "_endElement"); - xml_set_character_data_handler($this->_file, "_contentElement"); - - try { - Zend_Xml_Security::scanFile($filename); - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception( - $e->getMessage() - ); - } - - if (!xml_parse($this->_file, file_get_contents($filename))) { - $ex = sprintf('XML error: %s at line %d of file %s', - xml_error_string(xml_get_error_code($this->_file)), - xml_get_current_line_number($this->_file), - $filename); - xml_parser_free($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception($ex); - } - - return $this->_data; - } - - /** - * Internal method, called by xml element handler at start - * - * @param resource $file File handler - * @param string $name Elements name - * @param array $attrib Attributes for this element - */ - protected function _startElement($file, $name, $attrib) - { - if ($this->_seg !== null) { - $this->_content .= "<".$name; - foreach($attrib as $key => $value) { - $this->_content .= " $key=\"$value\""; - } - $this->_content .= ">"; - } else { - switch(strtolower($name)) { - case 'header': - if (empty($this->_useId) && isset($attrib['srclang'])) { - if (Zend_Locale::isLocale($attrib['srclang'])) { - $this->_srclang = Zend_Locale::findLocale($attrib['srclang']); - } else { - if (!$this->_options['disableNotices']) { - if ($this->_options['log']) { - $this->_options['log']->notice("The language '{$attrib['srclang']}' can not be set because it does not exist."); - } else { - trigger_error("The language '{$attrib['srclang']}' can not be set because it does not exist.", E_USER_NOTICE); - } - } - - $this->_srclang = $attrib['srclang']; - } - } - break; - case 'tu': - if (isset($attrib['tuid'])) { - $this->_tu = $attrib['tuid']; - } - break; - case 'tuv': - if (isset($attrib['xml:lang'])) { - if (Zend_Locale::isLocale($attrib['xml:lang'])) { - $this->_tuv = Zend_Locale::findLocale($attrib['xml:lang']); - } else { - if (!$this->_options['disableNotices']) { - if ($this->_options['log']) { - $this->_options['log']->notice("The language '{$attrib['xml:lang']}' can not be set because it does not exist."); - } else { - trigger_error("The language '{$attrib['xml:lang']}' can not be set because it does not exist.", E_USER_NOTICE); - } - } - - $this->_tuv = $attrib['xml:lang']; - } - - if (!isset($this->_data[$this->_tuv])) { - $this->_data[$this->_tuv] = array(); - } - } - break; - case 'seg': - $this->_seg = true; - $this->_content = null; - break; - default: - break; - } - } - } - - - /** - * Internal method, called by xml element handler at end - * - * @param resource $file File handler - * @param string $name Elements name - */ - protected function _endElement($file, $name) - { - if (($this->_seg !== null) and ($name !== 'seg')) { - $this->_content .= ""; - } else { - switch (strtolower($name)) { - case 'tu': - $this->_tu = null; - break; - case 'tuv': - $this->_tuv = null; - break; - case 'seg': - $this->_seg = null; - if (!empty($this->_srclang) && ($this->_srclang == $this->_tuv)) { - $this->_tu = $this->_content; - } - - if (!empty($this->_content) || (!isset($this->_data[$this->_tuv][$this->_tu]))) { - $this->_data[$this->_tuv][$this->_tu] = $this->_content; - } - break; - default: - break; - } - } - } - - /** - * Internal method, called by xml element handler for content - * - * @param resource $file File handler - * @param string $data Elements content - */ - protected function _contentElement($file, $data) - { - if (($this->_seg !== null) and ($this->_tu !== null) and ($this->_tuv !== null)) { - $this->_content .= $data; - } - } - - - /** - * Internal method, detects the encoding of the xml file - * - * @param string $name Filename - * @return string Encoding - */ - protected function _findEncoding($filename) - { - $file = file_get_contents($filename, null, null, 0, 100); - if (strpos($file, "encoding") !== false) { - $encoding = substr($file, strpos($file, "encoding") + 9); - $encoding = substr($encoding, 1, strpos($encoding, $encoding[0], 1) - 1); - return $encoding; - } - return 'UTF-8'; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "Tmx"; - } -} diff --git a/lib/Zend/Translate/Adapter/Xliff.php b/lib/Zend/Translate/Adapter/Xliff.php deleted file mode 100644 index a78bd8597b8..00000000000 --- a/lib/Zend/Translate/Adapter/Xliff.php +++ /dev/null @@ -1,244 +0,0 @@ -_data = array(); - if (!is_readable($filename)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Translation file \'' . $filename . '\' is not readable.'); - } - - if (empty($options['useId'])) { - $this->_useId = false; - } else { - $this->_useId = true; - } - - $encoding = $this->_findEncoding($filename); - $this->_target = $locale; - $this->_file = xml_parser_create($encoding); - xml_set_object($this->_file, $this); - xml_parser_set_option($this->_file, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($this->_file, "_startElement", "_endElement"); - xml_set_character_data_handler($this->_file, "_contentElement"); - - try { - Zend_Xml_Security::scanFile($filename); - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception( - $e->getMessage() - ); - } - - if (!xml_parse($this->_file, file_get_contents($filename))) { - $ex = sprintf('XML error: %s at line %d of file %s', - xml_error_string(xml_get_error_code($this->_file)), - xml_get_current_line_number($this->_file), - $filename); - xml_parser_free($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception($ex); - } - - return $this->_data; - } - - private function _startElement($file, $name, $attrib) - { - if ($this->_stag === true) { - $this->_scontent .= "<".$name; - foreach($attrib as $key => $value) { - $this->_scontent .= " $key=\"$value\""; - } - $this->_scontent .= ">"; - } else if ($this->_ttag === true) { - $this->_tcontent .= "<".$name; - foreach($attrib as $key => $value) { - $this->_tcontent .= " $key=\"$value\""; - } - $this->_tcontent .= ">"; - } else { - switch(strtolower($name)) { - case 'file': - $this->_source = $attrib['source-language']; - if (isset($attrib['target-language'])) { - $this->_target = $attrib['target-language']; - } - - if (!isset($this->_data[$this->_source])) { - $this->_data[$this->_source] = array(); - } - - if (!isset($this->_data[$this->_target])) { - $this->_data[$this->_target] = array(); - } - - break; - case 'trans-unit': - $this->_transunit = true; - $this->_langId = $attrib['id']; - break; - case 'source': - if ($this->_transunit === true) { - $this->_scontent = null; - $this->_stag = true; - $this->_ttag = false; - } - break; - case 'target': - if ($this->_transunit === true) { - $this->_tcontent = null; - $this->_ttag = true; - $this->_stag = false; - } - break; - default: - break; - } - } - } - - private function _endElement($file, $name) - { - if (($this->_stag === true) and ($name !== 'source')) { - $this->_scontent .= ""; - } else if (($this->_ttag === true) and ($name !== 'target')) { - $this->_tcontent .= ""; - } else { - switch (strtolower($name)) { - case 'trans-unit': - $this->_transunit = null; - $this->_langId = null; - $this->_scontent = null; - $this->_tcontent = null; - break; - case 'source': - if ($this->_useId) { - if (!empty($this->_scontent) && !empty($this->_langId) && - !isset($this->_data[$this->_source][$this->_langId])) { - $this->_data[$this->_source][$this->_langId] = $this->_scontent; - } - } else { - if (!empty($this->_scontent) && - !isset($this->_data[$this->_source][$this->_scontent])) { - $this->_data[$this->_source][$this->_scontent] = $this->_scontent; - } - } - $this->_stag = false; - break; - case 'target': - if ($this->_useId) { - if (!empty($this->_tcontent) && !empty($this->_langId) && - !isset($this->_data[$this->_target][$this->_langId])) { - $this->_data[$this->_target][$this->_langId] = $this->_tcontent; - } - } else { - if (!empty($this->_tcontent) && !empty($this->_scontent) && - !isset($this->_data[$this->_target][$this->_scontent])) { - $this->_data[$this->_target][$this->_scontent] = $this->_tcontent; - } - } - $this->_ttag = false; - break; - default: - break; - } - } - } - - private function _contentElement($file, $data) - { - if (($this->_transunit !== null) and ($this->_source !== null) and ($this->_stag === true)) { - $this->_scontent .= $data; - } - - if (($this->_transunit !== null) and ($this->_target !== null) and ($this->_ttag === true)) { - $this->_tcontent .= $data; - } - } - - private function _findEncoding($filename) - { - $file = file_get_contents($filename, null, null, 0, 100); - if (strpos($file, "encoding") !== false) { - $encoding = substr($file, strpos($file, "encoding") + 9); - $encoding = substr($encoding, 1, strpos($encoding, $encoding[0], 1) - 1); - return $encoding; - } - return 'UTF-8'; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "Xliff"; - } -} diff --git a/lib/Zend/Translate/Adapter/XmlTm.php b/lib/Zend/Translate/Adapter/XmlTm.php deleted file mode 100644 index b8af0a9f5d7..00000000000 --- a/lib/Zend/Translate/Adapter/XmlTm.php +++ /dev/null @@ -1,154 +0,0 @@ -_data = array(); - $this->_lang = $locale; - if (!is_readable($filename)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('Translation file \'' . $filename . '\' is not readable.'); - } - - $encoding = $this->_findEncoding($filename); - $this->_file = xml_parser_create($encoding); - xml_set_object($this->_file, $this); - xml_parser_set_option($this->_file, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($this->_file, "_startElement", "_endElement"); - xml_set_character_data_handler($this->_file, "_contentElement"); - - try { - Zend_Xml_Security::scanFile($filename); - } catch (Zend_Xml_Exception $e) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception( - $e->getMessage() - ); - } - - if (!xml_parse($this->_file, file_get_contents($filename))) { - $ex = sprintf('XML error: %s at line %d of file %s', - xml_error_string(xml_get_error_code($this->_file)), - xml_get_current_line_number($this->_file), - $filename); - xml_parser_free($this->_file); - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception($ex); - } - - return $this->_data; - } - - private function _startElement($file, $name, $attrib) - { - switch(strtolower($name)) { - case 'tm:tu': - $this->_tag = $attrib['id']; - $this->_content = null; - break; - default: - break; - } - } - - private function _endElement($file, $name) - { - switch (strtolower($name)) { - case 'tm:tu': - if (!empty($this->_tag) and !empty($this->_content) or - (isset($this->_data[$this->_lang][$this->_tag]) === false)) { - $this->_data[$this->_lang][$this->_tag] = $this->_content; - } - $this->_tag = null; - $this->_content = null; - break; - - default: - break; - } - } - - private function _contentElement($file, $data) - { - if (($this->_tag !== null)) { - $this->_content .= $data; - } - } - - private function _findEncoding($filename) - { - $file = file_get_contents($filename, null, null, 0, 100); - if (strpos($file, "encoding") !== false) { - $encoding = substr($file, strpos($file, "encoding") + 9); - $encoding = substr($encoding, 1, strpos($encoding, $encoding[0], 1) - 1); - return $encoding; - } - return 'UTF-8'; - } - - /** - * Returns the adapter name - * - * @return string - */ - public function toString() - { - return "XmlTm"; - } -} diff --git a/lib/Zend/Translate/Exception.php b/lib/Zend/Translate/Exception.php deleted file mode 100644 index b8fc68f56ca..00000000000 --- a/lib/Zend/Translate/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ - 3) { - $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); - } - - if (isset(self::$_plural[$locale])) { - $return = call_user_func(self::$_plural[$locale], $number); - - if (!is_int($return) || ($return < 0)) { - $return = 0; - } - - return $return; - } - - switch($locale) { - case 'az': - case 'bo': - case 'dz': - case 'id': - case 'ja': - case 'jv': - case 'ka': - case 'km': - case 'kn': - case 'ko': - case 'ms': - case 'th': - case 'tr': - case 'vi': - case 'zh': - return 0; - break; - - case 'af': - case 'bn': - case 'bg': - case 'ca': - case 'da': - case 'de': - case 'el': - case 'en': - case 'eo': - case 'es': - case 'et': - case 'eu': - case 'fa': - case 'fi': - case 'fo': - case 'fur': - case 'fy': - case 'gl': - case 'gu': - case 'ha': - case 'he': - case 'hu': - case 'is': - case 'it': - case 'ku': - case 'lb': - case 'ml': - case 'mn': - case 'mr': - case 'nah': - case 'nb': - case 'ne': - case 'nl': - case 'nn': - case 'no': - case 'om': - case 'or': - case 'pa': - case 'pap': - case 'ps': - case 'pt': - case 'so': - case 'sq': - case 'sv': - case 'sw': - case 'ta': - case 'te': - case 'tk': - case 'ur': - case 'zu': - return ($number == 1) ? 0 : 1; - - case 'am': - case 'bh': - case 'fil': - case 'fr': - case 'gun': - case 'hi': - case 'ln': - case 'mg': - case 'nso': - case 'xbr': - case 'ti': - case 'wa': - return (($number == 0) || ($number == 1)) ? 0 : 1; - - case 'be': - case 'bs': - case 'hr': - case 'ru': - case 'sr': - case 'uk': - return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); - - case 'cs': - case 'sk': - return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2); - - case 'ga': - return ($number == 1) ? 0 : (($number == 2) ? 1 : 2); - - case 'lt': - return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); - - case 'sl': - return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3)); - - case 'mk': - return ($number % 10 == 1) ? 0 : 1; - - case 'mt': - return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3)); - - case 'lv': - return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2); - - case 'pl': - return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2); - - case 'cy': - return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3)); - - case 'ro': - return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2); - - case 'ar': - return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number >= 3) && ($number <= 10)) ? 3 : ((($number >= 11) && ($number <= 99)) ? 4 : 5)))); - - default: - return 0; - } - } - - /** - * Set's a new plural rule - * - * @param string $rule Callback which acts as rule - * @param string $locale Locale which is used for this callback - * @return null - */ - public static function setPlural($rule, $locale) - { - if ($locale == "pt_BR") { - // temporary set a locale for brasilian - $locale = "xbr"; - } - - if (strlen($locale) > 3) { - $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); - } - - if (!is_callable($rule)) { - #require_once 'Zend/Translate/Exception.php'; - throw new Zend_Translate_Exception('The given rule can not be called'); - } - - self::$_plural[$locale] = $rule; - } -} diff --git a/lib/Zend/Uri.php b/lib/Zend/Uri.php deleted file mode 100644 index 657e16cb988..00000000000 --- a/lib/Zend/Uri.php +++ /dev/null @@ -1,207 +0,0 @@ - false - ); - - /** - * Return a string representation of this URI. - * - * @see getUri() - * @return string - */ - public function __toString() - { - try { - return $this->getUri(); - } catch (Exception $e) { - trigger_error($e->getMessage(), E_USER_WARNING); - return ''; - } - } - - /** - * Convenience function, checks that a $uri string is well-formed - * by validating it but not returning an object. Returns TRUE if - * $uri is a well-formed URI, or FALSE otherwise. - * - * @param string $uri The URI to check - * @return boolean - */ - public static function check($uri) - { - try { - $uri = self::factory($uri); - } catch (Exception $e) { - return false; - } - - return $uri->valid(); - } - - /** - * Create a new Zend_Uri object for a URI. If building a new URI, then $uri should contain - * only the scheme (http, ftp, etc). Otherwise, supply $uri with the complete URI. - * - * @param string $uri The URI form which a Zend_Uri instance is created - * @param string $className The name of the class to use in order to manipulate URI - * @throws Zend_Uri_Exception When an empty string was supplied for the scheme - * @throws Zend_Uri_Exception When an illegal scheme is supplied - * @throws Zend_Uri_Exception When the scheme is not supported - * @throws Zend_Uri_Exception When $className doesn't exist or doesn't implements Zend_Uri - * @return Zend_Uri - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public static function factory($uri = 'http', $className = null) - { - // Separate the scheme from the scheme-specific parts - $uri = explode(':', $uri, 2); - $scheme = strtolower($uri[0]); - $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; - - if (strlen($scheme) === 0) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('An empty string was supplied for the scheme'); - } - - // Security check: $scheme is used to load a class file, so only alphanumerics are allowed. - if (ctype_alnum($scheme) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted'); - } - - if ($className === null) { - /** - * Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the - * scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown. - */ - switch ($scheme) { - case 'http': - // Break intentionally omitted - case 'https': - $className = 'Zend_Uri_Http'; - break; - - case 'mailto': - // TODO - default: - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported"); - break; - } - } - - #require_once 'Zend/Loader.php'; - try { - Zend_Loader::loadClass($className); - } catch (Exception $e) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("\"$className\" not found"); - } - - $schemeHandler = new $className($scheme, $schemeSpecific); - - if (! $schemeHandler instanceof Zend_Uri) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("\"$className\" is not an instance of Zend_Uri"); - } - - return $schemeHandler; - } - - /** - * Get the URI's scheme - * - * @return string|false Scheme or false if no scheme is set. - */ - public function getScheme() - { - if (empty($this->_scheme) === false) { - return $this->_scheme; - } else { - return false; - } - } - - /** - * Set global configuration options - * - * @param Zend_Config|array $config - */ - static public function setConfig($config) - { - if ($config instanceof Zend_Config) { - $config = $config->toArray(); - } elseif (!is_array($config)) { - throw new Zend_Uri_Exception("Config must be an array or an instance of Zend_Config."); - } - - foreach ($config as $k => $v) { - self::$_config[$k] = $v; - } - } - - /** - * Zend_Uri and its subclasses cannot be instantiated directly. - * Use Zend_Uri::factory() to return a new Zend_Uri object. - * - * @param string $scheme The scheme of the URI - * @param string $schemeSpecific The scheme-specific part of the URI - */ - abstract protected function __construct($scheme, $schemeSpecific = ''); - - /** - * Return a string representation of this URI. - * - * @return string - */ - abstract public function getUri(); - - /** - * Returns TRUE if this URI is valid, or FALSE otherwise. - * - * @return boolean - */ - abstract public function valid(); -} diff --git a/lib/Zend/Uri/Exception.php b/lib/Zend/Uri/Exception.php deleted file mode 100644 index bff2d44de0b..00000000000 --- a/lib/Zend/Uri/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_scheme = $scheme; - - // Set up grammar rules for validation via regular expressions. These - // are to be used with slash-delimited regular expression strings. - - // Escaped special characters (eg. '%25' for '%') - $this->_regex['escaped'] = '%[[:xdigit:]]{2}'; - - // Unreserved characters - $this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']'; - - // Segment can use escaped, unreserved or a set of additional chars - $this->_regex['segment'] = '(?:' . $this->_regex['escaped'] . '|[' . - self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*'; - - // Path can be a series of segmets char strings seperated by '/' - $this->_regex['path'] = '(?:\/(?:' . $this->_regex['segment'] . ')?)+'; - - // URI characters can be escaped, alphanumeric, mark or reserved chars - $this->_regex['uric'] = '(?:' . $this->_regex['escaped'] . '|[' . - self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED . - - // If unwise chars are allowed, add them to the URI chars class - (self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])'; - - // If no scheme-specific part was supplied, the user intends to create - // a new URI with this object. No further parsing is required. - if (strlen($schemeSpecific) === 0) { - return; - } - - // Parse the scheme-specific URI parts into the instance variables. - $this->_parseUri($schemeSpecific); - - // Validate the URI - if ($this->valid() === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Invalid URI supplied'); - } - } - - /** - * Creates a Zend_Uri_Http from the given string - * - * @param string $uri String to create URI from, must start with - * 'http://' or 'https://' - * @throws InvalidArgumentException When the given $uri is not a string or - * does not start with http:// or https:// - * @throws Zend_Uri_Exception When the given $uri is invalid - * @return Zend_Uri_Http - */ - public static function fromString($uri) - { - if (is_string($uri) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('$uri is not a string'); - } - - $uri = explode(':', $uri, 2); - $scheme = strtolower($uri[0]); - $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; - - if (in_array($scheme, array('http', 'https')) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Invalid scheme: '$scheme'"); - } - - $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific); - return $schemeHandler; - } - - /** - * Parse the scheme-specific portion of the URI and place its parts into instance variables. - * - * @param string $schemeSpecific The scheme-specific portion to parse - * @throws Zend_Uri_Exception When scheme-specific decoposition fails - * @throws Zend_Uri_Exception When authority decomposition fails - * @return void - */ - protected function _parseUri($schemeSpecific) - { - // High-level decomposition parser - $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~'; - $status = @preg_match($pattern, $schemeSpecific, $matches); - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed'); - } - - // Failed decomposition; no further processing needed - if ($status === false) { - return; - } - - // Save URI components that need no further decomposition - $this->_path = isset($matches[4]) === true ? $matches[4] : ''; - $this->_query = isset($matches[6]) === true ? $matches[6] : ''; - $this->_fragment = isset($matches[8]) === true ? $matches[8] : ''; - - // Additional decomposition to get username, password, host, and port - $combo = isset($matches[3]) === true ? $matches[3] : ''; - $pattern = '~^(([^:@]*)(:([^@]*))?@)?((?(?=[[])[[][^]]+[]]|[^:]+))(:(.*))?$~'; - $status = @preg_match($pattern, $combo, $matches); - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: authority decomposition failed'); - } - - // Save remaining URI components - $this->_username = isset($matches[2]) === true ? $matches[2] : ''; - $this->_password = isset($matches[4]) === true ? $matches[4] : ''; - $this->_host = isset($matches[5]) === true - ? preg_replace('~^\[([^]]+)\]$~', '\1', $matches[5]) // Strip wrapper [] from IPv6 literal - : ''; - $this->_port = isset($matches[7]) === true ? $matches[7] : ''; - } - - /** - * Returns a URI based on current values of the instance variables. If any - * part of the URI does not pass validation, then an exception is thrown. - * - * @throws Zend_Uri_Exception When one or more parts of the URI are invalid - * @return string - */ - public function getUri() - { - if ($this->valid() === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('One or more parts of the URI are invalid'); - } - - $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; - $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; - $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; - $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; - $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; - - return $this->_scheme - . '://' - . $auth - . $this->_host - . $port - . $this->_path - . $query - . $fragment; - } - - /** - * Validate the current URI from the instance variables. Returns true if and only if all - * parts pass validation. - * - * @return boolean - */ - public function valid() - { - // Return true if and only if all parts of the URI have passed validation - return $this->validateUsername() - and $this->validatePassword() - and $this->validateHost() - and $this->validatePort() - and $this->validatePath() - and $this->validateQuery() - and $this->validateFragment(); - } - - /** - * Returns the username portion of the URL, or FALSE if none. - * - * @return string - */ - public function getUsername() - { - return strlen($this->_username) > 0 ? $this->_username : false; - } - - /** - * Returns true if and only if the username passes validation. If no username is passed, - * then the username contained in the instance variable is used. - * - * @param string $username The HTTP username - * @throws Zend_Uri_Exception When username validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateUsername($username = null) - { - if ($username === null) { - $username = $this->_username; - } - - // If the username is empty, then it is considered valid - if (strlen($username) === 0) { - return true; - } - - // Check the username against the allowed values - $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . - self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username); - - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: username validation failed'); - } - - return $status === 1; - } - - /** - * Sets the username for the current URI, and returns the old username - * - * @param string $username The HTTP username - * @throws Zend_Uri_Exception When $username is not a valid HTTP username - * @return string - */ - public function setUsername($username) - { - if ($this->validateUsername($username) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username"); - } - - $oldUsername = $this->_username; - $this->_username = $username; - - return $oldUsername; - } - - /** - * Returns the password portion of the URL, or FALSE if none. - * - * @return string - */ - public function getPassword() - { - return strlen($this->_password) > 0 ? $this->_password : false; - } - - /** - * Returns true if and only if the password passes validation. If no password is passed, - * then the password contained in the instance variable is used. - * - * @param string $password The HTTP password - * @throws Zend_Uri_Exception When password validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validatePassword($password = null) - { - if ($password === null) { - $password = $this->_password; - } - - // If the password is empty, then it is considered valid - if (strlen($password) === 0) { - return true; - } - - // If the password is nonempty, but there is no username, then it is considered invalid - if (strlen($password) > 0 and strlen($this->_username) === 0) { - return false; - } - - // Check the password against the allowed values - $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . - self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password); - - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: password validation failed.'); - } - - return $status == 1; - } - - /** - * Sets the password for the current URI, and returns the old password - * - * @param string $password The HTTP password - * @throws Zend_Uri_Exception When $password is not a valid HTTP password - * @return string - */ - public function setPassword($password) - { - if ($this->validatePassword($password) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password."); - } - - $oldPassword = $this->_password; - $this->_password = $password; - - return $oldPassword; - } - - /** - * Returns the domain or host IP portion of the URL, or FALSE if none. - * - * @return string - */ - public function getHost() - { - return strlen($this->_host) > 0 ? $this->_host : false; - } - - /** - * Returns true if and only if the host string passes validation. If no host is passed, - * then the host contained in the instance variable is used. - * - * @param string $host The HTTP host - * @return boolean - * @uses Zend_Filter - */ - public function validateHost($host = null) - { - if ($host === null) { - $host = $this->_host; - } - - // If the host is empty, then it is considered invalid - if (strlen($host) === 0) { - return false; - } - - // Check the host against the allowed values; delegated to Zend_Filter. - $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL); - - return $validate->isValid($host); - } - - /** - * Sets the host for the current URI, and returns the old host - * - * @param string $host The HTTP host - * @throws Zend_Uri_Exception When $host is nota valid HTTP host - * @return string - */ - public function setHost($host) - { - if ($this->validateHost($host) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host"); - } - - $oldHost = $this->_host; - $this->_host = $host; - - return $oldHost; - } - - /** - * Returns the TCP port, or FALSE if none. - * - * @return string - */ - public function getPort() - { - return strlen($this->_port) > 0 ? $this->_port : false; - } - - /** - * Returns true if and only if the TCP port string passes validation. If no port is passed, - * then the port contained in the instance variable is used. - * - * @param string $port The HTTP port - * @return boolean - */ - public function validatePort($port = null) - { - if ($port === null) { - $port = $this->_port; - } - - // If the port is empty, then it is considered valid - if (strlen($port) === 0) { - return true; - } - - // Check the port against the allowed values - return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; - } - - /** - * Sets the port for the current URI, and returns the old port - * - * @param string $port The HTTP port - * @throws Zend_Uri_Exception When $port is not a valid HTTP port - * @return string - */ - public function setPort($port) - { - if ($this->validatePort($port) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port."); - } - - $oldPort = $this->_port; - $this->_port = $port; - - return $oldPort; - } - - /** - * Returns the path and filename portion of the URL. - * - * @return string - */ - public function getPath() - { - return strlen($this->_path) > 0 ? $this->_path : '/'; - } - - /** - * Returns true if and only if the path string passes validation. If no path is passed, - * then the path contained in the instance variable is used. - * - * @param string $path The HTTP path - * @throws Zend_Uri_Exception When path validation fails - * @return boolean - */ - public function validatePath($path = null) - { - if ($path === null) { - $path = $this->_path; - } - - // If the path is empty, then it is considered valid - if (strlen($path) === 0) { - return true; - } - - // Determine whether the path is well-formed - $pattern = '/^' . $this->_regex['path'] . '$/'; - $status = @preg_match($pattern, $path); - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: path validation failed'); - } - - return (boolean) $status; - } - - /** - * Sets the path for the current URI, and returns the old path - * - * @param string $path The HTTP path - * @throws Zend_Uri_Exception When $path is not a valid HTTP path - * @return string - */ - public function setPath($path) - { - if ($this->validatePath($path) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path"); - } - - $oldPath = $this->_path; - $this->_path = $path; - - return $oldPath; - } - - /** - * Returns the query portion of the URL (after ?), or FALSE if none. - * - * @return string - */ - public function getQuery() - { - return strlen($this->_query) > 0 ? $this->_query : false; - } - - /** - * Returns the query portion of the URL (after ?) as a - * key-value-array. If the query is empty an empty array - * is returned - * - * @return array - */ - public function getQueryAsArray() - { - $query = $this->getQuery(); - $querryArray = array(); - if ($query !== false) { - parse_str($query, $querryArray); - } - return $querryArray; - } - - /** - * Returns true if and only if the query string passes validation. If no query is passed, - * then the query string contained in the instance variable is used. - * - * @param string $query The query to validate - * @throws Zend_Uri_Exception When query validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateQuery($query = null) - { - if ($query === null) { - $query = $this->_query; - } - - // If query is empty, it is considered to be valid - if (strlen($query) === 0) { - return true; - } - - // Determine whether the query is well-formed - $pattern = '/^' . $this->_regex['uric'] . '*$/'; - $status = @preg_match($pattern, $query); - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: query validation failed'); - } - - return $status == 1; - } - - /** - * Add or replace params in the query string for the current URI, and - * return the old query. - * - * @param array $queryParams - * @return string Old query string - */ - public function addReplaceQueryParameters(array $queryParams) - { - $queryParams = array_merge($this->getQueryAsArray(), $queryParams); - return $this->setQuery($queryParams); - } - - /** - * Remove params in the query string for the current URI, and - * return the old query. - * - * @param array $queryParamKeys - * @return string Old query string - */ - public function removeQueryParameters(array $queryParamKeys) - { - $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0)); - return $this->setQuery($queryParams); - } - - /** - * Set the query string for the current URI, and return the old query - * string This method accepts both strings and arrays. - * - * @param string|array $query The query string or array - * @throws Zend_Uri_Exception When $query is not a valid query string - * @return string Old query string - */ - public function setQuery($query) - { - $oldQuery = $this->_query; - - // If query is empty, set an empty string - if (empty($query) === true) { - $this->_query = ''; - return $oldQuery; - } - - // If query is an array, make a string out of it - if (is_array($query) === true) { - $query = http_build_query($query, '', '&'); - } else { - // If it is a string, make sure it is valid. If not parse and encode it - $query = (string) $query; - if ($this->validateQuery($query) === false) { - parse_str($query, $queryArray); - $query = http_build_query($queryArray, '', '&'); - } - } - - // Make sure the query is valid, and set it - if ($this->validateQuery($query) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("'$query' is not a valid query string"); - } - - $this->_query = $query; - - return $oldQuery; - } - - /** - * Returns the fragment portion of the URL (after #), or FALSE if none. - * - * @return string|false - */ - public function getFragment() - { - return strlen($this->_fragment) > 0 ? $this->_fragment : false; - } - - /** - * Returns true if and only if the fragment passes validation. If no fragment is passed, - * then the fragment contained in the instance variable is used. - * - * @param string $fragment Fragment of an URI - * @throws Zend_Uri_Exception When fragment validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateFragment($fragment = null) - { - if ($fragment === null) { - $fragment = $this->_fragment; - } - - // If fragment is empty, it is considered to be valid - if (strlen($fragment) === 0) { - return true; - } - - // Determine whether the fragment is well-formed - $pattern = '/^' . $this->_regex['uric'] . '*$/'; - $status = @preg_match($pattern, $fragment); - if ($status === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: fragment validation failed'); - } - - return (boolean) $status; - } - - /** - * Sets the fragment for the current URI, and returns the old fragment - * - * @param string $fragment Fragment of the current URI - * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment - * @return string - */ - public function setFragment($fragment) - { - if ($this->validateFragment($fragment) === false) { - #require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment"); - } - - $oldFragment = $this->_fragment; - $this->_fragment = $fragment; - - return $oldFragment; - } -} diff --git a/lib/Zend/Validate.php b/lib/Zend/Validate.php deleted file mode 100644 index 59b0d7f9ce4..00000000000 --- a/lib/Zend/Validate.php +++ /dev/null @@ -1,290 +0,0 @@ -_validators[] = array( - 'instance' => $validator, - 'breakChainOnFailure' => (boolean) $breakChainOnFailure - ); - return $this; - } - - /** - * Returns true if and only if $value passes all validations in the chain - * - * Validators are run in the order in which they were added to the chain (FIFO). - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_messages = array(); - $this->_errors = array(); - $result = true; - foreach ($this->_validators as $element) { - $validator = $element['instance']; - if ($validator->isValid($value)) { - continue; - } - $result = false; - $messages = $validator->getMessages(); - $this->_messages = array_merge($this->_messages, $messages); - $this->_errors = array_merge($this->_errors, array_keys($messages)); - if ($element['breakChainOnFailure']) { - break; - } - } - return $result; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns array of validation failure messages - * - * @return array - */ - public function getMessages() - { - return $this->_messages; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns array of validation failure message codes - * - * @return array - * @deprecated Since 1.5.0 - */ - public function getErrors() - { - return $this->_errors; - } - - /** - * Returns the set default namespaces - * - * @return array - */ - public static function getDefaultNamespaces() - { - return self::$_defaultNamespaces; - } - - /** - * Sets new default namespaces - * - * @param array|string $namespace - * @return null - */ - public static function setDefaultNamespaces($namespace) - { - if (!is_array($namespace)) { - $namespace = array((string) $namespace); - } - - self::$_defaultNamespaces = $namespace; - } - - /** - * Adds a new default namespace - * - * @param array|string $namespace - * @return null - */ - public static function addDefaultNamespaces($namespace) - { - if (!is_array($namespace)) { - $namespace = array((string) $namespace); - } - - self::$_defaultNamespaces = array_unique(array_merge(self::$_defaultNamespaces, $namespace)); - } - - /** - * Returns true when defaultNamespaces are set - * - * @return boolean - */ - public static function hasDefaultNamespaces() - { - return (!empty(self::$_defaultNamespaces)); - } - - /** - * @param mixed $value - * @param string $classBaseName - * @param array $args OPTIONAL - * @param mixed $namespaces OPTIONAL - * @return boolean - * @throws Zend_Validate_Exception - */ - public static function is($value, $classBaseName, array $args = array(), $namespaces = array()) - { - $namespaces = array_merge((array) $namespaces, self::$_defaultNamespaces, array('Zend_Validate')); - $className = ucfirst($classBaseName); - try { - if (!class_exists($className, false)) { - #require_once 'Zend/Loader.php'; - foreach($namespaces as $namespace) { - $class = $namespace . '_' . $className; - $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; - if (Zend_Loader::isReadable($file)) { - Zend_Loader::loadClass($class); - $className = $class; - break; - } - } - } - - $class = new ReflectionClass($className); - if ($class->implementsInterface('Zend_Validate_Interface')) { - if ($class->hasMethod('__construct')) { - $keys = array_keys($args); - $numeric = false; - foreach($keys as $key) { - if (is_numeric($key)) { - $numeric = true; - break; - } - } - - if ($numeric) { - $object = $class->newInstanceArgs($args); - } else { - $object = $class->newInstance($args); - } - } else { - $object = $class->newInstance(); - } - - return $object->isValid($value); - } - } catch (Zend_Validate_Exception $ze) { - // if there is an exception while validating throw it - throw $ze; - } catch (Exception $e) { - // fallthrough and continue for missing validation classes - } - - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Validate class not found from basename '$classBaseName'"); - } - - /** - * Returns the maximum allowed message length - * - * @return integer - */ - public static function getMessageLength() - { - #require_once 'Zend/Validate/Abstract.php'; - return Zend_Validate_Abstract::getMessageLength(); - } - - /** - * Sets the maximum allowed message length - * - * @param integer $length - */ - public static function setMessageLength($length = -1) - { - #require_once 'Zend/Validate/Abstract.php'; - Zend_Validate_Abstract::setMessageLength($length); - } - - /** - * Returns the default translation object - * - * @return Zend_Translate_Adapter|null - */ - public static function getDefaultTranslator($translator = null) - { - #require_once 'Zend/Validate/Abstract.php'; - return Zend_Validate_Abstract::getDefaultTranslator(); - } - - /** - * Sets a default translation object for all validation objects - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - */ - public static function setDefaultTranslator($translator = null) - { - #require_once 'Zend/Validate/Abstract.php'; - Zend_Validate_Abstract::setDefaultTranslator($translator); - } -} diff --git a/lib/Zend/Validate/Abstract.php b/lib/Zend/Validate/Abstract.php deleted file mode 100644 index 0e6d0a494ed..00000000000 --- a/lib/Zend/Validate/Abstract.php +++ /dev/null @@ -1,483 +0,0 @@ -_messages; - } - - /** - * Returns an array of the names of variables that are used in constructing validation failure messages - * - * @return array - */ - public function getMessageVariables() - { - return array_keys($this->_messageVariables); - } - - /** - * Returns the message templates from the validator - * - * @return array - */ - public function getMessageTemplates() - { - return $this->_messageTemplates; - } - - /** - * Sets the validation failure message template for a particular key - * - * @param string $messageString - * @param string $messageKey OPTIONAL - * @return Zend_Validate_Abstract Provides a fluent interface - * @throws Zend_Validate_Exception - */ - public function setMessage($messageString, $messageKey = null) - { - if ($messageKey === null) { - $keys = array_keys($this->_messageTemplates); - foreach($keys as $key) { - $this->setMessage($messageString, $key); - } - return $this; - } - - if (!isset($this->_messageTemplates[$messageKey])) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("No message template exists for key '$messageKey'"); - } - - $this->_messageTemplates[$messageKey] = $messageString; - return $this; - } - - /** - * Sets validation failure message templates given as an array, where the array keys are the message keys, - * and the array values are the message template strings. - * - * @param array $messages - * @return Zend_Validate_Abstract - */ - public function setMessages(array $messages) - { - foreach ($messages as $key => $message) { - $this->setMessage($message, $key); - } - return $this; - } - - /** - * Magic function returns the value of the requested property, if and only if it is the value or a - * message variable. - * - * @param string $property - * @return mixed - * @throws Zend_Validate_Exception - */ - public function __get($property) - { - if ($property == 'value') { - return $this->_value; - } - if (array_key_exists($property, $this->_messageVariables)) { - return $this->{$this->_messageVariables[$property]}; - } - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("No property exists by the name '$property'"); - } - - /** - * Constructs and returns a validation failure message with the given message key and value. - * - * Returns null if and only if $messageKey does not correspond to an existing template. - * - * If a translator is available and a translation exists for $messageKey, - * the translation will be used. - * - * @param string $messageKey - * @param string $value - * @return string - */ - protected function _createMessage($messageKey, $value) - { - if (!isset($this->_messageTemplates[$messageKey])) { - return null; - } - - $message = $this->_messageTemplates[$messageKey]; - - if (null !== ($translator = $this->getTranslator())) { - if ($translator->isTranslated($messageKey)) { - $message = $translator->translate($messageKey); - } else { - $message = $translator->translate($message); - } - } - - if (is_object($value)) { - if (!in_array('__toString', get_class_methods($value))) { - $value = get_class($value) . ' object'; - } else { - $value = $value->__toString(); - } - } elseif (is_array($value)) { - $value = $this->_implodeRecursive($value); - } else { - $value = implode((array) $value); - } - - if ($this->getObscureValue()) { - $value = str_repeat('*', strlen($value)); - } - - $message = str_replace('%value%', $value, $message); - foreach ($this->_messageVariables as $ident => $property) { - $message = str_replace( - "%$ident%", - implode(' ', (array) $this->$property), - $message - ); - } - - $length = self::getMessageLength(); - if (($length > -1) && (strlen($message) > $length)) { - $message = substr($message, 0, (self::getMessageLength() - 3)) . '...'; - } - - return $message; - } - - /** - * Joins elements of a multidimensional array - * - * @param array $pieces - * @return string - */ - protected function _implodeRecursive(array $pieces) - { - $values = array(); - foreach ($pieces as $item) { - if (is_array($item)) { - $values[] = $this->_implodeRecursive($item); - } else { - $values[] = $item; - } - } - - return implode(', ', $values); - } - - /** - * @param string $messageKey - * @param string $value OPTIONAL - * @return void - */ - protected function _error($messageKey, $value = null) - { - if ($messageKey === null) { - $keys = array_keys($this->_messageTemplates); - $messageKey = current($keys); - } - if ($value === null) { - $value = $this->_value; - } - $this->_errors[] = $messageKey; - $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value); - } - - /** - * Sets the value to be validated and clears the messages and errors arrays - * - * @param mixed $value - * @return void - */ - protected function _setValue($value) - { - $this->_value = $value; - $this->_messages = array(); - $this->_errors = array(); - } - - /** - * Returns array of validation failure message codes - * - * @return array - * @deprecated Since 1.5.0 - */ - public function getErrors() - { - return $this->_errors; - } - - /** - * Set flag indicating whether or not value should be obfuscated in messages - * - * @param bool $flag - * @return Zend_Validate_Abstract - */ - public function setObscureValue($flag) - { - $this->_obscureValue = (bool) $flag; - return $this; - } - - /** - * Retrieve flag indicating whether or not value should be obfuscated in - * messages - * - * @return bool - */ - public function getObscureValue() - { - return $this->_obscureValue; - } - - /** - * Set translation object - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - * @throws Zend_Validate_Exception - * @return Zend_Validate_Abstract - */ - public function setTranslator($translator = null) - { - if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) { - $this->_translator = $translator; - } elseif ($translator instanceof Zend_Translate) { - $this->_translator = $translator->getAdapter(); - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid translator specified'); - } - return $this; - } - - /** - * Return translation object - * - * @return Zend_Translate_Adapter|null - */ - public function getTranslator() - { - if ($this->translatorIsDisabled()) { - return null; - } - - if (null === $this->_translator) { - return self::getDefaultTranslator(); - } - - return $this->_translator; - } - - /** - * Does this validator have its own specific translator? - * - * @return bool - */ - public function hasTranslator() - { - return (bool)$this->_translator; - } - - /** - * Set default translation object for all validate objects - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - * @throws Zend_Validate_Exception - */ - public static function setDefaultTranslator($translator = null) - { - if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) { - self::$_defaultTranslator = $translator; - } elseif ($translator instanceof Zend_Translate) { - self::$_defaultTranslator = $translator->getAdapter(); - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid translator specified'); - } - } - - /** - * Get default translation object for all validate objects - * - * @return Zend_Translate_Adapter|null - */ - public static function getDefaultTranslator() - { - if (null === self::$_defaultTranslator) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Translate')) { - $translator = Zend_Registry::get('Zend_Translate'); - if ($translator instanceof Zend_Translate_Adapter) { - return $translator; - } elseif ($translator instanceof Zend_Translate) { - return $translator->getAdapter(); - } - } - } - - return self::$_defaultTranslator; - } - - /** - * Is there a default translation object set? - * - * @return boolean - */ - public static function hasDefaultTranslator() - { - return (bool)self::$_defaultTranslator; - } - - /** - * Indicate whether or not translation should be disabled - * - * @param bool $flag - * @return Zend_Validate_Abstract - */ - public function setDisableTranslator($flag) - { - $this->_translatorDisabled = (bool) $flag; - return $this; - } - - /** - * Is translation disabled? - * - * @return bool - */ - public function translatorIsDisabled() - { - return $this->_translatorDisabled; - } - - /** - * Returns the maximum allowed message length - * - * @return integer - */ - public static function getMessageLength() - { - return self::$_messageLength; - } - - /** - * Sets the maximum allowed message length - * - * @param integer $length - */ - public static function setMessageLength($length = -1) - { - self::$_messageLength = $length; - } -} diff --git a/lib/Zend/Validate/Alnum.php b/lib/Zend/Validate/Alnum.php deleted file mode 100644 index 5a2d8994a07..00000000000 --- a/lib/Zend/Validate/Alnum.php +++ /dev/null @@ -1,149 +0,0 @@ - "Invalid type given. String, integer or float expected", - self::NOT_ALNUM => "'%value%' contains characters which are non alphabetic and no digits", - self::STRING_EMPTY => "'%value%' is an empty string", - ); - - /** - * Sets default option values for this instance - * - * @param boolean|Zend_Config $allowWhiteSpace - */ - public function __construct($allowWhiteSpace = false) - { - if ($allowWhiteSpace instanceof Zend_Config) { - $allowWhiteSpace = $allowWhiteSpace->toArray(); - } - - if (is_array($allowWhiteSpace)) { - if (array_key_exists('allowWhiteSpace', $allowWhiteSpace)) { - $allowWhiteSpace = $allowWhiteSpace['allowWhiteSpace']; - } else { - $allowWhiteSpace = false; - } - } - - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - } - - /** - * Returns the allowWhiteSpace option - * - * @return boolean - */ - public function getAllowWhiteSpace() - { - return $this->allowWhiteSpace; - } - - /** - * Sets the allowWhiteSpace option - * - * @param boolean $allowWhiteSpace - * @return Zend_Filter_Alnum Provides a fluent interface - */ - public function setAllowWhiteSpace($allowWhiteSpace) - { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only alphabetic and digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - - if ('' === $value) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Alnum - */ - #require_once 'Zend/Filter/Alnum.php'; - self::$_filter = new Zend_Filter_Alnum(); - } - - self::$_filter->allowWhiteSpace = $this->allowWhiteSpace; - - if ($value != self::$_filter->filter($value)) { - $this->_error(self::NOT_ALNUM); - return false; - } - - return true; - } - -} diff --git a/lib/Zend/Validate/Alpha.php b/lib/Zend/Validate/Alpha.php deleted file mode 100644 index 6c356853374..00000000000 --- a/lib/Zend/Validate/Alpha.php +++ /dev/null @@ -1,149 +0,0 @@ - "Invalid type given. String expected", - self::NOT_ALPHA => "'%value%' contains non alphabetic characters", - self::STRING_EMPTY => "'%value%' is an empty string" - ); - - /** - * Sets default option values for this instance - * - * @param boolean|Zend_Config $allowWhiteSpace - */ - public function __construct($allowWhiteSpace = false) - { - if ($allowWhiteSpace instanceof Zend_Config) { - $allowWhiteSpace = $allowWhiteSpace->toArray(); - } - - if (is_array($allowWhiteSpace)) { - if (array_key_exists('allowWhiteSpace', $allowWhiteSpace)) { - $allowWhiteSpace = $allowWhiteSpace['allowWhiteSpace']; - } else { - $allowWhiteSpace = false; - } - } - - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - } - - /** - * Returns the allowWhiteSpace option - * - * @return boolean - */ - public function getAllowWhiteSpace() - { - return $this->allowWhiteSpace; - } - - /** - * Sets the allowWhiteSpace option - * - * @param boolean $allowWhiteSpace - * @return Zend_Filter_Alpha Provides a fluent interface - */ - public function setAllowWhiteSpace($allowWhiteSpace) - { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only alphabetic characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - - if ('' === $value) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Alpha - */ - #require_once 'Zend/Filter/Alpha.php'; - self::$_filter = new Zend_Filter_Alpha(); - } - - self::$_filter->allowWhiteSpace = $this->allowWhiteSpace; - - if ($value !== self::$_filter->filter($value)) { - $this->_error(self::NOT_ALPHA); - return false; - } - - return true; - } - -} diff --git a/lib/Zend/Validate/Barcode.php b/lib/Zend/Validate/Barcode.php deleted file mode 100644 index 642ccb20208..00000000000 --- a/lib/Zend/Validate/Barcode.php +++ /dev/null @@ -1,227 +0,0 @@ - "'%value%' failed checksum validation", - self::INVALID_CHARS => "'%value%' contains invalid characters", - self::INVALID_LENGTH => "'%value%' should have a length of %length% characters", - self::INVALID => "Invalid type given. String expected", - ); - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $_messageVariables = array( - 'length' => '_length' - ); - - /** - * Length for the set subtype - * - * @var integer - */ - protected $_length; - - /** - * Barcode adapter - * - * @var Zend_Validate_Barcode_BarcodeAdapter - */ - protected $_adapter; - - /** - * Generates the standard validator object - * - * @param string|Zend_Config| - * Zend_Validate_Barcode_BarcodeAdapter $adapter Barcode adapter to use - * @throws Zend_Validate_Exception - */ - public function __construct($adapter) - { - if ($adapter instanceof Zend_Config) { - $adapter = $adapter->toArray(); - } - - $options = null; - $checksum = null; - if (is_array($adapter)) { - if (array_key_exists('options', $adapter)) { - $options = $adapter['options']; - } - - if (array_key_exists('checksum', $adapter)) { - $checksum = $adapter['checksum']; - } - - if (array_key_exists('adapter', $adapter)) { - $adapter = $adapter['adapter']; - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Missing option 'adapter'"); - } - } - - $this->setAdapter($adapter, $options); - if ($checksum !== null) { - $this->setChecksum($checksum); - } - } - - /** - * Returns the set adapter - * - * @return Zend_Validate_Barcode_BarcodeAdapter - */ - public function getAdapter() - { - return $this->_adapter; - } - - /** - * Sets a new barcode adapter - * - * @param string|Zend_Validate_Barcode $adapter Barcode adapter to use - * @param array $options Options for this adapter - * @return $this - * @throws Zend_Validate_Exception - */ - public function setAdapter($adapter, $options = null) - { - $adapter = ucfirst(strtolower($adapter)); - #require_once 'Zend/Loader.php'; - if (Zend_Loader::isReadable('Zend/Validate/Barcode/' . $adapter. '.php')) { - $adapter = 'Zend_Validate_Barcode_' . $adapter; - } - - if (!class_exists($adapter)) { - Zend_Loader::loadClass($adapter); - } - - $this->_adapter = new $adapter($options); - if (!$this->_adapter instanceof Zend_Validate_Barcode_AdapterInterface) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception( - "Adapter " . $adapter . " does not implement Zend_Validate_Barcode_AdapterInterface" - ); - } - - return $this; - } - - /** - * Returns the checksum option - * - * @return boolean - */ - public function getChecksum() - { - return $this->getAdapter()->getCheck(); - } - - /** - * Sets the checksum option - * - * @param boolean $checksum - * @return Zend_Validate_Barcode - */ - public function setChecksum($checksum) - { - $this->getAdapter()->setCheck($checksum); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains a valid barcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - $adapter = $this->getAdapter(); - $this->_length = $adapter->getLength(); - $result = $adapter->checkLength($value); - if (!$result) { - if (is_array($this->_length)) { - $temp = $this->_length; - $this->_length = ""; - foreach($temp as $length) { - $this->_length .= "/"; - $this->_length .= $length; - } - - $this->_length = substr($this->_length, 1); - } - - $this->_error(self::INVALID_LENGTH); - return false; - } - - $result = $adapter->checkChars($value); - if (!$result) { - $this->_error(self::INVALID_CHARS); - return false; - } - - if ($this->getChecksum()) { - $result = $adapter->checksum($value); - if (!$result) { - $this->_error(self::FAILED); - return false; - } - } - - return true; - } -} diff --git a/lib/Zend/Validate/Barcode/AdapterAbstract.php b/lib/Zend/Validate/Barcode/AdapterAbstract.php deleted file mode 100644 index 30cf0e1798c..00000000000 --- a/lib/Zend/Validate/Barcode/AdapterAbstract.php +++ /dev/null @@ -1,315 +0,0 @@ -getLength(); - if (is_array($length)) { - foreach ($length as $value) { - if ($fixum == $value) { - $found = true; - } - - if ($value == -1) { - $found = true; - } - } - } elseif ($fixum == $length) { - $found = true; - } elseif ($length == -1) { - $found = true; - } elseif ($length == 'even') { - $count = $fixum % 2; - $found = ($count == 0) ? true : false; - } elseif ($length == 'odd') { - $count = $fixum % 2; - $found = ($count == 1) ? true : false; - } - - return $found; - } - - /** - * Checks for allowed characters within the barcode - * - * @param string $value The barcode to check for allowed characters - * @return boolean - */ - public function checkChars($value) - { - if (!is_string($value)) { - return false; - } - - $characters = $this->getCharacters(); - if ($characters == 128) { - for ($x = 0; $x < 128; ++$x) { - $value = str_replace(chr($x), '', $value); - } - } else { - $chars = str_split($characters); - foreach ($chars as $char) { - $value = str_replace($char, '', $value); - } - } - - if (strlen($value) > 0) { - return false; - } - - return true; - } - - /** - * Validates the checksum - * - * @param string $value The barcode to check the checksum for - * @return boolean - */ - public function checksum($value) - { - $checksum = $this->getChecksum(); - if (!empty($checksum)) { - if (method_exists($this, $checksum)) { - return call_user_func(array($this, $checksum), $value); - } - } - - return false; - } - - /** - * Returns the allowed barcode length - * - * @return string - */ - public function getLength() - { - return $this->_length; - } - - /** - * Returns the allowed characters - * - * @return integer|string - */ - public function getCharacters() - { - return $this->_characters; - } - - /** - * Returns the checksum function name - * - */ - public function getChecksum() - { - return $this->_checksum; - } - - /** - * Returns if barcode uses checksum - * - * @return boolean - */ - public function getCheck() - { - return $this->_hasChecksum; - } - - /** - * Sets the checksum validation - * - * @param boolean $check - * @return Zend_Validate_Barcode_AdapterAbstract - */ - public function setCheck($check) - { - $this->_hasChecksum = (boolean) $check; - return $this; - } - - /** - * Validates the checksum (Modulo 10) - * GTIN implementation factor 3 - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _gtin($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($barcode) - 1; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$length - $i] * 3; - } else { - $sum += $barcode[$length - $i]; - } - } - - $calc = $sum % 10; - $checksum = ($calc === 0) ? 0 : (10 - $calc); - if ($value[$length + 1] != $checksum) { - return false; - } - - return true; - } - - /** - * Validates the checksum (Modulo 10) - * IDENTCODE implementation factors 9 and 4 - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _identcode($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($value) - 2; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$length - $i] * 4; - } else { - $sum += $barcode[$length - $i] * 9; - } - } - - $calc = $sum % 10; - $checksum = ($calc === 0) ? 0 : (10 - $calc); - if ($value[$length + 1] != $checksum) { - return false; - } - - return true; - } - - /** - * Validates the checksum (Modulo 10) - * CODE25 implementation factor 3 - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _code25($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($barcode) - 1; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$i] * 3; - } else { - $sum += $barcode[$i]; - } - } - - $calc = $sum % 10; - $checksum = ($calc === 0) ? 0 : (10 - $calc); - if ($value[$length + 1] != $checksum) { - return false; - } - - return true; - } - - /** - * Validates the checksum () - * POSTNET implementation - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _postnet($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - - $check = 0; - foreach($values as $row) { - $check += $row; - } - - $check %= 10; - $check = 10 - $check; - if ($check == $checksum) { - return true; - } - - return false; - } -} diff --git a/lib/Zend/Validate/Barcode/AdapterInterface.php b/lib/Zend/Validate/Barcode/AdapterInterface.php deleted file mode 100644 index 8e96effbf46..00000000000 --- a/lib/Zend/Validate/Barcode/AdapterInterface.php +++ /dev/null @@ -1,68 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Code25interleaved.php b/lib/Zend/Validate/Barcode/Code25interleaved.php deleted file mode 100644 index 85ca0fbed52..00000000000 --- a/lib/Zend/Validate/Barcode/Code25interleaved.php +++ /dev/null @@ -1,62 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Code39.php b/lib/Zend/Validate/Barcode/Code39.php deleted file mode 100644 index 5b2322a839d..00000000000 --- a/lib/Zend/Validate/Barcode/Code39.php +++ /dev/null @@ -1,98 +0,0 @@ - 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, - '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, - 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, - 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, - 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, - 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, - '%' => 42, - ); - - /** - * Constructor - * - * Sets check flag to false. - */ - public function __construct() - { - $this->setCheck(false); - } - - /** - * Validates the checksum (Modulo 43) - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _code39($value) - { - $checksum = substr($value, -1, 1); - $value = str_split(substr($value, 0, -1)); - $count = 0; - foreach($value as $char) { - $count += $this->_check[$char]; - } - - $mod = $count % 43; - if ($mod == $this->_check[$checksum]) { - return true; - } - - return false; - } -} diff --git a/lib/Zend/Validate/Barcode/Code39ext.php b/lib/Zend/Validate/Barcode/Code39ext.php deleted file mode 100644 index 2e601722f97..00000000000 --- a/lib/Zend/Validate/Barcode/Code39ext.php +++ /dev/null @@ -1,56 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Code93.php b/lib/Zend/Validate/Barcode/Code93.php deleted file mode 100644 index d820675c218..00000000000 --- a/lib/Zend/Validate/Barcode/Code93.php +++ /dev/null @@ -1,118 +0,0 @@ - 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, - '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, - 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, - 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, - 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, - 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, - '%' => 42, '!' => 43, '"' => 44, '§' => 45, '&' => 46, - ); - - /** - * Constructor - * - * Sets check flag to false. - */ - public function __construct() - { - $this->setCheck(false); - } - - /** - * Validates the checksum (Modulo CK) - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _code93($value) - { - $checksum = substr($value, -2, 2); - $value = str_split(substr($value, 0, -2)); - $count = 0; - $length = count($value) % 20; - foreach($value as $char) { - if ($length == 0) { - $length = 20; - } - - $count += $this->_check[$char] * $length; - --$length; - } - - $check = array_search(($count % 47), $this->_check); - $value[] = $check; - $count = 0; - $length = count($value) % 15; - foreach($value as $char) { - if ($length == 0) { - $length = 15; - } - - $count += $this->_check[$char] * $length; - --$length; - } - $check .= array_search(($count % 47), $this->_check); - - if ($check == $checksum) { - return true; - } - - return false; - } -} diff --git a/lib/Zend/Validate/Barcode/Code93ext.php b/lib/Zend/Validate/Barcode/Code93ext.php deleted file mode 100644 index aa45280674a..00000000000 --- a/lib/Zend/Validate/Barcode/Code93ext.php +++ /dev/null @@ -1,56 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Ean12.php b/lib/Zend/Validate/Barcode/Ean12.php deleted file mode 100644 index 220a310a958..00000000000 --- a/lib/Zend/Validate/Barcode/Ean12.php +++ /dev/null @@ -1,52 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Ean5.php b/lib/Zend/Validate/Barcode/Ean5.php deleted file mode 100644 index ea27ec20097..00000000000 --- a/lib/Zend/Validate/Barcode/Ean5.php +++ /dev/null @@ -1,56 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Ean8.php b/lib/Zend/Validate/Barcode/Ean8.php deleted file mode 100644 index 9470c5dac74..00000000000 --- a/lib/Zend/Validate/Barcode/Ean8.php +++ /dev/null @@ -1,69 +0,0 @@ -setCheck(false); - } else { - $this->setCheck(true); - } - - return parent::checkLength($value); - } -} diff --git a/lib/Zend/Validate/Barcode/Gtin12.php b/lib/Zend/Validate/Barcode/Gtin12.php deleted file mode 100644 index 306aee37178..00000000000 --- a/lib/Zend/Validate/Barcode/Gtin12.php +++ /dev/null @@ -1,52 +0,0 @@ -setCheck(false); - } -} diff --git a/lib/Zend/Validate/Barcode/Issn.php b/lib/Zend/Validate/Barcode/Issn.php deleted file mode 100644 index 78cc55bc43d..00000000000 --- a/lib/Zend/Validate/Barcode/Issn.php +++ /dev/null @@ -1,119 +0,0 @@ -_checksum = '_issn'; - } else { - $this->_checksum = '_gtin'; - } - - return parent::checksum($value); - } - - /** - * Validates the checksum () - * ISSN implementation (reversed mod11) - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _issn($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - $check = 0; - $multi = 8; - foreach($values as $token) { - if ($token == 'X') { - $token = 10; - } - - $check += ($token * $multi); - --$multi; - } - - $check %= 11; - $check = 11 - $check; - if ($check == $checksum) { - return true; - } else if (($check == 10) && ($checksum == 'X')) { - return true; - } - - return false; - } -} diff --git a/lib/Zend/Validate/Barcode/Itf14.php b/lib/Zend/Validate/Barcode/Itf14.php deleted file mode 100644 index 62ec87756a7..00000000000 --- a/lib/Zend/Validate/Barcode/Itf14.php +++ /dev/null @@ -1,52 +0,0 @@ - 1, '1' => 1, '2' => 1, '3' => 1, '4' => 1, '5' => 1, - '6' => 2, '7' => 2, '8' => 2, '9' => 2, 'A' => 2, 'B' => 2, - 'C' => 3, 'D' => 3, 'E' => 3, 'F' => 3, 'G' => 3, 'H' => 3, - 'I' => 4, 'J' => 4, 'K' => 4, 'L' => 4, 'M' => 4, 'N' => 4, - 'O' => 5, 'P' => 5, 'Q' => 5, 'R' => 5, 'S' => 5, 'T' => 5, - 'U' => 0, 'V' => 0, 'W' => 0, 'X' => 0, 'Y' => 0, 'Z' => 0, - ); - - protected $_columns = array( - '0' => 1, '1' => 2, '2' => 3, '3' => 4, '4' => 5, '5' => 0, - '6' => 1, '7' => 2, '8' => 3, '9' => 4, 'A' => 5, 'B' => 0, - 'C' => 1, 'D' => 2, 'E' => 3, 'F' => 4, 'G' => 5, 'H' => 0, - 'I' => 1, 'J' => 2, 'K' => 3, 'L' => 4, 'M' => 5, 'N' => 0, - 'O' => 1, 'P' => 2, 'Q' => 3, 'R' => 4, 'S' => 5, 'T' => 0, - 'U' => 1, 'V' => 2, 'W' => 3, 'X' => 4, 'Y' => 5, 'Z' => 0, - ); - - /** - * Checksum function - * @var string - */ - protected $_checksum = '_royalmail'; - - /** - * Validates the checksum () - * - * @param string $value The barcode to validate - * @return boolean - */ - protected function _royalmail($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - $rowvalue = 0; - $colvalue = 0; - foreach($values as $row) { - $rowvalue += $this->_rows[$row]; - $colvalue += $this->_columns[$row]; - } - - $rowvalue %= 6; - $colvalue %= 6; - - $rowchkvalue = array_keys($this->_rows, $rowvalue); - $colchkvalue = array_keys($this->_columns, $colvalue); - $chkvalue = current(array_intersect($rowchkvalue, $colchkvalue)); - if ($chkvalue == $checksum) { - return true; - } - - return false; - } - - /** - * Allows start and stop tag within checked chars - * - * @param string $value The barcode to check for allowed characters - * @return boolean - */ - public function checkChars($value) - { - if ($value[0] == '(') { - $value = substr($value, 1); - - if ($value[strlen($value) - 1] == ')') { - $value = substr($value, 0, -1); - } else { - return false; - } - } - - return parent::checkChars($value); - } -} diff --git a/lib/Zend/Validate/Barcode/Sscc.php b/lib/Zend/Validate/Barcode/Sscc.php deleted file mode 100644 index 2172b452302..00000000000 --- a/lib/Zend/Validate/Barcode/Sscc.php +++ /dev/null @@ -1,52 +0,0 @@ -setCheck(false); - } else { - $this->setCheck(true); - } - - return parent::checkLength($value); - } -} diff --git a/lib/Zend/Validate/Between.php b/lib/Zend/Validate/Between.php deleted file mode 100644 index 4f40e9ff16e..00000000000 --- a/lib/Zend/Validate/Between.php +++ /dev/null @@ -1,224 +0,0 @@ - "'%value%' is not between '%min%' and '%max%', inclusively", - self::NOT_BETWEEN_STRICT => "'%value%' is not strictly between '%min%' and '%max%'" - ); - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum value - * - * @var mixed - */ - protected $_min; - - /** - * Maximum value - * - * @var mixed - */ - protected $_max; - - /** - * Whether to do inclusive comparisons, allowing equivalence to min and/or max - * - * If false, then strict comparisons are done, and the value may equal neither - * the min nor max options - * - * @var boolean - */ - protected $_inclusive; - - /** - * Sets validator options - * Accepts the following option keys: - * 'min' => scalar, minimum border - * 'max' => scalar, maximum border - * 'inclusive' => boolean, inclusive border values - * - * @param array|Zend_Config $options - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['min'] = array_shift($options); - if (!empty($options)) { - $temp['max'] = array_shift($options); - } - - if (!empty($options)) { - $temp['inclusive'] = array_shift($options); - } - - $options = $temp; - } - - if (!array_key_exists('min', $options) || !array_key_exists('max', $options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Missing option. 'min' and 'max' has to be given"); - } - - if (!array_key_exists('inclusive', $options)) { - $options['inclusive'] = true; - } - - $this->setMin($options['min']) - ->setMax($options['max']) - ->setInclusive($options['inclusive']); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param mixed $min - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setMin($min) - { - $this->_min = $min; - return $this; - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param mixed $max - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setMax($max) - { - $this->_max = $max; - return $this; - } - - /** - * Returns the inclusive option - * - * @return boolean - */ - public function getInclusive() - { - return $this->_inclusive; - } - - /** - * Sets the inclusive option - * - * @param boolean $inclusive - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setInclusive($inclusive) - { - $this->_inclusive = $inclusive; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is between min and max options, inclusively - * if inclusive option is true. - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if ($this->_inclusive) { - if ($this->_min > $value || $value > $this->_max) { - $this->_error(self::NOT_BETWEEN); - return false; - } - } else { - if ($this->_min >= $value || $value >= $this->_max) { - $this->_error(self::NOT_BETWEEN_STRICT); - return false; - } - } - return true; - } - -} diff --git a/lib/Zend/Validate/Callback.php b/lib/Zend/Validate/Callback.php deleted file mode 100644 index 7fbfdaa7dd5..00000000000 --- a/lib/Zend/Validate/Callback.php +++ /dev/null @@ -1,173 +0,0 @@ - "'%value%' is not valid", - self::INVALID_CALLBACK => "An exception has been raised within the callback", - ); - - /** - * Callback in a call_user_func format - * - * @var string|array - */ - protected $_callback = null; - - /** - * Default options to set for the filter - * - * @var mixed - */ - protected $_options = array(); - - /** - * Sets validator options - * - * @param mixed $callback - * @throws Zend_Validate_Exception - */ - public function __construct($callback = null) - { - if (is_callable($callback)) { - $this->setCallback($callback); - } elseif (is_array($callback)) { - if (isset($callback['callback'])) { - $this->setCallback($callback['callback']); - } - if (isset($callback['options'])) { - $this->setOptions($callback['options']); - } - } - - if (null === ($initializedCallack = $this->getCallback())) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('No callback registered'); - } - } - - /** - * Returns the set callback - * - * @return mixed - */ - public function getCallback() - { - return $this->_callback; - } - - /** - * Sets the callback - * - * @param string|array $callback - * @throws Zend_Validate_Exception - * @return Zend_Validate_Callback Provides a fluent interface - */ - public function setCallback($callback) - { - if (!is_callable($callback)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid callback given'); - } - $this->_callback = $callback; - return $this; - } - - /** - * Returns the set options for the callback - * - * @return mixed - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Sets options for the callback - * - * @param mixed $options - * @return Zend_Validate_Callback Provides a fluent interface - */ - public function setOptions($options) - { - $this->_options = (array) $options; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the set callback returns - * for the provided $value - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - $options = $this->getOptions(); - $callback = $this->getCallback(); - $args = func_get_args(); - $options = array_merge($args, $options); - - try { - if (!call_user_func_array($callback, $options)) { - $this->_error(self::INVALID_VALUE); - return false; - } - } catch (Exception $e) { - $this->_error(self::INVALID_CALLBACK); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Ccnum.php b/lib/Zend/Validate/Ccnum.php deleted file mode 100644 index c6d4fcddf6e..00000000000 --- a/lib/Zend/Validate/Ccnum.php +++ /dev/null @@ -1,112 +0,0 @@ - "'%value%' must contain between 13 and 19 digits", - self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'" - ); - - public function __construct() - { - trigger_error('Using the Ccnum validator is deprecated in favor of the CreditCard validator'); - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Digits - */ - #require_once 'Zend/Filter/Digits.php'; - self::$_filter = new Zend_Filter_Digits(); - } - - $valueFiltered = self::$_filter->filter($value); - - $length = strlen($valueFiltered); - - if ($length < 13 || $length > 19) { - $this->_error(self::LENGTH); - return false; - } - - $sum = 0; - $weight = 2; - - for ($i = $length - 2; $i >= 0; $i--) { - $digit = $weight * $valueFiltered[$i]; - $sum += floor($digit / 10) + $digit % 10; - $weight = $weight % 2 + 1; - } - - if ((10 - $sum % 10) % 10 != $valueFiltered[$length - 1]) { - $this->_error(self::CHECKSUM, $valueFiltered); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/CreditCard.php b/lib/Zend/Validate/CreditCard.php deleted file mode 100644 index 4a44c16789e..00000000000 --- a/lib/Zend/Validate/CreditCard.php +++ /dev/null @@ -1,319 +0,0 @@ - "'%value%' seems to contain an invalid checksum", - self::CONTENT => "'%value%' must contain only digits", - self::INVALID => "Invalid type given. String expected", - self::LENGTH => "'%value%' contains an invalid amount of digits", - self::PREFIX => "'%value%' is not from an allowed institute", - self::SERVICE => "'%value%' seems to be an invalid creditcard number", - self::SERVICEFAILURE => "An exception has been raised while validating '%value%'", - ); - - /** - * List of allowed CCV lengths - * - * @var array - */ - protected $_cardLength = array( - self::AMERICAN_EXPRESS => array(15), - self::DINERS_CLUB => array(14), - self::DINERS_CLUB_US => array(16), - self::DISCOVER => array(16), - self::JCB => array(16), - self::LASER => array(16, 17, 18, 19), - self::MAESTRO => array(12, 13, 14, 15, 16, 17, 18, 19), - self::MASTERCARD => array(16), - self::SOLO => array(16, 18, 19), - self::UNIONPAY => array(16, 17, 18, 19), - self::VISA => array(16), - ); - - /** - * List of accepted CCV provider tags - * - * @var array - */ - protected $_cardType = array( - self::AMERICAN_EXPRESS => array('34', '37'), - self::DINERS_CLUB => array('300', '301', '302', '303', '304', '305', '36'), - self::DINERS_CLUB_US => array('54', '55'), - self::DISCOVER => array('6011', '622126', '622127', '622128', '622129', '62213', - '62214', '62215', '62216', '62217', '62218', '62219', - '6222', '6223', '6224', '6225', '6226', '6227', '6228', - '62290', '62291', '622920', '622921', '622922', '622923', - '622924', '622925', '644', '645', '646', '647', '648', - '649', '65'), - self::JCB => array('3528', '3529', '353', '354', '355', '356', '357', '358'), - self::LASER => array('6304', '6706', '6771', '6709'), - self::MAESTRO => array('5018', '5020', '5038', '6304', '6759', '6761', '6763'), - self::MASTERCARD => array('51', '52', '53', '54', '55'), - self::SOLO => array('6334', '6767'), - self::UNIONPAY => array('622126', '622127', '622128', '622129', '62213', '62214', - '62215', '62216', '62217', '62218', '62219', '6222', '6223', - '6224', '6225', '6226', '6227', '6228', '62290', '62291', - '622920', '622921', '622922', '622923', '622924', '622925'), - self::VISA => array('4'), - ); - - /** - * CCIs which are accepted by validation - * - * @var array - */ - protected $_type = array(); - - /** - * Service callback for additional validation - * - * @var callback - */ - protected $_service; - - /** - * Constructor - * - * @param string|array|Zend_Config $options OPTIONAL Type of CCI to allow - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['type'] = array_shift($options); - if (!empty($options)) { - $temp['service'] = array_shift($options); - } - - $options = $temp; - } - - if (!array_key_exists('type', $options)) { - $options['type'] = self::ALL; - } - - $this->setType($options['type']); - if (array_key_exists('service', $options)) { - $this->setService($options['service']); - } - } - - /** - * Returns a list of accepted CCIs - * - * @return array - */ - public function getType() - { - return $this->_type; - } - - /** - * Sets CCIs which are accepted by validation - * - * @param string|array $type Type to allow for validation - * @return Zend_Validate_CreditCard Provides a fluent interface - */ - public function setType($type) - { - $this->_type = array(); - return $this->addType($type); - } - - /** - * Adds a CCI to be accepted by validation - * - * @param string|array $type Type to allow for validation - * @return Zend_Validate_CreditCard Provides a fluent interface - */ - public function addType($type) - { - if (is_string($type)) { - $type = array($type); - } - - foreach($type as $typ) { - if (defined('self::' . strtoupper($typ)) && !in_array($typ, $this->_type)) { - $this->_type[] = $typ; - } - - if (($typ == self::ALL)) { - $this->_type = array_keys($this->_cardLength); - } - } - - return $this; - } - - /** - * Returns the actual set service - * - * @return callback - */ - public function getService() - { - return $this->_service; - } - - /** - * Sets a new callback for service validation - * - * @param mixed $service - * @throws Zend_Validate_Exception - * @return $this - */ - public function setService($service) - { - if (!is_callable($service)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid callback given'); - } - - $this->_service = $service; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if (!is_string($value)) { - $this->_error(self::INVALID, $value); - return false; - } - - if (!ctype_digit($value)) { - $this->_error(self::CONTENT, $value); - return false; - } - - $length = strlen($value); - $types = $this->getType(); - $foundp = false; - $foundl = false; - foreach ($types as $type) { - foreach ($this->_cardType[$type] as $prefix) { - if (substr($value, 0, strlen($prefix)) == $prefix) { - $foundp = true; - if (in_array($length, $this->_cardLength[$type])) { - $foundl = true; - break 2; - } - } - } - } - - if ($foundp == false){ - $this->_error(self::PREFIX, $value); - return false; - } - - if ($foundl == false) { - $this->_error(self::LENGTH, $value); - return false; - } - - $sum = 0; - $weight = 2; - - for ($i = $length - 2; $i >= 0; $i--) { - $digit = $weight * $value[$i]; - $sum += floor($digit / 10) + $digit % 10; - $weight = $weight % 2 + 1; - } - - if ((10 - $sum % 10) % 10 != $value[$length - 1]) { - $this->_error(self::CHECKSUM, $value); - return false; - } - - if (!empty($this->_service)) { - try { - #require_once 'Zend/Validate/Callback.php'; - $callback = new Zend_Validate_Callback($this->_service); - $callback->setOptions($this->_type); - if (!$callback->isValid($value)) { - $this->_error(self::SERVICE, $value); - return false; - } - } catch (Zend_Exception $e) { - $this->_error(self::SERVICEFAILURE, $value); - return false; - } - } - - return true; - } -} diff --git a/lib/Zend/Validate/Date.php b/lib/Zend/Validate/Date.php deleted file mode 100644 index 2d9dcfe965d..00000000000 --- a/lib/Zend/Validate/Date.php +++ /dev/null @@ -1,258 +0,0 @@ - "Invalid type given. String, integer, array or Zend_Date expected", - self::INVALID_DATE => "'%value%' does not appear to be a valid date", - self::FALSEFORMAT => "'%value%' does not fit the date format '%format%'", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'format' => '_format' - ); - - /** - * Optional format - * - * @var string|null - */ - protected $_format; - - /** - * Optional locale - * - * @var string|Zend_Locale|null - */ - protected $_locale; - - /** - * Sets validator options - * - * @param string|array|Zend_Config $options OPTIONAL - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['format'] = array_shift($options); - if (!empty($options)) { - $temp['locale'] = array_shift($options); - } - - $options = $temp; - } - - if (array_key_exists('format', $options)) { - $this->setFormat($options['format']); - } - - if (!array_key_exists('locale', $options)) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Locale')) { - $options['locale'] = Zend_Registry::get('Zend_Locale'); - } - } - - if (array_key_exists('locale', $options)) { - $this->setLocale($options['locale']); - } - } - - /** - * Returns the locale option - * - * @return string|Zend_Locale|null - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale option - * - * @param string|Zend_Locale $locale - * @return Zend_Validate_Date provides a fluent interface - */ - public function setLocale($locale = null) - { - #require_once 'Zend/Locale.php'; - $this->_locale = Zend_Locale::findLocale($locale); - return $this; - } - - /** - * Returns the locale option - * - * @return string|null - */ - public function getFormat() - { - return $this->_format; - } - - /** - * Sets the format option - * - * @param string $format - * @return Zend_Validate_Date provides a fluent interface - */ - public function setFormat($format = null) - { - $this->_format = $format; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if $value is a valid date of the format YYYY-MM-DD - * If optional $format or $locale is set the date format is checked - * according to Zend_Date, see Zend_Date::isDate() - * - * @param string|array|Zend_Date $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value) && - !is_array($value) && !($value instanceof Zend_Date)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - - if (($this->_format !== null) || ($this->_locale !== null) || is_array($value) || - $value instanceof Zend_Date) { - #require_once 'Zend/Date.php'; - if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) { - if ($this->_checkFormat($value) === false) { - $this->_error(self::FALSEFORMAT); - } else { - $this->_error(self::INVALID_DATE); - } - return false; - } - } else { - if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) { - $this->_format = 'yyyy-MM-dd'; - $this->_error(self::FALSEFORMAT); - $this->_format = null; - return false; - } - - list($year, $month, $day) = sscanf($value, '%d-%d-%d'); - - if (!checkdate($month, $day, $year)) { - $this->_error(self::INVALID_DATE); - return false; - } - } - - return true; - } - - /** - * Check if the given date fits the given format - * - * @param string $value Date to check - * @return boolean False when date does not fit the format - */ - private function _checkFormat($value) - { - try { - #require_once 'Zend/Locale/Format.php'; - $parsed = Zend_Locale_Format::getDate($value, array( - 'date_format' => $this->_format, 'format_type' => 'iso', - 'fix_date' => false)); - if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and - (strpos(strtoupper($this->_format), 'YYYY') === false))) { - $parsed['year'] = Zend_Date::getFullYear($parsed['year']); - } - } catch (Exception $e) { - // Date can not be parsed - return false; - } - - if (((strpos($this->_format, 'Y') !== false) || (strpos($this->_format, 'y') !== false)) and - (!isset($parsed['year']))) { - // Year expected but not found - return false; - } - - if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) { - // Month expected but not found - return false; - } - - if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) { - // Day expected but not found - return false; - } - - if (((strpos($this->_format, 'H') !== false) || (strpos($this->_format, 'h') !== false)) and - (!isset($parsed['hour']))) { - // Hour expected but not found - return false; - } - - if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) { - // Minute expected but not found - return false; - } - - if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) { - // Second expected but not found - return false; - } - - // Date fits the format - return true; - } -} diff --git a/lib/Zend/Validate/Db/Abstract.php b/lib/Zend/Validate/Db/Abstract.php deleted file mode 100644 index b5938dac992..00000000000 --- a/lib/Zend/Validate/Db/Abstract.php +++ /dev/null @@ -1,355 +0,0 @@ - "No record matching '%value%' was found", - self::ERROR_RECORD_FOUND => "A record matching '%value%' was found", - ); - - /** - * @var string - */ - protected $_schema = null; - - /** - * @var string - */ - protected $_table = ''; - - /** - * @var string - */ - protected $_field = ''; - - /** - * @var mixed - */ - protected $_exclude = null; - - /** - * Database adapter to use. If null isValid() will use Zend_Db::getInstance instead - * - * @var unknown_type - */ - protected $_adapter = null; - - /** - * Select object to use. can be set, or will be auto-generated - * @var Zend_Db_Select - */ - protected $_select; - - /** - * Provides basic configuration for use with Zend_Validate_Db Validators - * Setting $exclude allows a single record to be excluded from matching. - * Exclude can either be a String containing a where clause, or an array with `field` and `value` keys - * to define the where clause added to the sql. - * A database adapter may optionally be supplied to avoid using the registered default adapter. - * - * The following option keys are supported: - * 'table' => The database table to validate against - * 'schema' => The schema keys - * 'field' => The field to check for a match - * 'exclude' => An optional where clause or field/value pair to exclude from the query - * 'adapter' => An optional database adapter to use - * - * @param array|Zend_Config $options Options to use for this validator - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Db_Select) { - $this->setSelect($options); - return; - } - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (func_num_args() > 1) { - $options = func_get_args(); - $temp['table'] = array_shift($options); - $temp['field'] = array_shift($options); - if (!empty($options)) { - $temp['exclude'] = array_shift($options); - } - - if (!empty($options)) { - $temp['adapter'] = array_shift($options); - } - - $options = $temp; - } - - if (!array_key_exists('table', $options) && !array_key_exists('schema', $options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Table or Schema option missing!'); - } - - if (!array_key_exists('field', $options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Field option missing!'); - } - - if (array_key_exists('adapter', $options)) { - $this->setAdapter($options['adapter']); - } - - if (array_key_exists('exclude', $options)) { - $this->setExclude($options['exclude']); - } - - $this->setField($options['field']); - if (array_key_exists('table', $options)) { - $this->setTable($options['table']); - } - - if (array_key_exists('schema', $options)) { - $this->setSchema($options['schema']); - } - } - - /** - * Returns the set adapter - * - * @throws Zend_Validate_Exception - * @return Zend_Db_Adapter - */ - public function getAdapter() - { - /** - * Check for an adapter being defined. if not, fetch the default adapter. - */ - if ($this->_adapter === null) { - $this->_adapter = Zend_Db_Table_Abstract::getDefaultAdapter(); - if (null === $this->_adapter) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('No database adapter present'); - } - } - return $this->_adapter; - } - - /** - * Sets a new database adapter - * - * @param Zend_Db_Adapter_Abstract $adapter - * @throws Zend_Validate_Exception - * @return Zend_Validate_Db_Abstract - */ - public function setAdapter($adapter) - { - if (!($adapter instanceof Zend_Db_Adapter_Abstract)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Adapter option must be a database adapter!'); - } - - $this->_adapter = $adapter; - return $this; - } - - /** - * Returns the set exclude clause - * - * @return string|array - */ - public function getExclude() - { - return $this->_exclude; - } - - /** - * Sets a new exclude clause - * - * @param string|array $exclude - * @return Zend_Validate_Db_Abstract - */ - public function setExclude($exclude) - { - $this->_exclude = $exclude; - return $this; - } - - /** - * Returns the set field - * - * @return string|array - */ - public function getField() - { - return $this->_field; - } - - /** - * Sets a new field - * - * @param string $field - * @return Zend_Validate_Db_Abstract - */ - public function setField($field) - { - $this->_field = (string) $field; - return $this; - } - - /** - * Returns the set table - * - * @return string - */ - public function getTable() - { - return $this->_table; - } - - /** - * Sets a new table - * - * @param string $table - * @return Zend_Validate_Db_Abstract - */ - public function setTable($table) - { - $this->_table = (string) $table; - return $this; - } - - /** - * Returns the set schema - * - * @return string - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * Sets a new schema - * - * @param string $schema - * @return Zend_Validate_Db_Abstract - */ - public function setSchema($schema) - { - $this->_schema = $schema; - return $this; - } - - /** - * Sets the select object to be used by the validator - * - * @param Zend_Db_Select $select - * @throws Zend_Validate_Exception - * @return Zend_Validate_Db_Abstract - */ - public function setSelect($select) - { - if (!$select instanceof Zend_Db_Select) { - throw new Zend_Validate_Exception('Select option must be a valid ' . - 'Zend_Db_Select object'); - } - $this->_select = $select; - return $this; - } - - /** - * Gets the select object to be used by the validator. - * If no select object was supplied to the constructor, - * then it will auto-generate one from the given table, - * schema, field, and adapter options. - * - * @return Zend_Db_Select The Select object which will be used - */ - public function getSelect() - { - if (null === $this->_select) { - $db = $this->getAdapter(); - /** - * Build select object - */ - $select = new Zend_Db_Select($db); - $select->from($this->_table, array($this->_field), $this->_schema); - if ($db->supportsParameters('named')) { - $select->where($db->quoteIdentifier($this->_field, true).' = :value'); // named - } else { - $select->where($db->quoteIdentifier($this->_field, true).' = ?'); // positional - } - if ($this->_exclude !== null) { - if (is_array($this->_exclude)) { - $select->where( - $db->quoteIdentifier($this->_exclude['field'], true) . - ' != ?', $this->_exclude['value'] - ); - } else { - $select->where($this->_exclude); - } - } - $select->limit(1); - $this->_select = $select; - } - return $this->_select; - } - - /** - * Run query and returns matches, or null if no matches are found. - * - * @param String $value - * @return Array when matches are found. - */ - protected function _query($value) - { - $select = $this->getSelect(); - /** - * Run query - */ - $result = $select->getAdapter()->fetchRow( - $select, - array('value' => $value), // this should work whether db supports positional or named params - Zend_Db::FETCH_ASSOC - ); - - return $result; - } -} diff --git a/lib/Zend/Validate/Db/NoRecordExists.php b/lib/Zend/Validate/Db/NoRecordExists.php deleted file mode 100644 index 5c6f1b163fb..00000000000 --- a/lib/Zend/Validate/Db/NoRecordExists.php +++ /dev/null @@ -1,51 +0,0 @@ -_setValue($value); - - $result = $this->_query($value); - if ($result) { - $valid = false; - $this->_error(self::ERROR_RECORD_FOUND); - } - - return $valid; - } -} diff --git a/lib/Zend/Validate/Db/RecordExists.php b/lib/Zend/Validate/Db/RecordExists.php deleted file mode 100644 index e1b287daa5a..00000000000 --- a/lib/Zend/Validate/Db/RecordExists.php +++ /dev/null @@ -1,51 +0,0 @@ -_setValue($value); - - $result = $this->_query($value); - if (!$result) { - $valid = false; - $this->_error(self::ERROR_NO_RECORD_FOUND); - } - - return $valid; - } -} diff --git a/lib/Zend/Validate/Digits.php b/lib/Zend/Validate/Digits.php deleted file mode 100644 index f021c6112d4..00000000000 --- a/lib/Zend/Validate/Digits.php +++ /dev/null @@ -1,91 +0,0 @@ - "'%value%' must contain only digits", - self::STRING_EMPTY => "'%value%' is an empty string", - self::INVALID => "Invalid type given. String, integer or float expected", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value only contains digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue((string) $value); - - if ('' === $this->_value) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - #require_once 'Zend/Filter/Digits.php'; - self::$_filter = new Zend_Filter_Digits(); - } - - if ($this->_value !== self::$_filter->filter($this->_value)) { - $this->_error(self::NOT_DIGITS); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/EmailAddress.php b/lib/Zend/Validate/EmailAddress.php deleted file mode 100644 index 22c896a8941..00000000000 --- a/lib/Zend/Validate/EmailAddress.php +++ /dev/null @@ -1,564 +0,0 @@ - "Invalid type given. String expected", - self::INVALID_FORMAT => "'%value%' is not a valid email address in the basic format local-part@hostname", - self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'", - self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'", - self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address '%value%' should not be resolved from public network", - self::DOT_ATOM => "'%localPart%' can not be matched against dot-atom format", - self::QUOTED_STRING => "'%localPart%' can not be matched against quoted-string format", - self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'", - self::LENGTH_EXCEEDED => "'%value%' exceeds the allowed length", - ); - - /** - * As of RFC5753 (JAN 2010), the following blocks are no longer reserved: - * - 128.0.0.0/16 - * - 191.255.0.0/16 - * - 223.255.255.0/24 - * @see http://tools.ietf.org/html/rfc5735#page-6 - * - * As of RFC6598 (APR 2012), the following blocks are now reserved: - * - 100.64.0.0/10 - * @see http://tools.ietf.org/html/rfc6598#section-7 - * - * @see http://en.wikipedia.org/wiki/IPv4 - * @var array - */ - protected $_invalidIp = array( - '0' => '0.0.0.0/8', - '10' => '10.0.0.0/8', - '100' => '100.64.0.0/10', - '127' => '127.0.0.0/8', - '169' => '169.254.0.0/16', - '172' => '172.16.0.0/12', - '192' => array( - '192.0.0.0/24', - '192.0.2.0/24', - '192.88.99.0/24', - '192.168.0.0/16' - ), - '198' => '198.18.0.0/15', - '224' => '224.0.0.0/4', - '240' => '240.0.0.0/4' - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'hostname' => '_hostname', - 'localPart' => '_localPart' - ); - - /** - * @var string - */ - protected $_hostname; - - /** - * @var string - */ - protected $_localPart; - - /** - * Internal options array - */ - protected $_options = array( - 'mx' => false, - 'deep' => false, - 'domain' => true, - 'allow' => Zend_Validate_Hostname::ALLOW_DNS, - 'hostname' => null - ); - - /** - * Instantiates hostname validator for local use - * - * The following option keys are supported: - * 'hostname' => A hostname validator, see Zend_Validate_Hostname - * 'allow' => Options for the hostname validator, see Zend_Validate_Hostname::ALLOW_* - * 'mx' => If MX check should be enabled, boolean - * 'deep' => If a deep MX check should be done, boolean - * - * @param array|string|Zend_Config $options OPTIONAL - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['allow'] = array_shift($options); - if (!empty($options)) { - $temp['mx'] = array_shift($options); - } - - if (!empty($options)) { - $temp['hostname'] = array_shift($options); - } - - $options = $temp; - } - - $options += $this->_options; - $this->setOptions($options); - } - - /** - * Returns all set Options - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Set options for the email validator - * - * @param array $options - * @return Zend_Validate_EmailAddress Provides a fluent inteface - */ - public function setOptions(array $options = array()) - { - if (array_key_exists('messages', $options)) { - $this->setMessages($options['messages']); - } - - if (array_key_exists('hostname', $options)) { - if (array_key_exists('allow', $options)) { - $this->setHostnameValidator($options['hostname'], $options['allow']); - } else { - $this->setHostnameValidator($options['hostname']); - } - } elseif ($this->_options['hostname'] == null) { - $this->setHostnameValidator(); - } - - if (array_key_exists('mx', $options)) { - $this->setValidateMx($options['mx']); - } - - if (array_key_exists('deep', $options)) { - $this->setDeepMxCheck($options['deep']); - } - - if (array_key_exists('domain', $options)) { - $this->setDomainCheck($options['domain']); - } - - return $this; - } - - /** - * Sets the validation failure message template for a particular key - * Adds the ability to set messages to the attached hostname validator - * - * @param string $messageString - * @param string $messageKey OPTIONAL - * @return Zend_Validate_Abstract Provides a fluent interface - * @throws Zend_Validate_Exception - */ - public function setMessage($messageString, $messageKey = null) - { - if ($messageKey === null) { - $this->_options['hostname']->setMessage($messageString); - parent::setMessage($messageString); - return $this; - } - - if (!isset($this->_messageTemplates[$messageKey])) { - $this->_options['hostname']->setMessage($messageString, $messageKey); - } - - $this->_messageTemplates[$messageKey] = $messageString; - return $this; - } - - /** - * Returns the set hostname validator - * - * @return Zend_Validate_Hostname - */ - public function getHostnameValidator() - { - return $this->_options['hostname']; - } - - /** - * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL - * @param int $allow OPTIONAL - * @return $this - */ - public function setHostnameValidator(Zend_Validate_Hostname $hostnameValidator = null, $allow = Zend_Validate_Hostname::ALLOW_DNS) - { - if (!$hostnameValidator) { - $hostnameValidator = new Zend_Validate_Hostname($allow); - } - - $this->_options['hostname'] = $hostnameValidator; - $this->_options['allow'] = $allow; - return $this; - } - - /** - * Whether MX checking via getmxrr is supported or not - * - * This currently only works on UNIX systems - * - * @return boolean - */ - public function validateMxSupported() - { - return function_exists('getmxrr'); - } - - /** - * Returns the set validateMx option - * - * @return boolean - */ - public function getValidateMx() - { - return $this->_options['mx']; - } - - /** - * Set whether we check for a valid MX record via DNS - * - * This only applies when DNS hostnames are validated - * - * @param boolean $mx Set allowed to true to validate for MX records, and false to not validate them - * @throws Zend_Validate_Exception - * @return Zend_Validate_EmailAddress Provides a fluent inteface - */ - public function setValidateMx($mx) - { - if ((bool) $mx && !$this->validateMxSupported()) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('MX checking not available on this system'); - } - - $this->_options['mx'] = (bool) $mx; - return $this; - } - - /** - * Returns the set deepMxCheck option - * - * @return boolean - */ - public function getDeepMxCheck() - { - return $this->_options['deep']; - } - - /** - * Set whether we check MX record should be a deep validation - * - * @param boolean $deep Set deep to true to perform a deep validation process for MX records - * @return Zend_Validate_EmailAddress Provides a fluent inteface - */ - public function setDeepMxCheck($deep) - { - $this->_options['deep'] = (bool) $deep; - return $this; - } - - /** - * Returns the set domainCheck option - * - * @return unknown - */ - public function getDomainCheck() - { - return $this->_options['domain']; - } - - /** - * Sets if the domain should also be checked - * or only the local part of the email address - * - * @param boolean $domain - * @return Zend_Validate_EmailAddress Provides a fluent inteface - */ - public function setDomainCheck($domain = true) - { - $this->_options['domain'] = (boolean) $domain; - return $this; - } - - /** - * Returns if the given host is reserved - * - * @param string $host - * @return boolean - */ - private function _isReserved($host){ - if (!preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) { - $host = gethostbyname($host); - } - - $octet = explode('.',$host); - if ((int)$octet[0] >= 224) { - return true; - } else if (array_key_exists($octet[0], $this->_invalidIp)) { - foreach ((array)$this->_invalidIp[$octet[0]] as $subnetData) { - // we skip the first loop as we already know that octet matches - for ($i = 1; $i < 4; $i++) { - if (strpos($subnetData, $octet[$i]) !== $i * 4) { - break; - } - } - - $host = explode("/", $subnetData); - $binaryHost = ""; - $tmp = explode(".", $host[0]); - for ($i = 0; $i < 4 ; $i++) { - $binaryHost .= str_pad(decbin($tmp[$i]), 8, "0", STR_PAD_LEFT); - } - - $segmentData = array( - 'network' => (int)$this->_toIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 0)), - 'broadcast' => (int)$this->_toIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 1)) - ); - - for ($j = $i; $j < 4; $j++) { - if ((int)$octet[$j] < $segmentData['network'][$j] || - (int)$octet[$j] > $segmentData['broadcast'][$j]) { - return false; - } - } - } - - return true; - } else { - return false; - } - } - - /** - * Converts a binary string to an IP address - * - * @param string $binary - * @return mixed - */ - private function _toIp($binary) - { - $ip = array(); - $tmp = explode(".", chunk_split($binary, 8, ".")); - for ($i = 0; $i < 4 ; $i++) { - $ip[$i] = bindec($tmp[$i]); - } - - return $ip; - } - - /** - * Internal method to validate the local part of the email address - * - * @return boolean - */ - private function _validateLocalPart() - { - // First try to match the local part on the common dot-atom format - $result = false; - - // Dot-atom characters are: 1*atext *("." 1*atext) - // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*", - // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~" - $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; - if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) { - $result = true; - } else { - $this->_error(self::DOT_ATOM); - $this->_error(self::INVALID_LOCAL_PART); - } - - return $result; - } - - /** - * Internal method to validate the servers MX records - * - * @return boolean - */ - private function _validateMXRecords() - { - $mxHosts = array(); - $hostname = $this->_hostname; - - //decode IDN domain name if possible - if (function_exists('idn_to_ascii')) { - $hostname = idn_to_ascii($this->_hostname); - } - - $result = getmxrr($hostname, $mxHosts); - if (!$result) { - $this->_error(self::INVALID_MX_RECORD); - } else if ($this->_options['deep'] && function_exists('checkdnsrr')) { - $validAddress = false; - $reserved = true; - foreach ($mxHosts as $hostname) { - $res = $this->_isReserved($hostname); - if (!$res) { - $reserved = false; - } - - if (!$res - && (checkdnsrr($hostname, "A") - || checkdnsrr($hostname, "AAAA") - || checkdnsrr($hostname, "A6"))) { - $validAddress = true; - break; - } - } - - if (!$validAddress) { - $result = false; - if ($reserved) { - $this->_error(self::INVALID_SEGMENT); - } else { - $this->_error(self::INVALID_MX_RECORD); - } - } - } - - return $result; - } - - /** - * Internal method to validate the hostname part of the email address - * - * @return boolean - */ - private function _validateHostnamePart() - { - $hostname = $this->_options['hostname']->setTranslator($this->getTranslator()) - ->isValid($this->_hostname); - if (!$hostname) { - $this->_error(self::INVALID_HOSTNAME); - - // Get messages and errors from hostnameValidator - foreach ($this->_options['hostname']->getMessages() as $code => $message) { - $this->_messages[$code] = $message; - } - - foreach ($this->_options['hostname']->getErrors() as $error) { - $this->_errors[] = $error; - } - } else if ($this->_options['mx']) { - // MX check on hostname - $hostname = $this->_validateMXRecords(); - } - - return $hostname; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid email address - * according to RFC2822 - * - * @link http://www.ietf.org/rfc/rfc2822.txt RFC2822 - * @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $matches = array(); - $length = true; - $this->_setValue($value); - - // Split email address up and disallow '..' - if ((strpos($value, '..') !== false) or - (!preg_match('/^(.+)@([^@]+)$/', $value, $matches))) { - $this->_error(self::INVALID_FORMAT); - return false; - } - - $this->_localPart = $matches[1]; - $this->_hostname = $matches[2]; - - if ((strlen($this->_localPart) > 64) || (strlen($this->_hostname) > 255)) { - $length = false; - $this->_error(self::LENGTH_EXCEEDED); - } - - // Match hostname part - if ($this->_options['domain']) { - $hostname = $this->_validateHostnamePart(); - } - - $local = $this->_validateLocalPart(); - - // If both parts valid, return true - if ($local && $length) { - if (($this->_options['domain'] && $hostname) || !$this->_options['domain']) { - return true; - } - } - - return false; - } -} diff --git a/lib/Zend/Validate/Exception.php b/lib/Zend/Validate/Exception.php deleted file mode 100644 index efc6c805083..00000000000 --- a/lib/Zend/Validate/Exception.php +++ /dev/null @@ -1,34 +0,0 @@ - "Too many files, maximum '%max%' are allowed but '%count%' are given", - self::TOO_FEW => "Too few files, minimum '%min%' are expected but '%count%' are given", - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max', - 'count' => '_count' - ); - - /** - * Minimum file count - * - * If null, there is no minimum file count - * - * @var integer - */ - protected $_min; - - /** - * Maximum file count - * - * If null, there is no maximum file count - * - * @var integer|null - */ - protected $_max; - - /** - * Actual filecount - * - * @var integer - */ - protected $_count; - - /** - * Internal file array - * @var array - */ - protected $_files; - - /** - * Sets validator options - * - * Min limits the file count, when used with max=null it is the maximum file count - * It also accepts an array with the keys 'min' and 'max' - * - * If $options is a integer, it will be used as maximum file count - * As Array is accepts the following keys: - * 'min': Minimum filecount - * 'max': Maximum filecount - * - * @param integer|array|Zend_Config $options Options for the adapter - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_string($options) || is_numeric($options)) { - $options = array('max' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - if (1 < func_num_args()) { - $options['min'] = func_get_arg(0); - $options['max'] = func_get_arg(1); - } - - if (isset($options['min'])) { - $this->setMin($options); - } - - if (isset($options['max'])) { - $this->setMax($options); - } - } - - /** - * Returns the minimum file count - * - * @return integer - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the minimum file count - * - * @param integer|array $min The minimum file count - * @return Zend_Validate_File_Count Provides a fluent interface - * @throws Zend_Validate_Exception When min is greater than max - */ - public function setMin($min) - { - if (is_array($min) and isset($min['min'])) { - $min = $min['min']; - } - - if (!is_string($min) and !is_numeric($min)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - $min = (integer) $min; - if (($this->_max !== null) && ($min > $this->_max)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum file count, but $min >" - . " {$this->_max}"); - } - - $this->_min = $min; - return $this; - } - - /** - * Returns the maximum file count - * - * @return integer - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the maximum file count - * - * @param integer|array $max The maximum file count - * @return Zend_Validate_StringLength Provides a fluent interface - * @throws Zend_Validate_Exception When max is smaller than min - */ - public function setMax($max) - { - if (is_array($max) and isset($max['max'])) { - $max = $max['max']; - } - - if (!is_string($max) and !is_numeric($max)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - $max = (integer) $max; - if (($this->_min !== null) && ($max < $this->_min)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum file count, but " - . "$max < {$this->_min}"); - } - - $this->_max = $max; - return $this; - } - - /** - * Adds a file for validation - * - * @param string|array $file - * @return $this - */ - public function addFile($file) - { - if (is_string($file)) { - $file = array($file); - } - - if (is_array($file)) { - foreach ($file as $name) { - if (!isset($this->_files[$name]) && !empty($name)) { - $this->_files[$name] = $name; - } - } - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file count of all checked files is at least min and - * not bigger than max (when max is not null). Attention: When checking with set min you - * must give all files with the first call, otherwise you will get an false. - * - * @param string|array $value Filenames to check for count - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - if (($file !== null) && !array_key_exists('destination', $file)) { - $file['destination'] = dirname($value); - } - - if (($file !== null) && array_key_exists('tmp_name', $file)) { - $value = $file['destination'] . DIRECTORY_SEPARATOR . $file['name']; - } - - if (($file === null) || !empty($file['tmp_name'])) { - $this->addFile($value); - } - - $this->_count = count($this->_files); - if (($this->_max !== null) && ($this->_count > $this->_max)) { - return $this->_throw($file, self::TOO_MANY); - } - - if (($this->_min !== null) && ($this->_count < $this->_min)) { - return $this->_throw($file, self::TOO_FEW); - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/Crc32.php b/lib/Zend/Validate/File/Crc32.php deleted file mode 100644 index b887a746682..00000000000 --- a/lib/Zend/Validate/File/Crc32.php +++ /dev/null @@ -1,180 +0,0 @@ - "File '%value%' does not match the given crc32 hashes", - self::NOT_DETECTED => "A crc32 hash could not be evaluated for the given file", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Hash of the file - * - * @var string - */ - protected $_hash; - - /** - * Sets validator options - * - * @param string|array|Zend_Config $options - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Crc32 - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_scalar($options)) { - $options = array('hash1' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options to validator provided'); - } - - $this->setCrc32($options); - } - - /** - * Returns all set crc32 hashes - * - * @return array - */ - public function getCrc32() - { - return $this->getHash(); - } - - /** - * Sets the crc32 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setHash($options) - { - if (!is_array($options)) { - $options = array($options); - } - - $options['algorithm'] = 'crc32'; - parent::setHash($options); - return $this; - } - - /** - * Sets the crc32 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setCrc32($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the crc32 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addHash($options) - { - if (!is_array($options)) { - $options = array($options); - } - - $options['algorithm'] = 'crc32'; - parent::addHash($options); - return $this; - } - - /** - * Adds the crc32 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addCrc32($options) - { - $this->addHash($options); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the given file confirms the set hash - * - * @param string $value Filename to check for hash - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - $hashes = array_unique(array_keys($this->_hash)); - $filehash = hash_file('crc32', $value); - if ($filehash === false) { - return $this->_throw($file, self::NOT_DETECTED); - } - - foreach($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - return $this->_throw($file, self::DOES_NOT_MATCH); - } -} diff --git a/lib/Zend/Validate/File/ExcludeExtension.php b/lib/Zend/Validate/File/ExcludeExtension.php deleted file mode 100644 index 47f51b17b38..00000000000 --- a/lib/Zend/Validate/File/ExcludeExtension.php +++ /dev/null @@ -1,94 +0,0 @@ - "File '%value%' has a false extension", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the fileextension of $value is not included in the - * set extension list - * - * @param string $value Real file to check for extension - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - if ($file !== null) { - $info['extension'] = substr($file['name'], strrpos($file['name'], '.') + 1); - } else { - $info = pathinfo($value); - } - - $extensions = $this->getExtension(); - - if ($this->_case and (!in_array($info['extension'], $extensions))) { - return true; - } else if (!$this->_case) { - $found = false; - foreach ($extensions as $extension) { - if (strtolower($extension) == strtolower($info['extension'])) { - $found = true; - } - } - - if (!$found) { - return true; - } - } - - return $this->_throw($file, self::FALSE_EXTENSION); - } -} diff --git a/lib/Zend/Validate/File/ExcludeMimeType.php b/lib/Zend/Validate/File/ExcludeMimeType.php deleted file mode 100644 index ec978a82c91..00000000000 --- a/lib/Zend/Validate/File/ExcludeMimeType.php +++ /dev/null @@ -1,101 +0,0 @@ - "File '%value%' has a false mimetype of '%type%'", - self::NOT_DETECTED => "The mimetype of file '%value%' could not be detected", - self::NOT_READABLE => "File '%value%' is not readable or does not exist", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if the mimetype of the file does not matche the given ones. Also parts - * of mimetypes can be checked. If you give for example "image" all image - * mime types will not be accepted like "image/gif", "image/jpeg" and so on. - * - * @param string $value Real file to check for mimetype - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - if ($file === null) { - $file = array( - 'type' => null, - 'name' => $value - ); - } - - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_READABLE); - } - - $this->_type = $this->_detectMimeType($value); - - if (empty($this->_type) && $this->_headerCheck) { - $this->_type = $file['type']; - } - - if (empty($this->_type)) { - return $this->_throw($file, self::NOT_DETECTED); - } - - $mimetype = $this->getMimeType(true); - if (in_array($this->_type, $mimetype)) { - return $this->_throw($file, self::FALSE_TYPE); - } - - $types = explode('/', $this->_type); - $types = array_merge($types, explode('-', $this->_type)); - foreach($mimetype as $mime) { - if (in_array($mime, $types)) { - return $this->_throw($file, self::FALSE_TYPE); - } - } - - return true; - } -} diff --git a/lib/Zend/Validate/File/Exists.php b/lib/Zend/Validate/File/Exists.php deleted file mode 100644 index 608dda9eefa..00000000000 --- a/lib/Zend/Validate/File/Exists.php +++ /dev/null @@ -1,204 +0,0 @@ - "File '%value%' does not exist", - ); - - /** - * Internal list of directories - * @var string - */ - protected $_directory = ''; - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'directory' => '_directory' - ); - - /** - * Sets validator options - * - * @param string|array|Zend_Config $directory - * @throws Zend_Validate_Exception - */ - public function __construct($directory = array()) - { - if ($directory instanceof Zend_Config) { - $directory = $directory->toArray(); - } else if (is_string($directory)) { - $directory = explode(',', $directory); - } else if (!is_array($directory)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - $this->setDirectory($directory); - } - - /** - * Returns the set file directories which are checked - * - * @param boolean $asArray Returns the values as array, when false an concated string is returned - * @return string - */ - public function getDirectory($asArray = false) - { - $asArray = (bool) $asArray; - $directory = (string) $this->_directory; - if ($asArray) { - $directory = explode(',', $directory); - } - - return $directory; - } - - /** - * Sets the file directory which will be checked - * - * @param string|array $directory The directories to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setDirectory($directory) - { - $this->_directory = null; - $this->addDirectory($directory); - return $this; - } - - /** - * Adds the file directory which will be checked - * - * @param string|array $directory The directory to add for validation - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addDirectory($directory) - { - $directories = $this->getDirectory(true); - - if (is_string($directory)) { - $directory = explode(',', $directory); - } else if (!is_array($directory)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - foreach ($directory as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - - $directories[] = trim($content); - } - $directories = array_unique($directories); - - // Sanity check to ensure no empty values - foreach ($directories as $key => $dir) { - if (empty($dir)) { - unset($directories[$key]); - } - } - - $this->_directory = implode(',', $directories); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file already exists in the set directories - * - * @param string $value Real file to check for existance - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - $directories = $this->getDirectory(true); - if (($file !== null) and (!empty($file['destination']))) { - $directories[] = $file['destination']; - } else if (!isset($file['name'])) { - $file['name'] = $value; - } - - $check = false; - foreach ($directories as $directory) { - if (empty($directory)) { - continue; - } - - $check = true; - if (!file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { - return $this->_throw($file, self::DOES_NOT_EXIST); - } - } - - if (!$check) { - return $this->_throw($file, self::DOES_NOT_EXIST); - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/Extension.php b/lib/Zend/Validate/File/Extension.php deleted file mode 100644 index 794ba51315f..00000000000 --- a/lib/Zend/Validate/File/Extension.php +++ /dev/null @@ -1,237 +0,0 @@ - "File '%value%' has a false extension", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Internal list of extensions - * @var string - */ - protected $_extension = ''; - - /** - * Validate case sensitive - * - * @var boolean - */ - protected $_case = false; - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'extension' => '_extension' - ); - - /** - * Sets validator options - * - * @param string|array|Zend_Config $options - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - if (1 < func_num_args()) { - $case = func_get_arg(1); - $this->setCase($case); - } - - if (is_array($options) and isset($options['case'])) { - $this->setCase($options['case']); - unset($options['case']); - } - - $this->setExtension($options); - } - - /** - * Returns the case option - * - * @return boolean - */ - public function getCase() - { - return $this->_case; - } - - /** - * Sets the case to use - * - * @param boolean $case - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setCase($case) - { - $this->_case = (boolean) $case; - return $this; - } - - /** - * Returns the set file extension - * - * @return array - */ - public function getExtension() - { - $extension = explode(',', $this->_extension); - - return $extension; - } - - /** - * Sets the file extensions - * - * @param string|array $extension The extensions to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setExtension($extension) - { - $this->_extension = null; - $this->addExtension($extension); - return $this; - } - - /** - * Adds the file extensions - * - * @param string|array $extension The extensions to add for validation - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addExtension($extension) - { - $extensions = $this->getExtension(); - if (is_string($extension)) { - $extension = explode(',', $extension); - } - - foreach ($extension as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - - $extensions[] = trim($content); - } - $extensions = array_unique($extensions); - - // Sanity check to ensure no empty values - foreach ($extensions as $key => $ext) { - if (empty($ext)) { - unset($extensions[$key]); - } - } - - $this->_extension = implode(',', $extensions); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the fileextension of $value is included in the - * set extension list - * - * @param string $value Real file to check for extension - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - if ($file !== null) { - $info['extension'] = substr($file['name'], strrpos($file['name'], '.') + 1); - } else { - $info = pathinfo($value); - if (!array_key_exists('extension', $info)) { - // From the manual at http://php.net/pathinfo: - // "If the path does not have an extension, no extension element - // will be returned (see second example below)." - return false; - } - } - - $extensions = $this->getExtension(); - - if ($this->_case && (in_array($info['extension'], $extensions))) { - return true; - } else if (!$this->getCase()) { - foreach ($extensions as $extension) { - if (strtolower($extension) == strtolower($info['extension'])) { - return true; - } - } - } - - return $this->_throw($file, self::FALSE_EXTENSION); - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if (null !== $file) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/FilesSize.php b/lib/Zend/Validate/File/FilesSize.php deleted file mode 100644 index dabff96df89..00000000000 --- a/lib/Zend/Validate/File/FilesSize.php +++ /dev/null @@ -1,164 +0,0 @@ - "All files in sum should have a maximum size of '%max%' but '%size%' were detected", - self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected", - self::NOT_READABLE => "One or more files can not be read", - ); - - /** - * Internal file array - * - * @var array - */ - protected $_files; - - /** - * Sets validator options - * - * Min limits the used diskspace for all files, when used with max=null it is the maximum filesize - * It also accepts an array with the keys 'min' and 'max' - * - * @param integer|array|Zend_Config $options Options for this validator - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - $this->_files = array(); - $this->_setSize(0); - - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_scalar($options)) { - $options = array('max' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options to validator provided'); - } - - if (1 < func_num_args()) { - $argv = func_get_args(); - array_shift($argv); - $options['max'] = array_shift($argv); - if (!empty($argv)) { - $options['bytestring'] = array_shift($argv); - } - } - - parent::__construct($options); - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the disk usage of all files is at least min and - * not bigger than max (when max is not null). - * - * @param string|array $value Real file to check for size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - #require_once 'Zend/Loader.php'; - if (is_string($value)) { - $value = array($value); - } - - $min = $this->getMin(true); - $max = $this->getMax(true); - $size = $this->_getSize(); - foreach ($value as $files) { - // Is file readable ? - if (!Zend_Loader::isReadable($files)) { - $this->_throw($file, self::NOT_READABLE); - continue; - } - - if (!isset($this->_files[$files])) { - $this->_files[$files] = $files; - } else { - // file already counted... do not count twice - continue; - } - - // limited to 2GB files - $size += @filesize($files); - $this->_size = $size; - if (($max !== null) && ($max < $size)) { - if ($this->useByteString()) { - $this->_max = $this->_toByteString($max); - $this->_size = $this->_toByteString($size); - $this->_throw($file, self::TOO_BIG); - $this->_max = $max; - $this->_size = $size; - } else { - $this->_throw($file, self::TOO_BIG); - } - } - } - - // Check that aggregate files are >= minimum size - if (($min !== null) && ($size < $min)) { - if ($this->useByteString()) { - $this->_min = $this->_toByteString($min); - $this->_size = $this->_toByteString($size); - $this->_throw($file, self::TOO_SMALL); - $this->_min = $min; - $this->_size = $size; - } else { - $this->_throw($file, self::TOO_SMALL); - } - } - - if (count($this->_messages) > 0) { - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/File/Hash.php b/lib/Zend/Validate/File/Hash.php deleted file mode 100644 index 17291151012..00000000000 --- a/lib/Zend/Validate/File/Hash.php +++ /dev/null @@ -1,195 +0,0 @@ - "File '%value%' does not match the given hashes", - self::NOT_DETECTED => "A hash could not be evaluated for the given file", - self::NOT_FOUND => "File '%value%' is not readable or does not exist" - ); - - /** - * Hash of the file - * - * @var string - */ - protected $_hash; - - /** - * Sets validator options - * - * @param string|array $options - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_scalar($options)) { - $options = array('hash1' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options to validator provided'); - } - - if (1 < func_num_args()) { - $options['algorithm'] = func_get_arg(1); - } - - $this->setHash($options); - } - - /** - * Returns the set hash values as array, the hash as key and the algorithm the value - * - * @return array - */ - public function getHash() - { - return $this->_hash; - } - - /** - * Sets the hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setHash($options) - { - $this->_hash = null; - $this->addHash($options); - - return $this; - } - - /** - * Adds the hash for one or multiple files - * - * @param string|array $options - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addHash($options) - { - if (is_string($options)) { - $options = array($options); - } else if (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("False parameter given"); - } - - $known = hash_algos(); - if (!isset($options['algorithm'])) { - $algorithm = 'crc32'; - } else { - $algorithm = $options['algorithm']; - unset($options['algorithm']); - } - - if (!in_array($algorithm, $known)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Unknown algorithm '{$algorithm}'"); - } - - foreach ($options as $value) { - $this->_hash[$value] = $algorithm; - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the given file confirms the set hash - * - * @param string $value Filename to check for hash - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - $algos = array_unique(array_values($this->_hash)); - $hashes = array_unique(array_keys($this->_hash)); - foreach ($algos as $algorithm) { - $filehash = hash_file($algorithm, $value); - if ($filehash === false) { - return $this->_throw($file, self::NOT_DETECTED); - } - - foreach($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - } - - return $this->_throw($file, self::DOES_NOT_MATCH); - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/ImageSize.php b/lib/Zend/Validate/File/ImageSize.php deleted file mode 100644 index 0fedeb51956..00000000000 --- a/lib/Zend/Validate/File/ImageSize.php +++ /dev/null @@ -1,364 +0,0 @@ - "Maximum allowed width for image '%value%' should be '%maxwidth%' but '%width%' detected", - self::WIDTH_TOO_SMALL => "Minimum expected width for image '%value%' should be '%minwidth%' but '%width%' detected", - self::HEIGHT_TOO_BIG => "Maximum allowed height for image '%value%' should be '%maxheight%' but '%height%' detected", - self::HEIGHT_TOO_SMALL => "Minimum expected height for image '%value%' should be '%minheight%' but '%height%' detected", - self::NOT_DETECTED => "The size of image '%value%' could not be detected", - self::NOT_READABLE => "File '%value%' is not readable or does not exist", - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'minwidth' => '_minwidth', - 'maxwidth' => '_maxwidth', - 'minheight' => '_minheight', - 'maxheight' => '_maxheight', - 'width' => '_width', - 'height' => '_height' - ); - - /** - * Minimum image width - * - * @var integer - */ - protected $_minwidth; - - /** - * Maximum image width - * - * @var integer - */ - protected $_maxwidth; - - /** - * Minimum image height - * - * @var integer - */ - protected $_minheight; - - /** - * Maximum image height - * - * @var integer - */ - protected $_maxheight; - - /** - * Detected width - * - * @var integer - */ - protected $_width; - - /** - * Detected height - * - * @var integer - */ - protected $_height; - - /** - * Sets validator options - * - * Accepts the following option keys: - * - minheight - * - minwidth - * - maxheight - * - maxwidth - * - * @param Zend_Config|array $options - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (1 < func_num_args()) { - if (!is_array($options)) { - $options = array('minwidth' => $options); - } - $argv = func_get_args(); - array_shift($argv); - $options['minheight'] = array_shift($argv); - if (!empty($argv)) { - $options['maxwidth'] = array_shift($argv); - if (!empty($argv)) { - $options['maxheight'] = array_shift($argv); - } - } - } else if (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - if (isset($options['minheight']) || isset($options['minwidth'])) { - $this->setImageMin($options); - } - - if (isset($options['maxheight']) || isset($options['maxwidth'])) { - $this->setImageMax($options); - } - } - - /** - * Returns the set minimum image sizes - * - * @return array - */ - public function getImageMin() - { - return array('minwidth' => $this->_minwidth, 'minheight' => $this->_minheight); - } - - /** - * Returns the set maximum image sizes - * - * @return array - */ - public function getImageMax() - { - return array('maxwidth' => $this->_maxwidth, 'maxheight' => $this->_maxheight); - } - - /** - * Returns the set image width sizes - * - * @return array - */ - public function getImageWidth() - { - return array('minwidth' => $this->_minwidth, 'maxwidth' => $this->_maxwidth); - } - - /** - * Returns the set image height sizes - * - * @return array - */ - public function getImageHeight() - { - return array('minheight' => $this->_minheight, 'maxheight' => $this->_maxheight); - } - - /** - * Sets the minimum image size - * - * @param array $options The minimum image dimensions - * @throws Zend_Validate_Exception When minwidth is greater than maxwidth - * @throws Zend_Validate_Exception When minheight is greater than maxheight - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageMin($options) - { - if (isset($options['minwidth'])) { - if (($this->_maxwidth !== null) and ($options['minwidth'] > $this->_maxwidth)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum image width must be less than or equal to the " - . " maximum image width, but {$options['minwidth']} > {$this->_maxwidth}"); - } - } - - if (isset($options['maxheight'])) { - if (($this->_maxheight !== null) and ($options['minheight'] > $this->_maxheight)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum image height must be less than or equal to the " - . " maximum image height, but {$options['minheight']} > {$this->_maxheight}"); - } - } - - if (isset($options['minwidth'])) { - $this->_minwidth = (int) $options['minwidth']; - } - - if (isset($options['minheight'])) { - $this->_minheight = (int) $options['minheight']; - } - - return $this; - } - - /** - * Sets the maximum image size - * - * @param array $options The maximum image dimensions - * @throws Zend_Validate_Exception When maxwidth is smaller than minwidth - * @throws Zend_Validate_Exception When maxheight is smaller than minheight - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setImageMax($options) - { - if (isset($options['maxwidth'])) { - if (($this->_minwidth !== null) and ($options['maxwidth'] < $this->_minwidth)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum image width must be greater than or equal to the " - . "minimum image width, but {$options['maxwidth']} < {$this->_minwidth}"); - } - } - - if (isset($options['maxheight'])) { - if (($this->_minheight !== null) and ($options['maxheight'] < $this->_minheight)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum image height must be greater than or equal to the " - . "minimum image height, but {$options['maxheight']} < {$this->_minwidth}"); - } - } - - if (isset($options['maxwidth'])) { - $this->_maxwidth = (int) $options['maxwidth']; - } - - if (isset($options['maxheight'])) { - $this->_maxheight = (int) $options['maxheight']; - } - - return $this; - } - - /** - * Sets the mimimum and maximum image width - * - * @param array $options The image width dimensions - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageWidth($options) - { - $this->setImageMin($options); - $this->setImageMax($options); - - return $this; - } - - /** - * Sets the mimimum and maximum image height - * - * @param array $options The image height dimensions - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageHeight($options) - { - $this->setImageMin($options); - $this->setImageMax($options); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the imagesize of $value is at least min and - * not bigger than max - * - * @param string $value Real file to check for image size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_READABLE); - } - - $size = @getimagesize($value); - $this->_setValue($file); - - if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { - return $this->_throw($file, self::NOT_DETECTED); - } - - $this->_width = $size[0]; - $this->_height = $size[1]; - if ($this->_width < $this->_minwidth) { - $this->_throw($file, self::WIDTH_TOO_SMALL); - } - - if (($this->_maxwidth !== null) and ($this->_maxwidth < $this->_width)) { - $this->_throw($file, self::WIDTH_TOO_BIG); - } - - if ($this->_height < $this->_minheight) { - $this->_throw($file, self::HEIGHT_TOO_SMALL); - } - - if (($this->_maxheight !== null) and ($this->_maxheight < $this->_height)) { - $this->_throw($file, self::HEIGHT_TOO_BIG); - } - - if (count($this->_messages) > 0) { - return false; - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/IsCompressed.php b/lib/Zend/Validate/File/IsCompressed.php deleted file mode 100644 index ab92e216993..00000000000 --- a/lib/Zend/Validate/File/IsCompressed.php +++ /dev/null @@ -1,149 +0,0 @@ - "File '%value%' is not compressed, '%type%' detected", - self::NOT_DETECTED => "The mimetype of file '%value%' could not be detected", - self::NOT_READABLE => "File '%value%' is not readable or does not exist", - ); - - /** - * Sets validator options - * - * @param string|array|Zend_Config $mimetype - */ - public function __construct($mimetype = array()) - { - if ($mimetype instanceof Zend_Config) { - $mimetype = $mimetype->toArray(); - } - - $temp = array(); - // http://de.wikipedia.org/wiki/Liste_von_Dateiendungen - $default = array( - 'application/arj', - 'application/gnutar', - 'application/lha', - 'application/lzx', - 'application/vnd.ms-cab-compressed', - 'application/x-ace-compressed', - 'application/x-arc', - 'application/x-archive', - 'application/x-arj', - 'application/x-bzip', - 'application/x-bzip2', - 'application/x-cab-compressed', - 'application/x-compress', - 'application/x-compressed', - 'application/x-cpio', - 'application/x-debian-package', - 'application/x-eet', - 'application/x-gzip', - 'application/x-java-pack200', - 'application/x-lha', - 'application/x-lharc', - 'application/x-lzh', - 'application/x-lzma', - 'application/x-lzx', - 'application/x-rar', - 'application/x-sit', - 'application/x-stuffit', - 'application/x-tar', - 'application/zip', - 'application/x-zip', - 'application/zoo', - 'multipart/x-gzip', - ); - - if (is_array($mimetype)) { - $temp = $mimetype; - if (array_key_exists('magicfile', $temp)) { - unset($temp['magicfile']); - } - - if (array_key_exists('headerCheck', $temp)) { - unset($temp['headerCheck']); - } - - if (empty($temp)) { - $mimetype += $default; - } - } - - if (empty($mimetype)) { - $mimetype = $default; - } - - parent::__construct($mimetype); - } - - /** - * Throws an error of the given type - * Duplicates parent method due to OOP Problem with late static binding in PHP 5.2 - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - $this->_value = $file['name']; - switch($errorType) { - case Zend_Validate_File_MimeType::FALSE_TYPE : - $errorType = self::FALSE_TYPE; - break; - case Zend_Validate_File_MimeType::NOT_DETECTED : - $errorType = self::NOT_DETECTED; - break; - case Zend_Validate_File_MimeType::NOT_READABLE : - $errorType = self::NOT_READABLE; - break; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/IsImage.php b/lib/Zend/Validate/File/IsImage.php deleted file mode 100644 index 49754348489..00000000000 --- a/lib/Zend/Validate/File/IsImage.php +++ /dev/null @@ -1,172 +0,0 @@ - "File '%value%' is no image, '%type%' detected", - self::NOT_DETECTED => "The mimetype of file '%value%' could not be detected", - self::NOT_READABLE => "File '%value%' is not readable or does not exist", - ); - - /** - * Sets validator options - * - * @param string|array|Zend_Config $mimetype - */ - public function __construct($mimetype = array()) - { - if ($mimetype instanceof Zend_Config) { - $mimetype = $mimetype->toArray(); - } - - $temp = array(); - // http://de.wikipedia.org/wiki/Liste_von_Dateiendungen - // http://www.iana.org/assignments/media-types/image/ - $default = array( - 'application/cdf', - 'application/dicom', - 'application/fractals', - 'application/postscript', - 'application/vnd.hp-hpgl', - 'application/vnd.oasis.opendocument.graphics', - 'application/x-cdf', - 'application/x-cmu-raster', - 'application/x-ima', - 'application/x-inventor', - 'application/x-koan', - 'application/x-portable-anymap', - 'application/x-world-x-3dmf', - 'image/bmp', - 'image/c', - 'image/cgm', - 'image/fif', - 'image/gif', - 'image/jpeg', - 'image/jpm', - 'image/jpx', - 'image/jp2', - 'image/naplps', - 'image/pjpeg', - 'image/png', - 'image/svg', - 'image/svg+xml', - 'image/tiff', - 'image/vnd.adobe.photoshop', - 'image/vnd.djvu', - 'image/vnd.fpx', - 'image/vnd.net-fpx', - 'image/x-cmu-raster', - 'image/x-cmx', - 'image/x-coreldraw', - 'image/x-cpi', - 'image/x-emf', - 'image/x-ico', - 'image/x-icon', - 'image/x-jg', - 'image/x-ms-bmp', - 'image/x-niff', - 'image/x-pict', - 'image/x-pcx', - 'image/x-portable-anymap', - 'image/x-portable-bitmap', - 'image/x-portable-greymap', - 'image/x-portable-pixmap', - 'image/x-quicktime', - 'image/x-rgb', - 'image/x-tiff', - 'image/x-unknown', - 'image/x-windows-bmp', - 'image/x-xpmi', - ); - - if (is_array($mimetype)) { - $temp = $mimetype; - if (array_key_exists('magicfile', $temp)) { - unset($temp['magicfile']); - } - - if (array_key_exists('headerCheck', $temp)) { - unset($temp['headerCheck']); - } - - if (empty($temp)) { - $mimetype += $default; - } - } - - if (empty($mimetype)) { - $mimetype = $default; - } - - parent::__construct($mimetype); - } - - /** - * Throws an error of the given type - * Duplicates parent method due to OOP Problem with late static binding in PHP 5.2 - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - $this->_value = $file['name']; - switch($errorType) { - case Zend_Validate_File_MimeType::FALSE_TYPE : - $errorType = self::FALSE_TYPE; - break; - case Zend_Validate_File_MimeType::NOT_DETECTED : - $errorType = self::NOT_DETECTED; - break; - case Zend_Validate_File_MimeType::NOT_READABLE : - $errorType = self::NOT_READABLE; - break; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/Md5.php b/lib/Zend/Validate/File/Md5.php deleted file mode 100644 index 0e790a8ff10..00000000000 --- a/lib/Zend/Validate/File/Md5.php +++ /dev/null @@ -1,182 +0,0 @@ - "File '%value%' does not match the given md5 hashes", - self::NOT_DETECTED => "A md5 hash could not be evaluated for the given file", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Hash of the file - * - * @var string - */ - protected $_hash; - - /** - * Sets validator options - * - * $hash is the hash we accept for the file $file - * - * @param string|array $options - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Md5 - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_scalar($options)) { - $options = array('hash1' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options to validator provided'); - } - - $this->setMd5($options); - } - - /** - * Returns all set md5 hashes - * - * @return array - */ - public function getMd5() - { - return $this->getHash(); - } - - /** - * Sets the md5 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setHash($options) - { - if (!is_array($options)) { - $options = (array) $options; - } - - $options['algorithm'] = 'md5'; - parent::setHash($options); - return $this; - } - - /** - * Sets the md5 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setMd5($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the md5 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addHash($options) - { - if (!is_array($options)) { - $options = (array) $options; - } - - $options['algorithm'] = 'md5'; - parent::addHash($options); - return $this; - } - - /** - * Adds the md5 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addMd5($options) - { - $this->addHash($options); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the given file confirms the set hash - * - * @param string $value Filename to check for hash - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - $hashes = array_unique(array_keys($this->_hash)); - $filehash = hash_file('md5', $value); - if ($filehash === false) { - return $this->_throw($file, self::NOT_DETECTED); - } - - foreach($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - return $this->_throw($file, self::DOES_NOT_MATCH); - } -} diff --git a/lib/Zend/Validate/File/MimeType.php b/lib/Zend/Validate/File/MimeType.php deleted file mode 100644 index f80d2600b9b..00000000000 --- a/lib/Zend/Validate/File/MimeType.php +++ /dev/null @@ -1,476 +0,0 @@ - "File '%value%' has a false mimetype of '%type%'", - self::NOT_DETECTED => "The mimetype of file '%value%' could not be detected", - self::NOT_READABLE => "File '%value%' is not readable or does not exist", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'type' => '_type' - ); - - /** - * @var string - */ - protected $_type; - - /** - * Mimetypes - * - * If null, there is no mimetype - * - * @var string|null - */ - protected $_mimetype; - - /** - * Magicfile to use - * - * @var string|null - */ - protected $_magicfile; - - /** - * Finfo object to use - * - * @var resource - */ - protected $_finfo; - - /** - * If no $_ENV['MAGIC'] is set, try and autodiscover it based on common locations - * @var array - */ - protected $_magicFiles = array( - '/usr/share/misc/magic', - '/usr/share/misc/magic.mime', - '/usr/share/misc/magic.mgc', - '/usr/share/mime/magic', - '/usr/share/mime/magic.mime', - '/usr/share/mime/magic.mgc', - '/usr/share/file/magic', - '/usr/share/file/magic.mime', - '/usr/share/file/magic.mgc', - ); - - /** - * Indicates whether use of $_magicFiles should be attempted. - * @var boolean - */ - protected $_tryCommonMagicFiles = true; - - /** - * Option to allow header check - * - * @var boolean - */ - protected $_headerCheck = false; - - /** - * Holds error information returned by finfo_open - * - * @var array - */ - protected $_finfoError; - - /** - * Sets validator options - * - * Mimetype to accept - * - * @param string|array $mimetype MimeType - * @throws Zend_Validate_Exception - */ - public function __construct($mimetype) - { - if ($mimetype instanceof Zend_Config) { - $mimetype = $mimetype->toArray(); - } elseif (is_string($mimetype)) { - $mimetype = explode(',', $mimetype); - } elseif (!is_array($mimetype)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Invalid options to validator provided"); - } - - if (isset($mimetype['magicfile'])) { - $this->setMagicFile($mimetype['magicfile']); - unset($mimetype['magicfile']); - } - - if (isset($mimetype['headerCheck'])) { - $this->enableHeaderCheck($mimetype['headerCheck']); - unset($mimetype['headerCheck']); - } - - $this->setMimeType($mimetype); - } - - /** - * Returns the actual set magicfile - * - * Note that for PHP 5.3.0 or higher, we don't use $_ENV['MAGIC'] or try to - * find a magic file in a common location as PHP now has a built-in internal - * magic file. - * - * @return string - */ - public function getMagicFile() - { - if (version_compare(PHP_VERSION, '5.3.0', '<') - && null === $this->_magicfile) { - if (!empty($_ENV['MAGIC'])) { - $this->setMagicFile($_ENV['MAGIC']); - } elseif ( - !(@ini_get("safe_mode") == 'On' || @ini_get("safe_mode") === 1) - && $this->shouldTryCommonMagicFiles() // @see ZF-11784 - ) { - #require_once 'Zend/Validate/Exception.php'; - foreach ($this->_magicFiles as $file) { - // supressing errors which are thrown due to openbase_dir restrictions - try { - $this->setMagicFile($file); - if ($this->_magicfile !== null) { - break; - } - } catch (Zend_Validate_Exception $e) { - // Intentionally, catch and fall through - } - } - } - - if ($this->_magicfile === null) { - $this->_magicfile = false; - } - } - - return $this->_magicfile; - } - - /** - * Sets the magicfile to use - * if null, the MAGIC constant from php is used - * if the MAGIC file is errorous, no file will be set - * - * @param string $file - * @throws Zend_Validate_Exception When finfo can not read the magicfile - * @return Zend_Validate_File_MimeType Provides a fluent interface - */ - public function setMagicFile($file) - { - if (empty($file)) { - $this->_magicfile = null; - } else if (!(class_exists('finfo', false))) { - $this->_magicfile = null; - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Magicfile can not be set. There is no finfo extension installed'); - } else if (!is_file($file) || !is_readable($file)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('The given magicfile can not be read'); - } else { - $const = defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME; - set_error_handler(array($this, '_errorHandler'), E_NOTICE | E_WARNING); - $this->_finfo = finfo_open($const, $file); - restore_error_handler(); - if (empty($this->_finfo)) { - $this->_finfo = null; - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception( - sprintf('The given magicfile ("%s") is not accepted by finfo', $file), - null, - $this->_finfoError - ); - } else { - $this->_magicfile = $file; - } - } - - return $this; - } - - /** - * Enables or disables attempts to try the common magic file locations - * specified by Zend_Validate_File_MimeType::_magicFiles - * - * @param boolean $flag - * @return Zend_Validate_File_MimeType Provides fluent interface - * @see http://framework.zend.com/issues/browse/ZF-11784 - */ - public function setTryCommonMagicFilesFlag($flag = true) - { - $this->_tryCommonMagicFiles = (boolean) $flag; - - return $this; - } - - /** - * Accessor for Zend_Validate_File_MimeType::_magicFiles - * - * @return boolean - * @see http://framework.zend.com/issues/browse/ZF-11784 - */ - public function shouldTryCommonMagicFiles() - { - return $this->_tryCommonMagicFiles; - } - - /** - * Returns the Header Check option - * - * @return boolean - */ - public function getHeaderCheck() - { - return $this->_headerCheck; - } - - /** - * Defines if the http header should be used - * Note that this is unsave and therefor the default value is false - * - * @param boolean $headerCheck - * @return Zend_Validate_File_MimeType Provides a fluent interface - */ - public function enableHeaderCheck($headerCheck = true) - { - $this->_headerCheck = (boolean) $headerCheck; - return $this; - } - - /** - * Returns the set mimetypes - * - * @param boolean $asArray Returns the values as array, when false an concated string is returned - * @return string|array - */ - public function getMimeType($asArray = false) - { - $asArray = (bool) $asArray; - $mimetype = (string) $this->_mimetype; - if ($asArray) { - $mimetype = explode(',', $mimetype); - } - - return $mimetype; - } - - /** - * Sets the mimetypes - * - * @param string|array $mimetype The mimetypes to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setMimeType($mimetype) - { - $this->_mimetype = null; - $this->addMimeType($mimetype); - return $this; - } - - /** - * Adds the mimetypes - * - * @param string|array $mimetype The mimetypes to add for validation - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addMimeType($mimetype) - { - $mimetypes = $this->getMimeType(true); - - if (is_string($mimetype)) { - $mimetype = explode(',', $mimetype); - } elseif (!is_array($mimetype)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Invalid options to validator provided"); - } - - if (isset($mimetype['magicfile'])) { - unset($mimetype['magicfile']); - } - - foreach ($mimetype as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - $mimetypes[] = trim($content); - } - $mimetypes = array_unique($mimetypes); - - // Sanity check to ensure no empty values - foreach ($mimetypes as $key => $mt) { - if (empty($mt)) { - unset($mimetypes[$key]); - } - } - - $this->_mimetype = implode(',', $mimetypes); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if the mimetype of the file matches the given ones. Also parts - * of mimetypes can be checked. If you give for example "image" all image - * mime types will be accepted like "image/gif", "image/jpeg" and so on. - * - * @param string $value Real file to check for mimetype - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - if ($file === null) { - $file = array( - 'type' => null, - 'name' => $value - ); - } - - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_READABLE); - } - - $this->_type = $this->_detectMimeType($value); - - if (empty($this->_type) && $this->_headerCheck) { - $this->_type = $file['type']; - } - - if (empty($this->_type)) { - return $this->_throw($file, self::NOT_DETECTED); - } - - $mimetype = $this->getMimeType(true); - if (in_array($this->_type, $mimetype)) { - return true; - } - - $types = explode('/', $this->_type); - $types = array_merge($types, explode('-', $this->_type)); - $types = array_merge($types, explode(';', $this->_type)); - foreach($mimetype as $mime) { - if (in_array($mime, $types)) { - return true; - } - } - - return $this->_throw($file, self::FALSE_TYPE); - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - $this->_value = $file['name']; - $this->_error($errorType); - return false; - } - - /** - * Try to detect mime type of given file. - * @param string $file File which mime type should be detected - * @return string File mime type or null if not detected - */ - protected function _detectMimeType($file) - { - $mimefile = $this->getMagicFile(); - $type = null; - - if (class_exists('finfo', false)) { - $const = defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME; - - if (!empty($mimefile) && empty($this->_finfo)) { - set_error_handler(array($this, '_errorHandler'), E_NOTICE | E_WARNING); - $this->_finfo = finfo_open($const, $mimefile); - restore_error_handler(); - } - - if (empty($this->_finfo)) { - set_error_handler(array($this, '_errorHandler'), E_NOTICE | E_WARNING); - $this->_finfo = finfo_open($const); - restore_error_handler(); - } - - if (!empty($this->_finfo)) { - $type = finfo_file($this->_finfo, $file); - } - } - - if (empty($type) && - (function_exists('mime_content_type') && ini_get('mime_magic.magicfile'))) { - $type = mime_content_type($file); - } - - return $type; - } - - /** - * Saves the provided error information by finfo_open to this instance - * - * @param integer $errno - * @param string $errstr - * @param string $errfile - * @param integer $errline - */ - protected function _errorHandler($errno, $errstr, $errfile, $errline) - { - $this->_finfoError = new ErrorException($errstr, $errno, 0, $errfile, $errline); - } -} diff --git a/lib/Zend/Validate/File/NotExists.php b/lib/Zend/Validate/File/NotExists.php deleted file mode 100644 index de801503668..00000000000 --- a/lib/Zend/Validate/File/NotExists.php +++ /dev/null @@ -1,84 +0,0 @@ - "File '%value%' exists", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file does not exist in the set destinations - * - * @param string $value Real file to check for - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - $directories = $this->getDirectory(true); - if (($file !== null) and (!empty($file['destination']))) { - $directories[] = $file['destination']; - } else if (!isset($file['name'])) { - $file['name'] = $value; - } - - foreach ($directories as $directory) { - if (empty($directory)) { - continue; - } - - $check = true; - if (file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { - return $this->_throw($file, self::DOES_EXIST); - } - } - - if (!isset($check)) { - return $this->_throw($file, self::DOES_EXIST); - } - - return true; - } -} diff --git a/lib/Zend/Validate/File/Sha1.php b/lib/Zend/Validate/File/Sha1.php deleted file mode 100644 index c54e7153dc7..00000000000 --- a/lib/Zend/Validate/File/Sha1.php +++ /dev/null @@ -1,182 +0,0 @@ - "File '%value%' does not match the given sha1 hashes", - self::NOT_DETECTED => "A sha1 hash could not be evaluated for the given file", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Hash of the file - * - * @var string - */ - protected $_hash; - - /** - * Sets validator options - * - * $hash is the hash we accept for the file $file - * - * @param string|array $options - * @throws Zend_Validate_Exception - * @return Zend_Validate_File_Sha1 - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_scalar($options)) { - $options = array('hash1' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options to validator provided'); - } - - $this->setHash($options); - } - - /** - * Returns all set sha1 hashes - * - * @return array - */ - public function getSha1() - { - return $this->getHash(); - } - - /** - * Sets the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setHash($options) - { - if (!is_array($options)) { - $options = (array) $options; - } - - $options['algorithm'] = 'sha1'; - parent::setHash($options); - return $this; - } - - /** - * Sets the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function setSha1($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addHash($options) - { - if (!is_array($options)) { - $options = (array) $options; - } - - $options['algorithm'] = 'sha1'; - parent::addHash($options); - return $this; - } - - /** - * Adds the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Zend_Validate_File_Hash Provides a fluent interface - */ - public function addSha1($options) - { - $this->addHash($options); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the given file confirms the set hash - * - * @param string $value Filename to check for hash - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - $hashes = array_unique(array_keys($this->_hash)); - $filehash = hash_file('sha1', $value); - if ($filehash === false) { - return $this->_throw($file, self::NOT_DETECTED); - } - - foreach ($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - return $this->_throw($file, self::DOES_NOT_MATCH); - } -} diff --git a/lib/Zend/Validate/File/Size.php b/lib/Zend/Validate/File/Size.php deleted file mode 100644 index f0651154ecc..00000000000 --- a/lib/Zend/Validate/File/Size.php +++ /dev/null @@ -1,405 +0,0 @@ - "Maximum allowed size for file '%value%' is '%max%' but '%size%' detected", - self::TOO_SMALL => "Minimum expected size for file '%value%' is '%min%' but '%size%' detected", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max', - 'size' => '_size', - ); - - /** - * Minimum filesize - * @var integer - */ - protected $_min; - - /** - * Maximum filesize - * - * If null, there is no maximum filesize - * - * @var integer|null - */ - protected $_max; - - /** - * Detected size - * - * @var integer - */ - protected $_size; - - /** - * Use bytestring ? - * - * @var boolean - */ - protected $_useByteString = true; - - /** - * Sets validator options - * - * If $options is a integer, it will be used as maximum filesize - * As Array is accepts the following keys: - * 'min': Minimum filesize - * 'max': Maximum filesize - * 'bytestring': Use bytestring or real size for messages - * - * @param integer|array $options Options for the adapter - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } elseif (is_string($options) || is_numeric($options)) { - $options = array('max' => $options); - } elseif (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - if (1 < func_num_args()) { - $argv = func_get_args(); - array_shift($argv); - $options['max'] = array_shift($argv); - if (!empty($argv)) { - $options['bytestring'] = array_shift($argv); - } - } - - if (isset($options['bytestring'])) { - $this->setUseByteString($options['bytestring']); - } - - if (isset($options['min'])) { - $this->setMin($options['min']); - } - - if (isset($options['max'])) { - $this->setMax($options['max']); - } - } - - /** - * Returns the minimum filesize - * - * @param boolean $byteString Use bytestring ? - * @return integer - */ - public function setUseByteString($byteString = true) - { - $this->_useByteString = (bool) $byteString; - return $this; - } - - /** - * Will bytestring be used? - * - * @return boolean - */ - public function useByteString() - { - return $this->_useByteString; - } - - /** - * Returns the minimum filesize - * - * @param bool $raw Whether or not to force return of the raw value (defaults off) - * @return integer|string - */ - public function getMin($raw = false) - { - $min = $this->_min; - if (!$raw && $this->useByteString()) { - $min = $this->_toByteString($min); - } - - return $min; - } - - /** - * Sets the minimum filesize - * - * @param integer $min The minimum filesize - * @throws Zend_Validate_Exception When min is greater than max - * @return Zend_Validate_File_Size Provides a fluent interface - */ - public function setMin($min) - { - if (!is_string($min) and !is_numeric($min)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - $min = (integer) $this->_fromByteString($min); - $max = $this->getMax(true); - if (($max !== null) && ($min > $max)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >" - . " $max"); - } - - $this->_min = $min; - return $this; - } - - /** - * Returns the maximum filesize - * - * @param bool $raw Whether or not to force return of the raw value (defaults off) - * @return integer|string - */ - public function getMax($raw = false) - { - $max = $this->_max; - if (!$raw && $this->useByteString()) { - $max = $this->_toByteString($max); - } - - return $max; - } - - /** - * Sets the maximum filesize - * - * @param integer $max The maximum filesize - * @throws Zend_Validate_Exception When max is smaller than min - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMax($max) - { - if (!is_string($max) && !is_numeric($max)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception ('Invalid options to validator provided'); - } - - $max = (integer) $this->_fromByteString($max); - $min = $this->getMin(true); - if (($min !== null) && ($max < $min)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but " - . "$max < $min"); - } - - $this->_max = $max; - return $this; - } - - /** - * Retrieve current detected file size - * - * @return int - */ - protected function _getSize() - { - return $this->_size; - } - - /** - * Set current size - * - * @param int $size - * @return Zend_Validate_File_Size - */ - protected function _setSize($size) - { - $this->_size = $size; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the filesize of $value is at least min and - * not bigger than max (when max is not null). - * - * @param string $value Real file to check for size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - // limited to 4GB files - $size = sprintf("%u", @filesize($value)); - $this->_size = $size; - - // Check to see if it's smaller than min size - $min = $this->getMin(true); - $max = $this->getMax(true); - if (($min !== null) && ($size < $min)) { - if ($this->useByteString()) { - $this->_min = $this->_toByteString($min); - $this->_size = $this->_toByteString($size); - $this->_throw($file, self::TOO_SMALL); - $this->_min = $min; - $this->_size = $size; - } else { - $this->_throw($file, self::TOO_SMALL); - } - } - - // Check to see if it's larger than max size - if (($max !== null) && ($max < $size)) { - if ($this->useByteString()) { - $this->_max = $this->_toByteString($max); - $this->_size = $this->_toByteString($size); - $this->_throw($file, self::TOO_BIG); - $this->_max = $max; - $this->_size = $size; - } else { - $this->_throw($file, self::TOO_BIG); - } - } - - if (count($this->_messages) > 0) { - return false; - } - - return true; - } - - /** - * Returns the formatted size - * - * @param integer $size - * @return string - */ - protected function _toByteString($size) - { - $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); - for ($i=0; $size >= 1024 && $i < 9; $i++) { - $size /= 1024; - } - - return round($size, 2) . $sizes[$i]; - } - - /** - * Returns the unformatted size - * - * @param string $size - * @return integer - */ - protected function _fromByteString($size) - { - if (is_numeric($size)) { - return (integer) $size; - } - - $type = trim(substr($size, -2, 1)); - - $value = substr($size, 0, -1); - if (!is_numeric($value)) { - $value = substr($value, 0, -1); - } - - switch (strtoupper($type)) { - case 'Y': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'Z': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'E': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'P': - $value *= (1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'T': - $value *= (1024 * 1024 * 1024 * 1024); - break; - case 'G': - $value *= (1024 * 1024 * 1024); - break; - case 'M': - $value *= (1024 * 1024); - break; - case 'K': - $value *= 1024; - break; - default: - break; - } - - return $value; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/Upload.php b/lib/Zend/Validate/File/Upload.php deleted file mode 100644 index 475b68cc3a1..00000000000 --- a/lib/Zend/Validate/File/Upload.php +++ /dev/null @@ -1,251 +0,0 @@ - "File '%value%' exceeds the defined ini size", - self::FORM_SIZE => "File '%value%' exceeds the defined form size", - self::PARTIAL => "File '%value%' was only partially uploaded", - self::NO_FILE => "File '%value%' was not uploaded", - self::NO_TMP_DIR => "No temporary directory was found for file '%value%'", - self::CANT_WRITE => "File '%value%' can't be written", - self::EXTENSION => "A PHP extension returned an error while uploading the file '%value%'", - self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", - self::FILE_NOT_FOUND => "File '%value%' was not found", - self::UNKNOWN => "Unknown error while uploading file '%value%'" - ); - - /** - * Internal array of files - * @var array - */ - protected $_files = array(); - - /** - * Sets validator options - * - * The array $files must be given in syntax of Zend_File_Transfer to be checked - * If no files are given the $_FILES array will be used automatically. - * NOTE: This validator will only work with HTTP POST uploads! - * - * @param array|Zend_Config $files Array of files in syntax of Zend_File_Transfer - */ - public function __construct($files = array()) - { - if ($files instanceof Zend_Config) { - $files = $files->toArray(); - } - - $this->setFiles($files); - } - - /** - * Returns the array of set files - * - * @param string $file (Optional) The file to return in detail - * @return array - * @throws Zend_Validate_Exception If file is not found - */ - public function getFiles($file = null) - { - if ($file !== null) { - $return = array(); - foreach ($this->_files as $name => $content) { - if ($name === $file) { - $return[$file] = $this->_files[$name]; - } - - if ($content['name'] === $file) { - $return[$name] = $this->_files[$name]; - } - } - - if (count($return) === 0) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The file '$file' was not found"); - } - - return $return; - } - - return $this->_files; - } - - /** - * Sets the files to be checked - * - * @param array $files The files to check in syntax of Zend_File_Transfer - * @return Zend_Validate_File_Upload Provides a fluent interface - */ - public function setFiles($files = array()) - { - if (count($files) === 0) { - $this->_files = $_FILES; - } else { - $this->_files = $files; - } - - // see ZF-10738 - if (is_null($this->_files)) { - $this->_files = array(); - } - - foreach($this->_files as $file => $content) { - if (!isset($content['error'])) { - unset($this->_files[$file]); - } - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file was uploaded without errors - * - * @param string $value Single file to check for upload errors, when giving null the $_FILES array - * from initialization will be used - * @param string|null $file - * @return boolean - */ - public function isValid($value, $file = null) - { - $this->_messages = null; - if (array_key_exists($value, $this->_files)) { - $files[$value] = $this->_files[$value]; - } else { - foreach ($this->_files as $file => $content) { - if (isset($content['name']) && ($content['name'] === $value)) { - $files[$file] = $this->_files[$file]; - } - - if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) { - $files[$file] = $this->_files[$file]; - } - } - } - - if (empty($files)) { - return $this->_throw($file, self::FILE_NOT_FOUND); - } - - foreach ($files as $file => $content) { - $this->_value = $file; - switch($content['error']) { - case 0: - if (!is_uploaded_file($content['tmp_name'])) { - $this->_throw($content, self::ATTACK); - } - break; - - case 1: - $this->_throw($content, self::INI_SIZE); - break; - - case 2: - $this->_throw($content, self::FORM_SIZE); - break; - - case 3: - $this->_throw($content, self::PARTIAL); - break; - - case 4: - $this->_throw($content, self::NO_FILE); - break; - - case 6: - $this->_throw($content, self::NO_TMP_DIR); - break; - - case 7: - $this->_throw($content, self::CANT_WRITE); - break; - - case 8: - $this->_throw($content, self::EXTENSION); - break; - - default: - $this->_throw($content, self::UNKNOWN); - break; - } - } - - if (count($this->_messages) > 0) { - return false; - } else { - return true; - } - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - if (is_array($file) and !empty($file['name'])) { - $this->_value = $file['name']; - } - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/File/WordCount.php b/lib/Zend/Validate/File/WordCount.php deleted file mode 100644 index 95707338455..00000000000 --- a/lib/Zend/Validate/File/WordCount.php +++ /dev/null @@ -1,101 +0,0 @@ - "Too much words, maximum '%max%' are allowed but '%count%' were counted", - self::TOO_LESS => "Too less words, minimum '%min%' are expected but '%count%' were counted", - self::NOT_FOUND => "File '%value%' is not readable or does not exist", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the counted words are at least min and - * not bigger than max (when max is not null). - * - * @param string $value Filename to check for word count - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - #require_once 'Zend/Loader.php'; - if (!Zend_Loader::isReadable($value)) { - return $this->_throw($file, self::NOT_FOUND); - } - - $content = file_get_contents($value); - $this->_count = str_word_count($content); - if (($this->_max !== null) && ($this->_count > $this->_max)) { - return $this->_throw($file, self::TOO_MUCH); - } - - if (($this->_min !== null) && ($this->_count < $this->_min)) { - return $this->_throw($file, self::TOO_LESS); - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/lib/Zend/Validate/Float.php b/lib/Zend/Validate/Float.php deleted file mode 100644 index c94f43ac1f1..00000000000 --- a/lib/Zend/Validate/Float.php +++ /dev/null @@ -1,135 +0,0 @@ - "Invalid type given. String, integer or float expected", - self::NOT_FLOAT => "'%value%' does not appear to be a float", - ); - - protected $_locale; - - /** - * Constructor for the float validator - * - * @param string|Zend_Config|Zend_Locale $locale - */ - public function __construct($locale = null) - { - if ($locale instanceof Zend_Config) { - $locale = $locale->toArray(); - } - - if (is_array($locale)) { - if (array_key_exists('locale', $locale)) { - $locale = $locale['locale']; - } else { - $locale = null; - } - } - - if (empty($locale)) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Locale')) { - $locale = Zend_Registry::get('Zend_Locale'); - } - } - - $this->setLocale($locale); - } - - /** - * Returns the set locale - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale to use - * - * @param string|Zend_Locale $locale - * @return $this - */ - public function setLocale($locale = null) - { - #require_once 'Zend/Locale.php'; - $this->_locale = Zend_Locale::findLocale($locale); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a floating-point value - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->_error(self::INVALID); - return false; - } - - if (is_float($value)) { - return true; - } - - $this->_setValue($value); - try { - if (!Zend_Locale_Format::isFloat($value, array('locale' => $this->_locale))) { - $this->_error(self::NOT_FLOAT); - return false; - } - } catch (Zend_Locale_Exception $e) { - $this->_error(self::NOT_FLOAT); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/GreaterThan.php b/lib/Zend/Validate/GreaterThan.php deleted file mode 100644 index 707bbc4a6c5..00000000000 --- a/lib/Zend/Validate/GreaterThan.php +++ /dev/null @@ -1,124 +0,0 @@ - "'%value%' is not greater than '%min%'", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min' - ); - - /** - * Minimum value - * - * @var mixed - */ - protected $_min; - - /** - * Sets validator options - * - * @param mixed|Zend_Config $min - * @throws Zend_Validate_Exception - */ - public function __construct($min) - { - if ($min instanceof Zend_Config) { - $min = $min->toArray(); - } - - if (is_array($min)) { - if (array_key_exists('min', $min)) { - $min = $min['min']; - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Missing option 'min'"); - } - } - - $this->setMin($min); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param mixed $min - * @return Zend_Validate_GreaterThan Provides a fluent interface - */ - public function setMin($min) - { - $this->_min = $min; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is greater than min option - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if ($this->_min >= $value) { - $this->_error(self::NOT_GREATER); - return false; - } - return true; - } - -} diff --git a/lib/Zend/Validate/Hex.php b/lib/Zend/Validate/Hex.php deleted file mode 100644 index 50cee39e3c5..00000000000 --- a/lib/Zend/Validate/Hex.php +++ /dev/null @@ -1,72 +0,0 @@ - "Invalid type given. String expected", - self::NOT_HEX => "'%value%' has not only hexadecimal digit characters", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only hexadecimal digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - if (!ctype_xdigit((string) $value)) { - $this->_error(self::NOT_HEX); - return false; - } - - return true; - } - -} diff --git a/lib/Zend/Validate/Hostname.php b/lib/Zend/Validate/Hostname.php deleted file mode 100644 index 500a256bcc2..00000000000 --- a/lib/Zend/Validate/Hostname.php +++ /dev/null @@ -1,1661 +0,0 @@ - "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", - self::INVALID => "Invalid type given. String expected", - self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", - self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", - self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", - self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", - self::INVALID_URI => "'%value%' does not appear to be a valid URI hostname", - self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed", - self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed", - self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", - self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'tld' => '_tld' - ); - - /** - * Allows Internet domain names (e.g., example.com) - */ - const ALLOW_DNS = 1; - - /** - * Allows IP addresses - */ - const ALLOW_IP = 2; - - /** - * Allows local network names (e.g., localhost, www.localdomain) - */ - const ALLOW_LOCAL = 4; - - /** - * Allows all types of hostnames - */ - const ALLOW_URI = 8; - - /** - * Allows all types of hostnames - */ - const ALLOW_ALL = 15; - - /** - * Array of valid top-level-domains - * - * Version 2014112800, Last Updated Fri Nov 28 07:07:01 2014 UTC - * - * @see http://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain - * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs - * @var array - */ - protected $_validTlds = array( - 'abogado', - 'ac', - 'academy', - 'accountants', - 'active', - 'actor', - 'ad', - 'ae', - 'aero', - 'af', - 'ag', - 'agency', - 'ai', - 'airforce', - 'al', - 'allfinanz', - 'alsace', - 'am', - 'an', - 'android', - 'ao', - 'aq', - 'ar', - 'archi', - 'army', - 'arpa', - 'as', - 'asia', - 'associates', - 'at', - 'attorney', - 'au', - 'auction', - 'audio', - 'autos', - 'aw', - 'ax', - 'axa', - 'az', - 'ba', - 'band', - 'bar', - 'bargains', - 'bayern', - 'bb', - 'bd', - 'be', - 'beer', - 'berlin', - 'best', - 'bf', - 'bg', - 'bh', - 'bi', - 'bid', - 'bike', - 'bio', - 'biz', - 'bj', - 'black', - 'blackfriday', - 'bloomberg', - 'blue', - 'bm', - 'bmw', - 'bn', - 'bnpparibas', - 'bo', - 'boo', - 'boutique', - 'br', - 'brussels', - 'bs', - 'bt', - 'budapest', - 'build', - 'builders', - 'business', - 'buzz', - 'bv', - 'bw', - 'by', - 'bz', - 'bzh', - 'ca', - 'cab', - 'cal', - 'camera', - 'camp', - 'cancerresearch', - 'capetown', - 'capital', - 'caravan', - 'cards', - 'care', - 'career', - 'careers', - 'casa', - 'cash', - 'cat', - 'catering', - 'cc', - 'cd', - 'center', - 'ceo', - 'cern', - 'cf', - 'cg', - 'ch', - 'channel', - 'cheap', - 'christmas', - 'chrome', - 'church', - 'ci', - 'citic', - 'city', - 'ck', - 'cl', - 'claims', - 'cleaning', - 'click', - 'clinic', - 'clothing', - 'club', - 'cm', - 'cn', - 'co', - 'coach', - 'codes', - 'coffee', - 'college', - 'cologne', - 'com', - 'community', - 'company', - 'computer', - 'condos', - 'construction', - 'consulting', - 'contractors', - 'cooking', - 'cool', - 'coop', - 'country', - 'cr', - 'credit', - 'creditcard', - 'cricket', - 'crs', - 'cruises', - 'cu', - 'cuisinella', - 'cv', - 'cw', - 'cx', - 'cy', - 'cymru', - 'cz', - 'dad', - 'dance', - 'dating', - 'day', - 'de', - 'deals', - 'degree', - 'delivery', - 'democrat', - 'dental', - 'dentist', - 'desi', - 'diamonds', - 'diet', - 'digital', - 'direct', - 'directory', - 'discount', - 'dj', - 'dk', - 'dm', - 'dnp', - 'do', - 'domains', - 'durban', - 'dvag', - 'dz', - 'eat', - 'ec', - 'edu', - 'education', - 'ee', - 'eg', - 'email', - 'emerck', - 'energy', - 'engineer', - 'engineering', - 'enterprises', - 'equipment', - 'er', - 'es', - 'esq', - 'estate', - 'et', - 'eu', - 'eus', - 'events', - 'everbank', - 'exchange', - 'expert', - 'exposed', - 'fail', - 'farm', - 'feedback', - 'fi', - 'finance', - 'financial', - 'firmdale', - 'fish', - 'fishing', - 'fitness', - 'fj', - 'fk', - 'flights', - 'florist', - 'flsmidth', - 'fly', - 'fm', - 'fo', - 'foo', - 'forsale', - 'foundation', - 'fr', - 'frl', - 'frogans', - 'fund', - 'furniture', - 'futbol', - 'ga', - 'gal', - 'gallery', - 'gb', - 'gbiz', - 'gd', - 'ge', - 'gent', - 'gf', - 'gg', - 'gh', - 'gi', - 'gift', - 'gifts', - 'gives', - 'gl', - 'glass', - 'gle', - 'global', - 'globo', - 'gm', - 'gmail', - 'gmo', - 'gmx', - 'gn', - 'google', - 'gop', - 'gov', - 'gp', - 'gq', - 'gr', - 'graphics', - 'gratis', - 'green', - 'gripe', - 'gs', - 'gt', - 'gu', - 'guide', - 'guitars', - 'guru', - 'gw', - 'gy', - 'hamburg', - 'haus', - 'healthcare', - 'help', - 'here', - 'hiphop', - 'hiv', - 'hk', - 'hm', - 'hn', - 'holdings', - 'holiday', - 'homes', - 'horse', - 'host', - 'hosting', - 'house', - 'how', - 'hr', - 'ht', - 'hu', - 'ibm', - 'id', - 'ie', - 'il', - 'im', - 'immo', - 'immobilien', - 'in', - 'industries', - 'info', - 'ing', - 'ink', - 'institute', - 'insure', - 'int', - 'international', - 'investments', - 'io', - 'iq', - 'ir', - 'is', - 'it', - 'je', - 'jetzt', - 'jm', - 'jo', - 'jobs', - 'joburg', - 'jp', - 'juegos', - 'kaufen', - 'ke', - 'kg', - 'kh', - 'ki', - 'kim', - 'kitchen', - 'kiwi', - 'km', - 'kn', - 'koeln', - 'kp', - 'kr', - 'krd', - 'kred', - 'kw', - 'ky', - 'kz', - 'la', - 'lacaixa', - 'land', - 'lawyer', - 'lb', - 'lc', - 'lds', - 'lease', - 'legal', - 'lgbt', - 'li', - 'life', - 'lighting', - 'limited', - 'limo', - 'link', - 'lk', - 'loans', - 'london', - 'lotto', - 'lr', - 'ls', - 'lt', - 'ltda', - 'lu', - 'luxe', - 'luxury', - 'lv', - 'ly', - 'ma', - 'madrid', - 'maison', - 'management', - 'mango', - 'market', - 'marketing', - 'mc', - 'md', - 'me', - 'media', - 'meet', - 'melbourne', - 'meme', - 'memorial', - 'menu', - 'mg', - 'mh', - 'miami', - 'mil', - 'mini', - 'mk', - 'ml', - 'mm', - 'mn', - 'mo', - 'mobi', - 'moda', - 'moe', - 'monash', - 'money', - 'mormon', - 'mortgage', - 'moscow', - 'motorcycles', - 'mov', - 'mp', - 'mq', - 'mr', - 'ms', - 'mt', - 'mu', - 'museum', - 'mv', - 'mw', - 'mx', - 'my', - 'mz', - 'na', - 'nagoya', - 'name', - 'navy', - 'nc', - 'ne', - 'net', - 'network', - 'neustar', - 'new', - 'nexus', - 'nf', - 'ng', - 'ngo', - 'nhk', - 'ni', - 'ninja', - 'nl', - 'no', - 'np', - 'nr', - 'nra', - 'nrw', - 'nu', - 'nyc', - 'nz', - 'okinawa', - 'om', - 'ong', - 'onl', - 'ooo', - 'org', - 'organic', - 'otsuka', - 'ovh', - 'pa', - 'paris', - 'partners', - 'parts', - 'party', - 'pe', - 'pf', - 'pg', - 'ph', - 'pharmacy', - 'photo', - 'photography', - 'photos', - 'physio', - 'pics', - 'pictures', - 'pink', - 'pizza', - 'pk', - 'pl', - 'place', - 'plumbing', - 'pm', - 'pn', - 'pohl', - 'poker', - 'post', - 'pr', - 'praxi', - 'press', - 'pro', - 'prod', - 'productions', - 'prof', - 'properties', - 'property', - 'ps', - 'pt', - 'pub', - 'pw', - 'py', - 'qa', - 'qpon', - 'quebec', - 're', - 'realtor', - 'recipes', - 'red', - 'rehab', - 'reise', - 'reisen', - 'reit', - 'ren', - 'rentals', - 'repair', - 'report', - 'republican', - 'rest', - 'restaurant', - 'reviews', - 'rich', - 'rio', - 'rip', - 'ro', - 'rocks', - 'rodeo', - 'rs', - 'rsvp', - 'ru', - 'ruhr', - 'rw', - 'ryukyu', - 'sa', - 'saarland', - 'sarl', - 'sb', - 'sc', - 'sca', - 'scb', - 'schmidt', - 'schule', - 'science', - 'scot', - 'sd', - 'se', - 'services', - 'sexy', - 'sg', - 'sh', - 'shiksha', - 'shoes', - 'si', - 'singles', - 'sj', - 'sk', - 'sl', - 'sm', - 'sn', - 'so', - 'social', - 'software', - 'sohu', - 'solar', - 'solutions', - 'soy', - 'space', - 'spiegel', - 'sr', - 'st', - 'su', - 'supplies', - 'supply', - 'support', - 'surf', - 'surgery', - 'suzuki', - 'sv', - 'sx', - 'sy', - 'sydney', - 'systems', - 'sz', - 'taipei', - 'tatar', - 'tattoo', - 'tax', - 'tc', - 'td', - 'technology', - 'tel', - 'tf', - 'tg', - 'th', - 'tienda', - 'tips', - 'tirol', - 'tj', - 'tk', - 'tl', - 'tm', - 'tn', - 'to', - 'today', - 'tokyo', - 'tools', - 'top', - 'town', - 'toys', - 'tp', - 'tr', - 'trade', - 'training', - 'travel', - 'tt', - 'tui', - 'tv', - 'tw', - 'tz', - 'ua', - 'ug', - 'uk', - 'university', - 'uno', - 'uol', - 'us', - 'uy', - 'uz', - 'va', - 'vacations', - 'vc', - 've', - 'vegas', - 'ventures', - 'versicherung', - 'vet', - 'vg', - 'vi', - 'viajes', - 'villas', - 'vision', - 'vlaanderen', - 'vn', - 'vodka', - 'vote', - 'voting', - 'voto', - 'voyage', - 'vu', - 'wales', - 'wang', - 'watch', - 'webcam', - 'website', - 'wed', - 'wedding', - 'wf', - 'whoswho', - 'wien', - 'wiki', - 'williamhill', - 'wme', - 'work', - 'works', - 'world', - 'ws', - 'wtc', - 'wtf', - 'xn--1qqw23a', - 'xn--3bst00m', - 'xn--3ds443g', - 'xn--3e0b707e', - 'xn--45brj9c', - 'xn--45q11c', - 'xn--4gbrim', - 'xn--55qw42g', - 'xn--55qx5d', - 'xn--6frz82g', - 'xn--6qq986b3xl', - 'xn--80adxhks', - 'xn--80ao21a', - 'xn--80asehdb', - 'xn--80aswg', - 'xn--90a3ac', - 'xn--c1avg', - 'xn--cg4bki', - 'xn--clchc0ea0b2g2a9gcd', - 'xn--czr694b', - 'xn--czru2d', - 'xn--d1acj3b', - 'xn--d1alf', - 'xn--fiq228c5hs', - 'xn--fiq64b', - 'xn--fiqs8s', - 'xn--fiqz9s', - 'xn--flw351e', - 'xn--fpcrj9c3d', - 'xn--fzc2c9e2c', - 'xn--gecrj9c', - 'xn--h2brj9c', - 'xn--i1b6b1a6a2e', - 'xn--io0a7i', - 'xn--j1amh', - 'xn--j6w193g', - 'xn--kprw13d', - 'xn--kpry57d', - 'xn--kput3i', - 'xn--l1acc', - 'xn--lgbbat1ad8j', - 'xn--mgb9awbf', - 'xn--mgba3a4f16a', - 'xn--mgbaam7a8h', - 'xn--mgbab2bd', - 'xn--mgbayh7gpa', - 'xn--mgbbh1a71e', - 'xn--mgbc0a9azcg', - 'xn--mgberp4a5d4ar', - 'xn--mgbx4cd0ab', - 'xn--ngbc5azd', - 'xn--node', - 'xn--nqv7f', - 'xn--nqv7fs00ema', - 'xn--o3cw4h', - 'xn--ogbpf8fl', - 'xn--p1acf', - 'xn--p1ai', - 'xn--pgbs0dh', - 'xn--q9jyb4c', - 'xn--qcka1pmc', - 'xn--rhqv96g', - 'xn--s9brj9c', - 'xn--ses554g', - 'xn--unup4y', - 'xn--vermgensberater-ctb', - 'xn--vermgensberatung-pwb', - 'xn--vhquv', - 'xn--wgbh1c', - 'xn--wgbl6a', - 'xn--xhq521b', - 'xn--xkc2al3hye2a', - 'xn--xkc2dl3a5ee0h', - 'xn--yfro4i67o', - 'xn--ygbi2ammx', - 'xn--zfr164b', - 'xxx', - 'xyz', - 'yachts', - 'yandex', - 'ye', - 'yoga', - 'yokohama', - 'youtube', - 'yt', - 'za', - 'zip', - 'zm', - 'zone', - 'zw', - '测试', - 'परीक्षा', - '佛山', - '集团', - '在线', - '한국', - 'ভারত', - '八卦', - 'موقع', - 'বাংলা', - '公益', - '公司', - '移动', - '我爱你', - 'москва', - 'испытание', - 'қаз', - 'онлайн', - 'сайт', - 'срб', - 'бел', - '테스트', - 'орг', - '삼성', - 'சிங்கப்பூர்', - '商标', - '商城', - 'дети', - 'мкд', - 'טעסט', - '中文网', - '中信', - '中国', - '中國', - '谷歌', - 'భారత్', - 'ලංකා', - '測試', - 'ભારત', - 'भारत', - 'آزمایشی', - 'பரிட்சை', - 'संगठन', - '网络', - 'укр', - '香港', - 'δοκιμή', - 'إختبار', - '台湾', - '台灣', - '手机', - 'мон', - 'الجزائر', - 'عمان', - 'ایران', - 'امارات', - 'بازار', - 'پاکستان', - 'الاردن', - 'بھارت', - 'المغرب', - 'السعودية', - 'سودان', - 'عراق', - 'مليسيا', - 'شبكة', - 'გე', - '机构', - '组织机构', - 'ไทย', - 'سورية', - 'рус', - 'рф', - 'تونس', - 'みんな', - 'グーグル', - '世界', - 'ਭਾਰਤ', - '网址', - '游戏', - 'vermögensberater', - 'vermögensberatung', - '企业', - 'مصر', - 'قطر', - '广东', - 'இலங்கை', - 'இந்தியா', - 'հայ', - '新加坡', - 'فلسطين', - 'テスト', - '政务', - ); - - /** - * @var string - */ - protected $_tld; - - /** - * Array for valid Idns - * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars - * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf - * (.AR) Argentinia http://www.nic.ar/faqidn.html - * (.AS) American Samoa http://www.nic.as/idn/chars.cfm - * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ - * (.BIZ) International http://www.iana.org/domains/idn-tables/ - * (.BR) Brazil http://registro.br/faq/faq6.html - * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.CA) Canada http://www.iana.org/domains/idn-tables/tables/ca_fr_1.0.html - * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html - * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html - * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.DE) Germany http://www.denic.de/en/domains/idns/liste.html - * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 - * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf - * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html - * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp - * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html - * (.INFO) International http://www.nic.info/info/idn - * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf - * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran - * (.IS) Iceland http://www.isnic.is/domain/rules.php - * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html - * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf - * (.MD) Moldova http://www.register.md/ - * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html - * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.NU) Niue http://www.worldnames.net/ - * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 - * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php - * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf - * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp - * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); - * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html - * (.RS) Serbia http://www.iana.org/domains/idn-tables/tables/rs_sr-rs_1.0.pdf - * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html - * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en - * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf - * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html - * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf - * (.TR) Turkey https://www.nic.tr/index.php - * (.UA) Ukraine http://www.iana.org/domains/idn-tables/tables/ua_cyrl_1.2.html - * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html - * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction - * - * @var array - */ - protected $_validIdns = array( - 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), - 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'), - 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'), - 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'), - 'BIZ' => 'Zend/Validate/Hostname/Biz.php', - 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'), - 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'CA' => array(1 => '/^[\x{002d}0-9a-zàâæçéèêëîïôœùûüÿ\x{00E0}\x{00E2}\x{00E7}\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{00EE}\x{00EF}\x{00F4}\x{00F9}\x{00FB}\x{00FC}\x{00E6}\x{0153}\x{00FF}]{1,63}$/iu'), - 'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'), - 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), - 'CL' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), - 'CN' => 'Zend/Validate/Hostname/Cn.php', - 'COM' => 'Zend/Validate/Hostname/Com.php', - 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťßţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'DK' => array(1 => '/^[\x{002d}0-9a-zäéöüæøå]{1,63}$/iu'), - 'ES' => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'), - 'EU' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ὼώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ῒΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'), - 'FI' => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'), - 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'), - 'HK' => 'Zend/Validate/Hostname/Cn.php', - 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'), - 'IL' => array(1 => '/^[\x{002d}0-9\x{05D0}-\x{05EA}]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-z]{1,63}$/i'), - 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', - 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), - 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'IS' => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'), - 'IT' => array(1 => '/^[\x{002d}0-9a-zàâäèéêëìîïòôöùûüæœçÿß-]{1,63}$/iu'), - 'JP' => 'Zend/Validate/Hostname/Jp.php', - 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'), - 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), - 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'), - 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'), - 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'), - 'NET' => 'Zend/Validate/Hostname/Com.php', - 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'NU' => 'Zend/Validate/Hostname/Com.php', - 'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'), - 'PE' => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'), - 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', - 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', - 11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu', - 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', - 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', - 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', - 15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', - 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', - 18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', - 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', - 20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', - 21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', - 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', - 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', - 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', - 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', - 26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', - 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', - 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', - 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', - 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', - 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'), - 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'), - 'PT' => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'), - 'RS' => array(1 => '/^[\x{002D}\x{0030}-\x{0039}\x{0061}-\x{007A}\x{0107}\x{010D}\x{0111}\x{0161}\x{017E}]{1,63}$/iu)'), - 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), - 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'), - 'SE' => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'), - 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'SI' => array( - 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu'), - 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), - 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), - 'TW' => 'Zend/Validate/Hostname/Cn.php', - 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'), - 'UA' => array(1 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџґӂʼ]{1,63}$/iu'), - 'VE' => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'), - 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'), - 'мон' => array(1 => '/^[\x{002d}0-9\x{0430}-\x{044F}]{1,63}$/iu'), - 'срб' => array(1 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu'), - 'сайт' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), - 'онлайн' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), - '中国' => 'Zend/Validate/Hostname/Cn.php', - '中國' => 'Zend/Validate/Hostname/Cn.php', - 'ලංකා' => array(1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'), - '香港' => 'Zend/Validate/Hostname/Cn.php', - '台湾' => 'Zend/Validate/Hostname/Cn.php', - '台灣' => 'Zend/Validate/Hostname/Cn.php', - 'امارات' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'الاردن' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'السعودية' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'ไทย' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), - 'рф' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), - 'تونس' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'مصر' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'இலங்கை' => array(1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'), - 'فلسطين' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'شبكة' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - ); - - protected $_idnLength = array( - 'BIZ' => array(5 => 17, 11 => 15, 12 => 20), - 'CN' => array(1 => 20), - 'COM' => array(3 => 17, 5 => 20), - 'HK' => array(1 => 15), - 'INFO'=> array(4 => 17), - 'KR' => array(1 => 17), - 'NET' => array(3 => 17, 5 => 20), - 'ORG' => array(6 => 17), - 'TW' => array(1 => 20), - 'ایران' => array(1 => 30), - '中国' => array(1 => 20), - '公司' => array(1 => 20), - '网络' => array(1 => 20), - ); - - protected $_options = array( - 'allow' => self::ALLOW_DNS, - 'idn' => true, - 'tld' => true, - 'ip' => null - ); - - /** - * Sets validator options - * - * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs - * @param array $options Validator options - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['allow'] = array_shift($options); - if (!empty($options)) { - $temp['idn'] = array_shift($options); - } - - if (!empty($options)) { - $temp['tld'] = array_shift($options); - } - - if (!empty($options)) { - $temp['ip'] = array_shift($options); - } - - $options = $temp; - } - - $options += $this->_options; - $this->setOptions($options); - } - - /** - * Returns all set options - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Sets the options for this validator - * - * @param array $options - * @return Zend_Validate_Hostname - */ - public function setOptions($options) - { - if (array_key_exists('allow', $options)) { - $this->setAllow($options['allow']); - } - - if (array_key_exists('idn', $options)) { - $this->setValidateIdn($options['idn']); - } - - if (array_key_exists('tld', $options)) { - $this->setValidateTld($options['tld']); - } - - if (array_key_exists('ip', $options)) { - $this->setIpValidator($options['ip']); - } - - return $this; - } - - /** - * Returns the set ip validator - * - * @return Zend_Validate_Ip - */ - public function getIpValidator() - { - return $this->_options['ip']; - } - - /** - * @param Zend_Validate_Ip $ipValidator OPTIONAL - * @return Zend_Validate_Hostname - */ - public function setIpValidator(Zend_Validate_Ip $ipValidator = null) - { - if ($ipValidator === null) { - $ipValidator = new Zend_Validate_Ip(); - } - - $this->_options['ip'] = $ipValidator; - return $this; - } - - /** - * Returns the allow option - * - * @return integer - */ - public function getAllow() - { - return $this->_options['allow']; - } - - /** - * Sets the allow option - * - * @param integer $allow - * @return Zend_Validate_Hostname Provides a fluent interface - */ - public function setAllow($allow) - { - $this->_options['allow'] = $allow; - return $this; - } - - /** - * Returns the set idn option - * - * @return boolean - */ - public function getValidateIdn() - { - return $this->_options['idn']; - } - - /** - * Set whether IDN domains are validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them - * @return $this - */ - public function setValidateIdn ($allowed) - { - $this->_options['idn'] = (bool) $allowed; - return $this; - } - - /** - * Returns the set tld option - * - * @return boolean - */ - public function getValidateTld() - { - return $this->_options['tld']; - } - - /** - * Set whether the TLD element of a hostname is validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them - * @return $this - */ - public function setValidateTld ($allowed) - { - $this->_options['tld'] = (bool) $allowed; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the $value is a valid hostname with respect to the current allow option - * - * @param string $value - * @throws Zend_Validate_Exception if a fatal error occurs for validation process - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - // Check input against IP address schema - if (preg_match('/^[0-9a-f:.]*$/i', $value) && - $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { - if (!($this->_options['allow'] & self::ALLOW_IP)) { - $this->_error(self::IP_ADDRESS_NOT_ALLOWED); - return false; - } else { - return true; - } - } - - // RFC3986 3.2.2 states: - // - // The rightmost domain label of a fully qualified domain name - // in DNS may be followed by a single "." and should be if it is - // necessary to distinguish between the complete domain name and - // some local domain. - // - // (see ZF-6363) - - // Local hostnames are allowed to be partitial (ending '.') - if ($this->_options['allow'] & self::ALLOW_LOCAL) { - if (substr($value, -1) === '.') { - $value = substr($value, 0, -1); - if (substr($value, -1) === '.') { - // Empty hostnames (ending '..') are not allowed - $this->_error(self::INVALID_LOCAL_NAME); - return false; - } - } - } - - $domainParts = explode('.', $value); - - // Prevent partitial IP V4 adresses (ending '.') - if ((count($domainParts) == 4) && preg_match('/^[0-9.a-e:.]*$/i', $value) && - $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { - $this->_error(self::INVALID_LOCAL_NAME); - } - - // Check input against DNS hostname schema - if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) { - $status = false; - - $origenc = PHP_VERSION_ID < 50600 - ? iconv_get_encoding('internal_encoding') - : ini_get('default_charset'); - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('internal_encoding', 'UTF-8'); - } else { - ini_set('default_charset', 'UTF-8'); - } - do { - // First check TLD - $matches = array(); - if (preg_match('/([^.]{2,63})$/iu', end($domainParts), $matches) - || (array_key_exists(end($domainParts), $this->_validIdns))) { - reset($domainParts); - - // Hostname characters are: *(label dot)(label dot label); max 254 chars - // label: id-prefix [*ldh{61} id-prefix]; max 63 chars - // id-prefix: alpha / digit - // ldh: alpha / digit / dash - - // Match TLD against known list - $this->_tld = $matches[1]; - if ($this->_options['tld']) { - if (!in_array(strtolower($this->_tld), $this->_validTlds) - && !in_array($this->_tld, $this->_validTlds)) { - $this->_error(self::UNKNOWN_TLD); - $status = false; - break; - } - // We have already validated that the TLD is fine. We don't want it to go through the below - // checks as new UTF-8 TLDs will incorrectly fail if there is no IDN regex for it. - array_pop($domainParts); - } - - /** - * Match against IDN hostnames - * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames - * @see Zend_Validate_Hostname_Interface - */ - $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i'); - if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) { - if (is_string($this->_validIdns[strtoupper($this->_tld)])) { - $regexChars += include($this->_validIdns[strtoupper($this->_tld)]); - } else { - $regexChars += $this->_validIdns[strtoupper($this->_tld)]; - } - } - - // Check each hostname part - $check = 0; - foreach ($domainParts as $domainPart) { - // If some domain part is empty (i.e. zend..com), it's invalid - if (empty($domainPart) && $domainPart !== '0') { - $this->_error(self::INVALID_HOSTNAME); - return false; - } - - // Decode Punycode domainnames to IDN - if (strpos($domainPart, 'xn--') === 0) { - $domainPart = $this->decodePunycode(substr($domainPart, 4)); - if ($domainPart === false) { - return false; - } - } - - // Check dash (-) does not start, end or appear in 3rd and 4th positions - if ((strpos($domainPart, '-') === 0) - || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3)) - || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) { - $this->_error(self::INVALID_DASH); - $status = false; - break 2; - } - - // Check each domain part - $checked = false; - foreach($regexChars as $regexKey => $regexChar) { - $status = preg_match($regexChar, $domainPart); - if ($status > 0) { - $length = 63; - if (array_key_exists(strtoupper($this->_tld), $this->_idnLength) - && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) { - $length = $this->_idnLength[strtoupper($this->_tld)]; - } - - if (iconv_strlen($domainPart, 'UTF-8') > $length) { - $this->_error(self::INVALID_HOSTNAME); - } else { - $checked = true; - break; - } - } - } - - if ($checked) { - ++$check; - } - } - - // If one of the labels doesn't match, the hostname is invalid - if ($check !== count($domainParts)) { - $this->_error(self::INVALID_HOSTNAME_SCHEMA); - $status = false; - } - } else { - // Hostname not long enough - $this->_error(self::UNDECIPHERABLE_TLD); - $status = false; - } - } while (false); - - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('internal_encoding', $origenc); - } else { - ini_set('default_charset', $origenc); - } - // If the input passes as an Internet domain name, and domain names are allowed, then the hostname - // passes validation - if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) { - return true; - } - } else if ($this->_options['allow'] & self::ALLOW_DNS) { - $this->_error(self::INVALID_HOSTNAME); - } - - // Check for URI Syntax (RFC3986) - if ($this->_options['allow'] & self::ALLOW_URI) { - if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { - return true; - } else { - $this->_error(self::INVALID_URI); - } - } - - // Check input against local network name schema; last chance to pass validation - $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; - $status = @preg_match($regexLocal, $value); - - // If the input passes as a local network name, and local network names are allowed, then the - // hostname passes validation - $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL; - if ($status && $allowLocal) { - return true; - } - - // If the input does not pass as a local network name, add a message - if (!$status) { - $this->_error(self::INVALID_LOCAL_NAME); - } - - // If local network names are not allowed, add a message - if ($status && !$allowLocal) { - $this->_error(self::LOCAL_NAME_NOT_ALLOWED); - } - - return false; - } - - /** - * Decodes a punycode encoded string to it's original utf8 string - * In case of a decoding failure the original string is returned - * - * @param string $encoded Punycode encoded string to decode - * @return string - */ - protected function decodePunycode($encoded) - { - if (!preg_match('/^[a-z0-9-]+$/i', $encoded)) { - // no punycode encoded string - $this->_error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - - $decoded = array(); - $separator = strrpos($encoded, '-'); - if ($separator > 0) { - for ($x = 0; $x < $separator; ++$x) { - // prepare decoding matrix - $decoded[] = ord($encoded[$x]); - } - } - - $lengthd = count($decoded); - $lengthe = strlen($encoded); - - // decoding - $init = true; - $base = 72; - $index = 0; - $char = 0x80; - - for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { - for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) { - $hex = ord($encoded[$indexe++]); - $digit = ($hex - 48 < 10) ? $hex - 22 - : (($hex - 65 < 26) ? $hex - 65 - : (($hex - 97 < 26) ? $hex - 97 - : 36)); - - $index += $digit * $pos; - $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); - if ($digit < $tag) { - break; - } - - $pos = (int) ($pos * (36 - $tag)); - } - - $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2)); - $delta += intval($delta / ($lengthd + 1)); - for ($key = 0; $delta > 910 / 2; $key += 36) { - $delta = intval($delta / 35); - } - - $base = intval($key + 36 * $delta / ($delta + 38)); - $init = false; - $char += (int) ($index / ($lengthd + 1)); - $index %= ($lengthd + 1); - if ($lengthd > 0) { - for ($i = $lengthd; $i > $index; $i--) { - $decoded[$i] = $decoded[($i - 1)]; - } - } - - $decoded[$index++] = $char; - } - - // convert decoded ucs4 to utf8 string - foreach ($decoded as $key => $value) { - if ($value < 128) { - $decoded[$key] = chr($value); - } elseif ($value < (1 << 11)) { - $decoded[$key] = chr(192 + ($value >> 6)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < (1 << 16)) { - $decoded[$key] = chr(224 + ($value >> 12)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < (1 << 21)) { - $decoded[$key] = chr(240 + ($value >> 18)); - $decoded[$key] .= chr(128 + (($value >> 12) & 63)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } else { - $this->_error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - } - - return implode($decoded); - } -} diff --git a/lib/Zend/Validate/Hostname/Biz.php b/lib/Zend/Validate/Hostname/Biz.php deleted file mode 100644 index eb1bea22d9d..00000000000 --- a/lib/Zend/Validate/Hostname/Biz.php +++ /dev/null @@ -1,2917 +0,0 @@ - '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', - 5 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu', - 9 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 10 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu', - 11 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}\x{30A1}-\x{30F6}\x{30FC}' . -'\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . -'\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' . -'\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' . -'\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' . -'\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' . -'\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' . -'\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' . -'\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' . -'\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' . -'\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' . -'\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' . -'\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' . -'\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' . -'\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' . -'\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' . -'\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' . -'\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' . -'\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' . -'\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' . -'\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' . -'\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' . -'\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' . -'\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' . -'\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' . -'\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' . -'\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' . -'\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' . -'\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' . -'\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' . -'\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' . -'\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' . -'\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' . -'\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' . -'\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' . -'\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . -'\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' . -'\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' . -'\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' . -'\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' . -'\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' . -'\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' . -'\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' . -'\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' . -'\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' . -'\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' . -'\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' . -'\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' . -'\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' . -'\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' . -'\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' . -'\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' . -'\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' . -'\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' . -'\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' . -'\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' . -'\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' . -'\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' . -'\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' . -'\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' . -'\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' . -'\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' . -'\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' . -'\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' . -'\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' . -'\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' . -'\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' . -'\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' . -'\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' . -'\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' . -'\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' . -'\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' . -'\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' . -'\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' . -'\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' . -'\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' . -'\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' . -'\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' . -'\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' . -'\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' . -'\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' . -'\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' . -'\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' . -'\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' . -'\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' . -'\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' . -'\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' . -'\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' . -'\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' . -'\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' . -'\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' . -'\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' . -'\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' . -'\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' . -'\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' . -'\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' . -'\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' . -'\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' . -'\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' . -'\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' . -'\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' . -'\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' . -'\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' . -'\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' . -'\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' . -'\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' . -'\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' . -'\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' . -'\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' . -'\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' . -'\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' . -'\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' . -'\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' . -'\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' . -'\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' . -'\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' . -'\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' . -'\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' . -'\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' . -'\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' . -'\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' . -'\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' . -'\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' . -'\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' . -'\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' . -'\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' . -'\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' . -'\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' . -'\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' . -'\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' . -'\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' . -'\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' . -'\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' . -'\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' . -'\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' . -'\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' . -'\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' . -'\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' . -'\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' . -'\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' . -'\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' . -'\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' . -'\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' . -'\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' . -'\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' . -'\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' . -'\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' . -'\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' . -'\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' . -'\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' . -'\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' . -'\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' . -'\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' . -'\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' . -'\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' . -'\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' . -'\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' . -'\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' . -'\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' . -'\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' . -'\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' . -'\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' . -'\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' . -'\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' . -'\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' . -'\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' . -'\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' . -'\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' . -'\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' . -'\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' . -'\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' . -'\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' . -'\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' . -'\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' . -'\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' . -'\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' . -'\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' . -'\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' . -'\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' . -'\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' . -'\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' . -'\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' . -'\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' . -'\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' . -'\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' . -'\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' . -'\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' . -'\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' . -'\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' . -'\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' . -'\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' . -'\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' . -'\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' . -'\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' . -'\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' . -'\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' . -'\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' . -'\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . -'\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' . -'\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' . -'\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' . -'\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' . -'\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' . -'\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' . -'\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' . -'\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' . -'\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' . -'\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' . -'\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' . -'\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' . -'\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' . -'\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' . -'\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' . -'\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' . -'\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' . -'\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' . -'\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' . -'\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' . -'\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' . -'\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' . -'\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' . -'\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' . -'\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' . -'\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' . -'\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' . -'\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' . -'\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' . -'\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' . -'\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' . -'\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' . -'\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' . -'\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' . -'\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' . -'\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' . -'\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' . -'\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' . -'\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' . -'\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' . -'\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' . -'\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' . -'\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' . -'\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' . -'\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' . -'\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' . -'\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' . -'\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' . -'\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' . -'\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' . -'\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' . -'\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' . -'\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' . -'\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' . -'\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' . -'\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . -'\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' . -'\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' . -'\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' . -'\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' . -'\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' . -'\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' . -'\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' . -'\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' . -'\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' . -'\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' . -'\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' . -'\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' . -'\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' . -'\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' . -'\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' . -'\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' . -'\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' . -'\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' . -'\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' . -'\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' . -'\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' . -'\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' . -'\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' . -'\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' . -'\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' . -'\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' . -'\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' . -'\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' . -'\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' . -'\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' . -'\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' . -'\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' . -'\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' . -'\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' . -'\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' . -'\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' . -'\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' . -'\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' . -'\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' . -'\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' . -'\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' . -'\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' . -'\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' . -'\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' . -'\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' . -'\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' . -'\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' . -'\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' . -'\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' . -'\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' . -'\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' . -'\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' . -'\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' . -'\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' . -'\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' . -'\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' . -'\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' . -'\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' . -'\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' . -'\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' . -'\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' . -'\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' . -'\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' . -'\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' . -'\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' . -'\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' . -'\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' . -'\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' . -'\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' . -'\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' . -'\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' . -'\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' . -'\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' . -'\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' . -'\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' . -'\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' . -'\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' . -'\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' . -'\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' . -'\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' . -'\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' . -'\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' . -'\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' . -'\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' . -'\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' . -'\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' . -'\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' . -'\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' . -'\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' . -'\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' . -'\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' . -'\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' . -'\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' . -'\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' . -'\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' . -'\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' . -'\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' . -'\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' . -'\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' . -'\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' . -'\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' . -'\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' . -'\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' . -'\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' . -'\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' . -'\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' . -'\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' . -'\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' . -'\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' . -'\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' . -'\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' . -'\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' . -'\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' . -'\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' . -'\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' . -'\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' . -'\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' . -'\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' . -'\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' . -'\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' . -'\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' . -'\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' . -'\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' . -'\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' . -'\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' . -'\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' . -'\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' . -'\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' . -'\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' . -'\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' . -'\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' . -'\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' . -'\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' . -'\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' . -'\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' . -'\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' . -'\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' . -'\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' . -'\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' . -'\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' . -'\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' . -'\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' . -'\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' . -'\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' . -'\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' . -'\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' . -'\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' . -'\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' . -'\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' . -'\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' . -'\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' . -'\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' . -'\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' . -'\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' . -'\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' . -'\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' . -'\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' . -'\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . -'\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' . -'\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' . -'\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' . -'\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' . -'\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' . -'\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' . -'\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' . -'\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' . -'\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' . -'\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' . -'\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' . -'\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' . -'\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' . -'\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' . -'\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' . -'\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' . -'\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' . -'\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' . -'\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' . -'\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' . -'\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' . -'\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' . -'\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' . -'\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' . -'\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' . -'\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' . -'\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' . -'\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' . -'\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' . -'\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' . -'\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' . -'\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' . -'\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' . -'\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' . -'\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' . -'\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' . -'\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' . -'\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' . -'\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' . -'\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' . -'\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' . -'\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' . -'\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' . -'\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' . -'\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' . -'\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' . -'\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' . -'\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' . -'\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' . -'\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' . -'\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' . -'\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' . -'\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' . -'\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' . -'\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' . -'\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' . -'\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' . -'\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' . -'\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' . -'\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' . -'\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' . -'\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' . -'\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' . -'\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' . -'\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' . -'\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' . -'\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' . -'\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' . -'\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' . -'\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' . -'\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' . -'\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' . -'\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' . -'\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' . -'\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' . -'\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' . -'\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' . -'\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' . -'\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' . -'\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' . -'\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' . -'\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' . -'\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' . -'\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' . -'\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' . -'\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' . -'\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' . -'\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' . -'\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' . -'\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' . -'\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' . -'\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' . -'\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' . -'\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' . -'\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' . -'\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' . -'\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' . -'\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' . -'\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' . -'\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' . -'\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' . -'\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' . -'\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' . -'\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' . -'\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' . -'\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' . -'\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' . -'\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' . -'\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' . -'\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' . -'\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' . -'\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' . -'\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' . -'\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' . -'\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' . -'\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' . -'\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' . -'\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' . -'\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' . -'\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' . -'\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' . -'\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' . -'\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' . -'\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' . -'\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' . -'\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' . -'\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' . -'\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' . -'\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' . -'\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' . -'\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' . -'\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' . -'\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' . -'\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' . -'\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' . -'\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' . -'\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' . -'\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' . -'\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' . -'\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' . -'\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' . -'\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' . -'\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' . -'\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' . -'\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' . -'\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' . -'\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' . -'\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' . -'\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' . -'\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' . -'\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' . -'\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' . -'\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' . -'\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' . -'\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' . -'\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' . -'\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' . -'\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' . -'\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' . -'\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' . -'\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' . -'\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' . -'\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' . -'\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' . -'\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' . -'\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' . -'\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' . -'\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' . -'\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' . -'\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' . -'\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' . -'\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' . -'\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' . -'\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' . -'\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' . -'\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' . -'\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' . -'\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' . -'\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' . -'\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' . -'\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' . -'\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' . -'\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' . -'\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' . -'\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' . -'\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' . -'\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' . -'\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' . -'\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' . -'\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' . -'\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' . -'\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' . -'\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' . -'\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' . -'\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' . -'\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' . -'\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' . -'\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' . -'\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' . -'\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' . -'\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' . -'\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' . -'\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' . -'\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' . -'\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' . -'\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' . -'\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' . -'\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' . -'\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' . -'\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' . -'\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' . -'\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' . -'\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' . -'\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' . -'\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' . -'\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' . -'\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' . -'\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' . -'\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' . -'\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' . -'\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' . -'\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' . -'\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' . -'\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' . -'\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' . -'\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' . -'\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' . -'\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' . -'\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' . -'\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' . -'\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' . -'\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' . -'\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' . -'\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' . -'\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' . -'\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' . -'\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' . -'\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' . -'\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' . -'\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' . -'\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' . -'\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' . -'\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' . -'\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' . -'\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' . -'\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' . -'\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' . -'\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' . -'\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' . -'\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' . -'\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' . -'\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' . -'\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' . -'\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' . -'\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' . -'\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' . -'\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' . -'\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' . -'\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' . -'\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' . -'\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' . -'\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' . -'\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' . -'\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' . -'\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' . -'\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' . -'\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' . -'\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' . -'\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' . -'\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' . -'\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' . -'\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' . -'\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' . -'\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' . -'\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' . -'\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' . -'\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' . -'\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' . -'\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . -'\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' . -'\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' . -'\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' . -'\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' . -'\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' . -'\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' . -'\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' . -'\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' . -'\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' . -'\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' . -'\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' . -'\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' . -'\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' . -'\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' . -'\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' . -'\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' . -'\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', - 12 => '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' . -'\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' . -'\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' . -'\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' . -'\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' . -'\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' . -'\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . -'\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' . -'\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' . -'\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' . -'\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' . -'\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' . -'\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' . -'\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' . -'\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' . -'\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' . -'\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' . -'\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' . -'\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' . -'\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' . -'\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' . -'\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' . -'\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' . -'\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' . -'\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' . -'\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' . -'\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' . -'\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' . -'\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' . -'\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' . -'\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' . -'\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' . -'\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' . -'\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' . -'\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' . -'\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' . -'\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' . -'\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' . -'\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' . -'\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' . -'\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' . -'\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' . -'\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' . -'\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' . -'\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' . -'\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' . -'\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' . -'\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' . -'\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' . -'\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' . -'\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' . -'\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' . -'\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' . -'\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' . -'\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' . -'\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' . -'\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' . -'\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' . -'\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' . -'\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' . -'\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' . -'\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' . -'\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' . -'\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' . -'\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' . -'\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' . -'\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' . -'\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' . -'\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' . -'\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' . -'\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' . -'\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' . -'\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' . -'\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' . -'\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' . -'\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' . -'\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' . -'\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' . -'\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' . -'\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' . -'\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' . -'\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' . -'\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' . -'\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' . -'\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' . -'\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' . -'\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' . -'\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' . -'\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' . -'\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' . -'\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' . -'\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . -'\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' . -'\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' . -'\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' . -'\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' . -'\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' . -'\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' . -'\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' . -'\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' . -'\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' . -'\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' . -'\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' . -'\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' . -'\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' . -'\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' . -'\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' . -'\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' . -'\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' . -'\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' . -'\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' . -'\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' . -'\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' . -'\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' . -'\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' . -'\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' . -'\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' . -'\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' . -'\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' . -'\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' . -'\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' . -'\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' . -'\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' . -'\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' . -'\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' . -'\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' . -'\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' . -'\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' . -'\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' . -'\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' . -'\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' . -'\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' . -'\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' . -'\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' . -'\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' . -'\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' . -'\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' . -'\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' . -'\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' . -'\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' . -'\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' . -'\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' . -'\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' . -'\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' . -'\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' . -'\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' . -'\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' . -'\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' . -'\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' . -'\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' . -'\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' . -'\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' . -'\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' . -'\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' . -'\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' . -'\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' . -'\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' . -'\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' . -'\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' . -'\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' . -'\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' . -'\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' . -'\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' . -'\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' . -'\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' . -'\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' . -'\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' . -'\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' . -'\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' . -'\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' . -'\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' . -'\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' . -'\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' . -'\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' . -'\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' . -'\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' . -'\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' . -'\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' . -'\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' . -'\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' . -'\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' . -'\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' . -'\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' . -'\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' . -'\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' . -'\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' . -'\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' . -'\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' . -'\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' . -'\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' . -'\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' . -'\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' . -'\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' . -'\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' . -'\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' . -'\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' . -'\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' . -'\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' . -'\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' . -'\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' . -'\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' . -'\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' . -'\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' . -'\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' . -'\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' . -'\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' . -'\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' . -'\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' . -'\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' . -'\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' . -'\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' . -'\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' . -'\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' . -'\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' . -'\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' . -'\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' . -'\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' . -'\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' . -'\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' . -'\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' . -'\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' . -'\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' . -'\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' . -'\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' . -'\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' . -'\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' . -'\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' . -'\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' . -'\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' . -'\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' . -'\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' . -'\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' . -'\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' . -'\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' . -'\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' . -'\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' . -'\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' . -'\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' . -'\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' . -'\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' . -'\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' . -'\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' . -'\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' . -'\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' . -'\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' . -'\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' . -'\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' . -'\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' . -'\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' . -'\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' . -'\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' . -'\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' . -'\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' . -'\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' . -'\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' . -'\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' . -'\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' . -'\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' . -'\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' . -'\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' . -'\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' . -'\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' . -'\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' . -'\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' . -'\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' . -'\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' . -'\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' . -'\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' . -'\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' . -'\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' . -'\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' . -'\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' . -'\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' . -'\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' . -'\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' . -'\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' . -'\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' . -'\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' . -'\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' . -'\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' . -'\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' . -'\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' . -'\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' . -'\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' . -'\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' . -'\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' . -'\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' . -'\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' . -'\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' . -'\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' . -'\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' . -'\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' . -'\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' . -'\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' . -'\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' . -'\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' . -'\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' . -'\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' . -'\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' . -'\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' . -'\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' . -'\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' . -'\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' . -'\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' . -'\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' . -'\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' . -'\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' . -'\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' . -'\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' . -'\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' . -'\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' . -'\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' . -'\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' . -'\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' . -'\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' . -'\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' . -'\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' . -'\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' . -'\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' . -'\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' . -'\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' . -'\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' . -'\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' . -'\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' . -'\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' . -'\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' . -'\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' . -'\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' . -'\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' . -'\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' . -'\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' . -'\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' . -'\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' . -'\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' . -'\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' . -'\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' . -'\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' . -'\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' . -'\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' . -'\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' . -'\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' . -'\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' . -'\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' . -'\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' . -'\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' . -'\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' . -'\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' . -'\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' . -'\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' . -'\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' . -'\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' . -'\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' . -'\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' . -'\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' . -'\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' . -'\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' . -'\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' . -'\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' . -'\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' . -'\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' . -'\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' . -'\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' . -'\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' . -'\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' . -'\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' . -'\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' . -'\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' . -'\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' . -'\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' . -'\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' . -'\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' . -'\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' . -'\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' . -'\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' . -'\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' . -'\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' . -'\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' . -'\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' . -'\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' . -'\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' . -'\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' . -'\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' . -'\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' . -'\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' . -'\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' . -'\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' . -'\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' . -'\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' . -'\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' . -'\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' . -'\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' . -'\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' . -'\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' . -'\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' . -'\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' . -'\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' . -'\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' . -'\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' . -'\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' . -'\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' . -'\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' . -'\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' . -'\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' . -'\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' . -'\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' . -'\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' . -'\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' . -'\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' . -'\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' . -'\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' . -'\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' . -'\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' . -'\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' . -'\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' . -'\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' . -'\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' . -'\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' . -'\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' . -'\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' . -'\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' . -'\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' . -'\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' . -'\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' . -'\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' . -'\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' . -'\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' . -'\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' . -'\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' . -'\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' . -'\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' . -'\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' . -'\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' . -'\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' . -'\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' . -'\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' . -'\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' . -'\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' . -'\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' . -'\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' . -'\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' . -'\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' . -'\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' . -'\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' . -'\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' . -'\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' . -'\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' . -'\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' . -'\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' . -'\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' . -'\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' . -'\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' . -'\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' . -'\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' . -'\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' . -'\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' . -'\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' . -'\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' . -'\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' . -'\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' . -'\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' . -'\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' . -'\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' . -'\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' . -'\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' . -'\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' . -'\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' . -'\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' . -'\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' . -'\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' . -'\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' . -'\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' . -'\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' . -'\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' . -'\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' . -'\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' . -'\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' . -'\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' . -'\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' . -'\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' . -'\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' . -'\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' . -'\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' . -'\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' . -'\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' . -'\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' . -'\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' . -'\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' . -'\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' . -'\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' . -'\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' . -'\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' . -'\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' . -'\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' . -'\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' . -'\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' . -'\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' . -'\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' . -'\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' . -'\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' . -'\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' . -'\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' . -'\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' . -'\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' . -'\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' . -'\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' . -'\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' . -'\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' . -'\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' . -'\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' . -'\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' . -'\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' . -'\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' . -'\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' . -'\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' . -'\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' . -'\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' . -'\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' . -'\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' . -'\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' . -'\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' . -'\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' . -'\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' . -'\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' . -'\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' . -'\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' . -'\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' . -'\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . -'\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' . -'\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' . -'\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' . -'\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' . -'\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' . -'\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' . -'\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' . -'\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' . -'\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' . -'\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' . -'\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' . -'\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' . -'\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' . -'\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' . -'\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' . -'\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' . -'\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' . -'\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' . -'\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' . -'\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' . -'\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' . -'\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' . -'\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' . -'\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' . -'\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' . -'\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' . -'\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' . -'\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' . -'\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' . -'\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' . -'\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' . -'\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' . -'\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' . -'\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' . -'\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' . -'\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' . -'\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' . -'\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' . -'\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' . -'\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' . -'\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' . -'\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' . -'\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' . -'\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' . -'\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' . -'\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' . -'\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' . -'\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' . -'\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' . -'\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' . -'\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' . -'\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' . -'\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' . -'\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' . -'\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' . -'\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' . -'\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' . -'\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' . -'\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' . -'\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' . -'\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' . -'\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' . -'\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' . -'\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' . -'\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' . -'\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' . -'\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' . -'\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' . -'\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' . -'\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' . -'\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' . -'\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' . -'\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' . -'\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' . -'\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' . -'\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' . -'\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' . -'\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' . -'\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' . -'\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' . -'\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' . -'\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' . -'\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' . -'\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' . -'\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' . -'\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' . -'\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' . -'\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' . -'\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' . -'\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' . -'\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' . -'\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' . -'\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' . -'\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' . -'\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' . -'\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' . -'\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' . -'\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' . -'\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' . -'\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' . -'\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' . -'\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' . -'\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' . -'\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' . -'\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' . -'\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' . -'\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' . -'\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' . -'\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' . -'\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' . -'\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' . -'\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' . -'\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' . -'\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' . -'\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' . -'\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' . -'\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' . -'\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' . -'\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' . -'\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' . -'\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' . -'\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' . -'\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' . -'\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' . -'\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' . -'\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' . -'\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' . -'\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' . -'\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' . -'\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' . -'\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' . -'\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' . -'\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' . -'\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' . -'\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' . -'\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' . -'\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' . -'\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' . -'\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' . -'\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' . -'\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' . -'\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' . -'\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' . -'\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' . -'\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' . -'\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' . -'\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' . -'\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . -'\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' . -'\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' . -'\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' . -'\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' . -'\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' . -'\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' . -'\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' . -'\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' . -'\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' . -'\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' . -'\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' . -'\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' . -'\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' . -'\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' . -'\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' . -'\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' . -'\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' . -'\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' . -'\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' . -'\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' . -'\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' . -'\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' . -'\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' . -'\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' . -'\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' . -'\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' . -'\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' . -'\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' . -'\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' . -'\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' . -'\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' . -'\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' . -'\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' . -'\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' . -'\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' . -'\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' . -'\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' . -'\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' . -'\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' . -'\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' . -'\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' . -'\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' . -'\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' . -'\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' . -'\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' . -'\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' . -'\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' . -'\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' . -'\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' . -'\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' . -'\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' . -'\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' . -'\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' . -'\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' . -'\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' . -'\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' . -'\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' . -'\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' . -'\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' . -'\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' . -'\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' . -'\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' . -'\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' . -'\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' . -'\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' . -'\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' . -'\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' . -'\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' . -'\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' . -'\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' . -'\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' . -'\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' . -'\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' . -'\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' . -'\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' . -'\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' . -'\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' . -'\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' . -'\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' . -'\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' . -'\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' . -'\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' . -'\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' . -'\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' . -'\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' . -'\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' . -'\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' . -'\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' . -'\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' . -'\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' . -'\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' . -'\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' . -'\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' . -'\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' . -'\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' . -'\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' . -'\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' . -'\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' . -'\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' . -'\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' . -'\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' . -'\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' . -'\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' . -'\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' . -'\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' . -'\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' . -'\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' . -'\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' . -'\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' . -'\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' . -'\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' . -'\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' . -'\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' . -'\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' . -'\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' . -'\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' . -'\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' . -'\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' . -'\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' . -'\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' . -'\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' . -'\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' . -'\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' . -'\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' . -'\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' . -'\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' . -'\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' . -'\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' . -'\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' . -'\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' . -'\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' . -'\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' . -'\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' . -'\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' . -'\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' . -'\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' . -'\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' . -'\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' . -'\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' . -'\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' . -'\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' . -'\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' . -'\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' . -'\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' . -'\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' . -'\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' . -'\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' . -'\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' . -'\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' . -'\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' . -'\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' . -'\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' . -'\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' . -'\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' . -'\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' . -'\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' . -'\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' . -'\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' . -'\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' . -'\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' . -'\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' . -'\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' . -'\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' . -'\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' . -'\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' . -'\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' . -'\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' . -'\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' . -'\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' . -'\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' . -'\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' . -'\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' . -'\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' . -'\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' . -'\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' . -'\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' . -'\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' . -'\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' . -'\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' . -'\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' . -'\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' . -'\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' . -'\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' . -'\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' . -'\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' . -'\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' . -'\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' . -'\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' . -'\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' . -'\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' . -'\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' . -'\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' . -'\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' . -'\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' . -'\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' . -'\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' . -'\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' . -'\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' . -'\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' . -'\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' . -'\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' . -'\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' . -'\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' . -'\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' . -'\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' . -'\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' . -'\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' . -'\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' . -'\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' . -'\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' . -'\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' . -'\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' . -'\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' . -'\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' . -'\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' . -'\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' . -'\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' . -'\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' . -'\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' . -'\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' . -'\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' . -'\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' . -'\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' . -'\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' . -'\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' . -'\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' . -'\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' . -'\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' . -'\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' . -'\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' . -'\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' . -'\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' . -'\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' . -'\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' . -'\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' . -'\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' . -'\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' . -'\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' . -'\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' . -'\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' . -'\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' . -'\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' . -'\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' . -'\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' . -'\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' . -'\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' . -'\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' . -'\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' . -'\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' . -'\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' . -'\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' . -'\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' . -'\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' . -'\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' . -'\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' . -'\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' . -'\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' . -'\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' . -'\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' . -'\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' . -'\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' . -'\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' . -'\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' . -'\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' . -'\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' . -'\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' . -'\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' . -'\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' . -'\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' . -'\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' . -'\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' . -'\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' . -'\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' . -'\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' . -'\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' . -'\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' . -'\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' . -'\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' . -'\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' . -'\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' . -'\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' . -'\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' . -'\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' . -'\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' . -'\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' . -'\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' . -'\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' . -'\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' . -'\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' . -'\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' . -'\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' . -'\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' . -'\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' . -'\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' . -'\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' . -'\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' . -'\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' . -'\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' . -'\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' . -'\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' . -'\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' . -'\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' . -'\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' . -'\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' . -'\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' . -'\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' . -'\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' . -'\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' . -'\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' . -'\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' . -'\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' . -'\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' . -'\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' . -'\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' . -'\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' . -'\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' . -'\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' . -'\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' . -'\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' . -'\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' . -'\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' . -'\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' . -'\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' . -'\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' . -'\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' . -'\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' . -'\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' . -'\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' . -'\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' . -'\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' . -'\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' . -'\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' . -'\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' . -'\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' . -'\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' . -'\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' . -'\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' . -'\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' . -'\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' . -'\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' . -'\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' . -'\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' . -'\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' . -'\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' . -'\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' . -'\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' . -'\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' . -'\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' . -'\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' . -'\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' . -'\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' . -'\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' . -'\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' . -'\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' . -'\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' . -'\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' . -'\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' . -'\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' . -'\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' . -'\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' . -'\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' . -'\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' . -'\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' . -'\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' . -'\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' . -'\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' . -'\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' . -'\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' . -'\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' . -'\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' . -'\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' . -'\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' . -'\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' . -'\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' . -'\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' . -'\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' . -'\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' . -'\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' . -'\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' . -'\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' . -'\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' . -'\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' . -'\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' . -'\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' . -'\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' . -'\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' . -'\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' . -'\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' . -'\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' . -'\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' . -'\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' . -'\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' . -'\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' . -'\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' . -'\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' . -'\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' . -'\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' . -'\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' . -'\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' . -'\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' . -'\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' . -'\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' . -'\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' . -'\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' . -'\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' . -'\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' . -'\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' . -'\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' . -'\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' . -'\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' . -'\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' . -'\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' . -'\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' . -'\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' . -'\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' . -'\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' . -'\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' . -'\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' . -'\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' . -'\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' . -'\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' . -'\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' . -'\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' . -'\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' . -'\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' . -'\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' . -'\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' . -'\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' . -'\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' . -'\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' . -'\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' . -'\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' . -'\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' . -'\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' . -'\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' . -'\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' . -'\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' . -'\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' . -'\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' . -'\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' . -'\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' . -'\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' . -'\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' . -'\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' . -'\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' . -'\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' . -'\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' . -'\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' . -'\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' . -'\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' . -'\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' . -'\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' . -'\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' . -'\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' . -'\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' . -'\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' . -'\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' . -'\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' . -'\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' . -'\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' . -'\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' . -'\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' . -'\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' . -'\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' . -'\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' . -'\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' . -'\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' . -'\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' . -'\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' . -'\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' . -'\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' . -'\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' . -'\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' . -'\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' . -'\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' . -'\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' . -'\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' . -'\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' . -'\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' . -'\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' . -'\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' . -'\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' . -'\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' . -'\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' . -'\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' . -'\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' . -'\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' . -'\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' . -'\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' . -'\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' . -'\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' . -'\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' . -'\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' . -'\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' . -'\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' . -'\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' . -'\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' . -'\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' . -'\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . -'\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' . -'\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' . -'\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' . -'\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' . -'\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' . -'\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' . -'\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' . -'\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' . -'\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' . -'\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' . -'\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' . -'\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' . -'\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' . -'\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' . -'\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' . -'\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' . -'\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' . -'\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' . -'\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' . -'\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' . -'\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' . -'\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' . -'\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' . -'\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' . -'\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' . -'\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' . -'\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' . -'\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' . -'\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' . -'\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' . -'\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' . -'\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' . -'\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' . -'\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' . -'\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' . -'\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' . -'\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' . -'\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' . -'\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' . -'\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' . -'\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' . -'\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' . -'\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' . -'\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' . -'\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' . -'\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' . -'\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' . -'\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' . -'\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' . -'\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' . -'\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' . -'\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' . -'\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' . -'\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' . -'\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' . -'\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' . -'\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' . -'\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' . -'\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' . -'\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' . -'\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' . -'\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' . -'\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' . -'\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' . -'\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' . -'\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' . -'\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' . -'\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' . -'\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' . -'\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' . -'\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' . -'\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' . -'\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' . -'\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' . -'\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' . -'\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' . -'\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' . -'\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' . -'\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' . -'\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' . -'\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' . -'\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' . -'\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' . -'\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' . -'\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' . -'\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' . -'\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' . -'\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' . -'\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' . -'\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' . -'\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' . -'\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' . -'\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' . -'\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' . -'\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' . -'\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' . -'\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' . -'\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' . -'\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' . -'\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' . -'\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' . -'\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' . -'\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' . -'\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' . -'\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' . -'\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' . -'\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' . -'\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' . -'\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' . -'\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' . -'\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' . -'\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' . -'\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' . -'\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' . -'\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' . -'\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' . -'\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' . -'\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' . -'\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' . -'\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' . -'\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' . -'\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' . -'\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' . -'\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' . -'\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' . -'\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' . -'\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' . -'\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' . -'\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' . -'\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' . -'\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' . -'\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' . -'\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' . -'\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' . -'\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' . -'\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' . -'\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' . -'\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' . -'\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' . -'\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' . -'\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' . -'\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' . -'\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' . -'\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' . -'\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' . -'\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' . -'\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' . -'\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' . -'\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' . -'\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' . -'\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' . -'\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' . -'\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' . -'\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' . -'\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' . -'\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' . -'\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' . -'\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' . -'\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' . -'\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' . -'\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' . -'\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' . -'\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' . -'\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' . -'\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' . -'\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' . -'\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' . -'\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' . -'\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' . -'\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' . -'\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' . -'\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' . -'\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' . -'\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' . -'\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' . -'\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' . -'\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' . -'\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' . -'\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' . -'\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' . -'\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' . -'\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' . -'\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' . -'\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' . -'\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' . -'\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' . -'\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' . -'\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' . -'\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' . -'\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' . -'\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' . -'\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' . -'\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' . -'\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' . -'\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' . -'\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' . -'\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' . -'\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' . -'\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' . -'\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' . -'\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' . -'\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' . -'\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' . -'\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' . -'\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' . -'\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' . -'\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' . -'\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' . -'\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' . -'\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' . -'\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' . -'\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' . -'\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' . -'\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' . -'\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' . -'\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' . -'\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' . -'\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' . -'\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' . -'\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' . -'\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' . -'\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' . -'\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' . -'\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' . -'\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' . -'\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' . -'\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' . -'\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' . -'\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' . -'\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' . -'\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' . -'\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' . -'\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' . -'\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' . -'\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' . -'\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' . -'\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' . -'\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' . -'\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' . -'\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' . -'\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' . -'\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' . -'\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' . -'\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' . -'\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' . -'\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' . -'\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' . -'\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' . -'\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' . -'\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' . -'\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' . -'\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' . -'\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' . -'\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' . -'\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' . -'\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' . -'\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' . -'\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' . -'\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' . -'\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' . -'\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' . -'\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' . -'\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' . -'\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' . -'\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' . -'\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' . -'\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' . -'\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' . -'\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' . -'\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' . -'\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' . -'\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' . -'\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' . -'\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' . -'\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' . -'\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' . -'\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' . -'\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' . -'\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' . -'\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' . -'\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' . -'\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' . -'\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' . -'\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' . -'\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' . -'\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' . -'\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' . -'\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' . -'\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' . -'\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' . -'\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' . -'\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' . -'\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' . -'\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' . -'\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' . -'\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' . -'\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' . -'\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' . -'\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' . -'\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' . -'\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' . -'\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' . -'\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' . -'\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' . -'\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' . -'\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' . -'\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' . -'\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' . -'\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' . -'\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' . -'\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' . -'\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' . -'\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' . -'\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' . -'\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' . -'\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' . -'\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' . -'\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' . -'\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' . -'\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' . -'\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' . -'\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' . -'\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' . -'\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' . -'\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' . -'\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' . -'\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' . -'\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' . -'\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' . -'\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' . -'\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' . -'\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' . -'\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' . -'\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' . -'\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' . -'\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' . -'\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' . -'\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' . -'\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' . -'\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' . -'\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' . -'\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' . -'\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' . -'\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' . -'\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' . -'\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' . -'\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' . -'\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' . -'\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' . -'\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' . -'\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' . -'\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' . -'\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' . -'\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' . -'\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' . -'\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' . -'\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' . -'\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' . -'\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' . -'\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' . -'\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' . -'\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' . -'\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' . -'\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' . -'\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' . -'\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' . -'\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' . -'\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' . -'\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' . -'\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' . -'\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' . -'\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' . -'\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' . -'\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' . -'\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' . -'\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' . -'\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' . -'\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' . -'\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' . -'\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' . -'\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' . -'\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' . -'\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' . -'\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' . -'\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' . -'\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' . -'\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' . -'\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' . -'\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' . -'\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' . -'\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' . -'\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' . -'\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' . -'\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' . -'\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' . -'\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' . -'\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' . -'\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' . -'\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' . -'\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' . -'\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' . -'\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' . -'\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' . -'\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' . -'\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' . -'\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' . -'\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' . -'\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' . -'\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' . -'\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' . -'\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' . -'\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' . -'\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' . -'\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' . -'\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' . -'\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' . -'\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' . -'\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' . -'\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' . -'\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' . -'\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' . -'\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' . -'\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' . -'\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' . -'\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' . -'\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' . -'\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' . -'\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' . -'\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' . -'\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' . -'\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' . -'\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' . -'\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' . -'\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' . -'\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' . -'\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' . -'\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' . -'\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' . -'\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' . -'\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' . -'\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' . -'\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' . -'\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' . -'\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' . -'\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' . -'\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' . -'\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' . -'\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' . -'\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' . -'\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' . -'\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' . -'\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' . -'\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' . -'\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' . -'\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' . -'\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' . -'\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' . -'\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' . -'\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' . -'\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' . -'\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' . -'\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' . -'\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' . -'\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' . -'\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' . -'\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' . -'\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' . -'\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' . -'\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' . -'\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' . -'\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' . -'\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' . -'\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' . -'\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' . -'\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' . -'\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' . -'\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' . -'\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' . -'\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' . -'\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' . -'\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' . -'\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' . -'\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' . -'\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' . -'\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' . -'\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' . -'\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' . -'\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' . -'\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' . -'\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' . -'\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' . -'\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' . -'\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' . -'\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' . -'\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' . -'\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' . -'\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' . -'\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' . -'\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' . -'\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' . -'\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' . -'\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' . -'\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' . -'\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' . -'\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' . -'\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' . -'\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' . -'\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' . -'\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' . -'\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' . -'\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' . -'\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' . -'\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' . -'\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' . -'\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' . -'\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' . -'\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' . -'\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' . -'\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' . -'\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' . -'\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' . -'\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' . -'\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' . -'\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' . -'\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' . -'\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' . -'\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' . -'\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' . -'\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' . -'\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' . -'\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' . -'\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' . -'\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' . -'\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' . -'\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' . -'\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' . -'\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' . -'\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' . -'\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' . -'\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' . -'\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' . -'\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' . -'\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' . -'\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' . -'\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' . -'\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' . -'\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' . -'\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' . -'\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' . -'\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' . -'\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' . -'\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' . -'\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' . -'\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' . -'\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' . -'\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' . -'\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' . -'\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' . -'\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' . -'\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' . -'\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' . -'\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' . -'\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' . -'\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' . -'\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' . -'\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' . -'\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' . -'\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' . -'\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' . -'\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' . -'\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' . -'\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' . -'\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' . -'\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' . -'\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' . -'\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' . -'\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' . -'\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' . -'\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' . -'\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' . -'\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' . -'\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' . -'\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' . -'\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' . -'\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' . -'\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' . -'\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' . -'\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' . -'\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' . -'\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' . -'\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' . -'\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' . -'\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' . -'\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' . -'\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' . -'\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' . -'\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' . -'\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' . -'\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' . -'\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' . -'\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' . -'\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' . -'\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' . -'\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' . -'\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' . -'\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' . -'\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' . -'\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' . -'\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' . -'\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' . -'\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' . -'\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' . -'\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' . -'\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' . -'\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' . -'\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' . -'\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' . -'\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' . -'\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' . -'\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' . -'\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' . -'\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' . -'\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' . -'\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' . -'\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' . -'\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' . -'\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' . -'\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' . -'\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' . -'\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' . -'\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' . -'\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' . -'\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' . -'\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' . -'\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' . -'\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' . -'\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' . -'\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' . -'\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' . -'\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' . -'\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' . -'\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' . -'\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' . -'\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' . -'\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' . -'\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' . -'\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' . -'\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' . -'\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' . -'\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' . -'\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' . -'\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' . -'\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' . -'\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' . -'\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' . -'\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' . -'\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' . -'\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' . -'\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' . -'\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' . -'\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' . -'\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' . -'\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' . -'\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' . -'\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' . -'\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' . -'\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' . -'\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' . -'\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' . -'\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' . -'\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' . -'\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' . -'\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' . -'\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' . -'\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' . -'\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' . -'\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' . -'\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' . -'\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' . -'\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' . -'\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' . -'\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' . -'\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' . -'\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' . -'\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' . -'\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' . -'\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' . -'\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' . -'\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' . -'\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' . -'\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' . -'\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' . -'\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' . -'\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' . -'\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' . -'\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' . -'\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' . -'\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' . -'\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' . -'\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' . -'\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' . -'\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' . -'\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' . -'\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' . -'\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' . -'\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' . -'\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' . -'\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' . -'\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' . -'\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' . -'\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' . -'\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' . -'\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' . -'\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' . -'\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' . -'\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' . -'\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' . -'\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' . -'\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' . -'\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' . -'\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' . -'\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' . -'\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' . -'\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' . -'\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' . -'\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' . -'\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' . -'\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' . -'\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' . -'\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' . -'\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' . -'\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' . -'\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' . -'\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' . -'\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' . -'\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' . -'\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' . -'\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' . -'\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' . -'\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' . -'\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' . -'\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' . -'\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' . -'\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' . -'\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' . -'\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' . -'\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' . -'\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' . -'\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' . -'\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' . -'\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' . -'\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' . -'\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' . -'\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' . -'\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' . -'\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' . -'\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' . -'\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' . -'\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' . -'\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' . -'\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' . -'\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' . -'\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' . -'\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' . -'\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' . -'\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' . -'\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' . -'\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' . -'\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' . -'\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' . -'\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' . -'\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' . -'\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' . -'\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' . -'\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' . -'\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' . -'\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' . -'\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' . -'\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' . -'\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' . -'\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' . -'\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' . -'\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' . -'\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' . -'\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' . -'\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' . -'\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' . -'\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' . -'\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' . -'\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' . -'\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' . -'\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' . -'\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' . -'\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' . -'\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' . -'\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' . -'\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' . -'\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' . -'\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' . -'\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' . -'\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' . -'\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' . -'\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' . -'\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' . -'\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' . -'\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' . -'\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' . -'\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' . -'\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' . -'\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' . -'\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' . -'\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' . -'\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' . -'\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' . -'\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' . -'\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' . -'\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' . -'\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' . -'\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' . -'\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' . -'\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' . -'\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' . -'\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' . -'\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' . -'\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' . -'\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' . -'\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' . -'\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' . -'\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' . -'\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' . -'\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' . -'\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' . -'\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' . -'\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' . -'\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' . -'\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' . -'\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' . -'\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' . -'\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' . -'\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' . -'\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' . -'\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' . -'\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' . -'\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' . -'\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' . -'\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' . -'\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' . -'\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' . -'\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' . -'\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' . -'\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' . -'\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' . -'\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' . -'\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' . -'\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' . -'\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' . -'\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' . -'\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' . -'\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' . -'\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' . -'\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' . -'\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' . -'\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' . -'\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' . -'\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' . -'\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' . -'\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' . -'\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' . -'\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' . -'\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' . -'\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' . -'\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' . -'\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' . -'\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' . -'\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' . -'\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' . -'\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' . -'\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' . -'\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' . -'\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' . -'\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' . -'\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' . -'\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' . -'\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' . -'\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' . -'\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' . -'\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' . -'\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' . -'\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' . -'\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' . -'\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' . -'\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' . -'\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' . -'\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' . -'\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' . -'\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' . -'\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' . -'\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' . -'\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' . -'\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' . -'\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' . -'\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' . -'\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' . -'\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' . -'\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' . -'\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' . -'\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' . -'\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' . -'\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' . -'\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' . -'\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' . -'\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' . -'\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' . -'\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' . -'\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' . -'\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' . -'\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' . -'\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' . -'\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' . -'\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' . -'\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' . -'\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' . -'\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' . -'\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' . -'\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' . -'\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . -'\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' . -'\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' . -'\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' . -'\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' . -'\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' . -'\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' . -'\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' . -'\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' . -'\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' . -'\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' . -'\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' . -'\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' . -'\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' . -'\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' . -'\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' . -'\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' . -'\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' . -'\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' . -'\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' . -'\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' . -'\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' . -'\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' . -'\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' . -'\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' . -'\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' . -'\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' . -'\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' . -'\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' . -'\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' . -'\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' . -'\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' . -'\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' . -'\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' . -'\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' . -'\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' . -'\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' . -'\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' . -'\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' . -'\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' . -'\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' . -'\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' . -'\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' . -'\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' . -'\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' . -'\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' . -'\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' . -'\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' . -'\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' . -'\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' . -'\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' . -'\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' . -'\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' . -'\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' . -'\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' . -'\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' . -'\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' . -'\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' . -'\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' . -'\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' . -'\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' . -'\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' . -'\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' . -'\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' . -'\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' . -'\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' . -'\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' . -'\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' . -'\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' . -'\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu'); diff --git a/lib/Zend/Validate/Hostname/Cn.php b/lib/Zend/Validate/Hostname/Cn.php deleted file mode 100644 index 816e499a9b0..00000000000 --- a/lib/Zend/Validate/Hostname/Cn.php +++ /dev/null @@ -1,2199 +0,0 @@ - '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' . -'\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' . -'\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' . -'\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' . -'\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' . -'\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' . -'\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . -'\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' . -'\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' . -'\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' . -'\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' . -'\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' . -'\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' . -'\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' . -'\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' . -'\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' . -'\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' . -'\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' . -'\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' . -'\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' . -'\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' . -'\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' . -'\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' . -'\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' . -'\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' . -'\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' . -'\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' . -'\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' . -'\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' . -'\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' . -'\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' . -'\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' . -'\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' . -'\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' . -'\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' . -'\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' . -'\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' . -'\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' . -'\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' . -'\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' . -'\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' . -'\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' . -'\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' . -'\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' . -'\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' . -'\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' . -'\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' . -'\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' . -'\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' . -'\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' . -'\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' . -'\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' . -'\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' . -'\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' . -'\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' . -'\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' . -'\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' . -'\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' . -'\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' . -'\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' . -'\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' . -'\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' . -'\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' . -'\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' . -'\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' . -'\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' . -'\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' . -'\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' . -'\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' . -'\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' . -'\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' . -'\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' . -'\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' . -'\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' . -'\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' . -'\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' . -'\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' . -'\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' . -'\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' . -'\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' . -'\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' . -'\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' . -'\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' . -'\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' . -'\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' . -'\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' . -'\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' . -'\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' . -'\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' . -'\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' . -'\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' . -'\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . -'\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' . -'\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' . -'\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' . -'\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' . -'\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' . -'\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' . -'\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' . -'\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' . -'\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' . -'\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' . -'\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' . -'\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' . -'\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' . -'\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' . -'\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' . -'\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' . -'\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' . -'\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' . -'\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' . -'\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' . -'\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' . -'\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' . -'\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' . -'\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' . -'\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' . -'\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' . -'\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' . -'\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' . -'\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' . -'\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' . -'\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' . -'\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' . -'\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' . -'\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' . -'\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' . -'\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' . -'\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' . -'\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' . -'\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' . -'\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' . -'\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' . -'\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' . -'\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' . -'\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' . -'\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' . -'\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' . -'\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' . -'\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' . -'\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' . -'\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' . -'\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' . -'\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' . -'\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' . -'\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' . -'\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' . -'\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' . -'\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' . -'\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' . -'\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' . -'\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' . -'\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' . -'\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' . -'\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' . -'\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' . -'\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' . -'\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' . -'\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' . -'\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' . -'\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' . -'\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' . -'\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' . -'\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' . -'\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' . -'\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' . -'\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' . -'\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' . -'\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' . -'\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' . -'\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' . -'\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' . -'\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' . -'\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' . -'\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' . -'\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' . -'\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' . -'\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' . -'\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' . -'\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' . -'\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' . -'\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' . -'\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' . -'\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' . -'\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' . -'\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' . -'\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' . -'\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' . -'\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' . -'\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' . -'\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' . -'\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' . -'\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' . -'\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' . -'\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' . -'\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' . -'\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' . -'\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' . -'\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' . -'\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' . -'\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' . -'\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' . -'\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' . -'\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' . -'\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' . -'\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' . -'\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' . -'\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' . -'\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' . -'\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' . -'\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' . -'\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' . -'\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' . -'\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' . -'\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' . -'\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' . -'\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' . -'\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' . -'\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' . -'\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' . -'\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' . -'\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' . -'\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' . -'\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' . -'\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' . -'\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' . -'\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' . -'\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' . -'\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' . -'\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' . -'\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' . -'\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' . -'\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' . -'\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' . -'\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' . -'\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' . -'\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' . -'\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' . -'\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' . -'\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' . -'\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' . -'\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' . -'\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' . -'\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' . -'\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' . -'\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' . -'\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' . -'\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' . -'\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' . -'\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' . -'\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' . -'\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' . -'\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' . -'\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' . -'\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' . -'\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' . -'\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' . -'\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' . -'\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' . -'\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' . -'\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' . -'\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' . -'\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' . -'\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' . -'\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' . -'\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' . -'\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' . -'\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' . -'\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' . -'\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' . -'\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' . -'\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' . -'\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' . -'\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' . -'\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' . -'\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' . -'\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' . -'\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' . -'\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' . -'\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' . -'\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' . -'\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' . -'\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' . -'\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' . -'\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' . -'\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' . -'\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' . -'\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' . -'\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' . -'\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' . -'\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' . -'\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' . -'\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' . -'\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' . -'\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' . -'\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' . -'\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' . -'\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' . -'\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' . -'\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' . -'\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' . -'\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' . -'\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' . -'\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' . -'\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' . -'\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' . -'\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' . -'\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' . -'\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' . -'\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' . -'\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' . -'\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' . -'\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' . -'\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' . -'\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' . -'\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' . -'\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' . -'\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' . -'\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' . -'\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' . -'\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' . -'\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' . -'\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' . -'\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' . -'\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' . -'\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' . -'\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' . -'\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' . -'\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' . -'\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' . -'\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' . -'\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' . -'\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' . -'\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' . -'\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' . -'\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' . -'\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' . -'\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' . -'\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' . -'\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' . -'\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' . -'\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' . -'\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' . -'\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' . -'\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' . -'\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' . -'\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' . -'\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' . -'\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' . -'\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' . -'\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' . -'\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' . -'\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' . -'\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' . -'\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' . -'\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' . -'\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' . -'\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' . -'\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' . -'\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' . -'\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' . -'\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' . -'\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' . -'\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' . -'\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' . -'\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' . -'\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' . -'\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' . -'\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' . -'\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' . -'\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' . -'\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' . -'\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' . -'\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' . -'\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' . -'\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' . -'\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' . -'\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' . -'\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' . -'\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' . -'\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' . -'\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' . -'\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' . -'\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' . -'\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' . -'\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' . -'\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' . -'\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' . -'\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' . -'\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' . -'\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' . -'\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' . -'\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' . -'\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' . -'\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' . -'\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' . -'\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' . -'\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' . -'\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' . -'\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' . -'\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' . -'\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' . -'\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' . -'\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' . -'\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' . -'\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' . -'\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' . -'\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' . -'\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' . -'\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' . -'\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' . -'\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' . -'\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' . -'\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' . -'\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' . -'\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' . -'\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' . -'\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' . -'\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' . -'\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' . -'\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' . -'\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' . -'\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' . -'\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' . -'\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' . -'\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' . -'\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' . -'\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' . -'\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' . -'\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' . -'\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' . -'\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' . -'\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' . -'\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' . -'\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' . -'\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' . -'\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' . -'\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' . -'\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' . -'\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' . -'\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' . -'\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' . -'\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' . -'\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' . -'\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' . -'\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' . -'\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' . -'\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' . -'\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' . -'\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' . -'\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' . -'\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' . -'\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' . -'\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' . -'\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' . -'\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' . -'\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' . -'\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' . -'\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' . -'\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' . -'\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' . -'\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' . -'\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' . -'\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' . -'\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' . -'\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' . -'\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' . -'\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' . -'\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' . -'\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' . -'\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' . -'\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' . -'\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' . -'\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' . -'\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' . -'\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' . -'\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' . -'\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' . -'\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' . -'\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' . -'\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' . -'\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' . -'\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' . -'\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' . -'\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' . -'\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' . -'\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' . -'\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' . -'\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' . -'\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' . -'\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' . -'\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' . -'\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' . -'\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' . -'\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' . -'\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' . -'\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' . -'\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' . -'\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' . -'\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' . -'\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' . -'\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' . -'\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' . -'\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' . -'\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' . -'\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' . -'\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' . -'\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' . -'\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' . -'\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' . -'\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' . -'\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' . -'\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' . -'\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' . -'\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' . -'\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' . -'\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' . -'\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' . -'\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' . -'\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' . -'\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' . -'\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' . -'\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' . -'\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' . -'\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' . -'\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' . -'\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . -'\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' . -'\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' . -'\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' . -'\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' . -'\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' . -'\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' . -'\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' . -'\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' . -'\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' . -'\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' . -'\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' . -'\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' . -'\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' . -'\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' . -'\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' . -'\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' . -'\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' . -'\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' . -'\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' . -'\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' . -'\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' . -'\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' . -'\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' . -'\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' . -'\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' . -'\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' . -'\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' . -'\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' . -'\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' . -'\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' . -'\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' . -'\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' . -'\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' . -'\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' . -'\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' . -'\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' . -'\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' . -'\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' . -'\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' . -'\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' . -'\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' . -'\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' . -'\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' . -'\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' . -'\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' . -'\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' . -'\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' . -'\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' . -'\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' . -'\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' . -'\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' . -'\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' . -'\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' . -'\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' . -'\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' . -'\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' . -'\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' . -'\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' . -'\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' . -'\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' . -'\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' . -'\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' . -'\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' . -'\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' . -'\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' . -'\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' . -'\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' . -'\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' . -'\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' . -'\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' . -'\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' . -'\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' . -'\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' . -'\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' . -'\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' . -'\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' . -'\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' . -'\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' . -'\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' . -'\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' . -'\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' . -'\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' . -'\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' . -'\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' . -'\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' . -'\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' . -'\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' . -'\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' . -'\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' . -'\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' . -'\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' . -'\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' . -'\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' . -'\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' . -'\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' . -'\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' . -'\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' . -'\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' . -'\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' . -'\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' . -'\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' . -'\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' . -'\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' . -'\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' . -'\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' . -'\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' . -'\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' . -'\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' . -'\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' . -'\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' . -'\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' . -'\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' . -'\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' . -'\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' . -'\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' . -'\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' . -'\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' . -'\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' . -'\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' . -'\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' . -'\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' . -'\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' . -'\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' . -'\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' . -'\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' . -'\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' . -'\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' . -'\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' . -'\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' . -'\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' . -'\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' . -'\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' . -'\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' . -'\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' . -'\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' . -'\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' . -'\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' . -'\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' . -'\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' . -'\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' . -'\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' . -'\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' . -'\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' . -'\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' . -'\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' . -'\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' . -'\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' . -'\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . -'\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' . -'\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' . -'\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' . -'\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' . -'\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' . -'\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' . -'\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' . -'\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' . -'\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' . -'\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' . -'\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' . -'\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' . -'\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' . -'\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' . -'\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' . -'\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' . -'\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' . -'\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' . -'\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' . -'\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' . -'\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' . -'\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' . -'\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' . -'\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' . -'\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' . -'\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' . -'\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' . -'\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' . -'\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' . -'\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' . -'\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' . -'\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' . -'\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' . -'\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' . -'\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' . -'\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' . -'\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' . -'\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' . -'\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' . -'\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' . -'\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' . -'\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' . -'\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' . -'\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' . -'\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' . -'\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' . -'\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' . -'\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' . -'\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' . -'\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' . -'\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' . -'\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' . -'\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' . -'\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' . -'\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' . -'\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' . -'\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' . -'\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' . -'\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' . -'\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' . -'\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' . -'\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' . -'\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' . -'\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' . -'\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' . -'\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' . -'\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' . -'\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' . -'\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' . -'\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' . -'\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' . -'\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' . -'\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' . -'\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' . -'\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' . -'\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' . -'\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' . -'\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' . -'\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' . -'\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' . -'\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' . -'\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' . -'\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' . -'\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' . -'\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' . -'\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' . -'\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' . -'\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' . -'\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' . -'\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' . -'\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' . -'\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' . -'\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' . -'\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' . -'\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' . -'\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' . -'\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' . -'\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' . -'\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' . -'\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' . -'\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' . -'\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' . -'\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' . -'\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' . -'\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' . -'\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' . -'\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' . -'\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' . -'\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' . -'\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' . -'\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' . -'\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' . -'\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' . -'\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' . -'\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' . -'\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' . -'\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' . -'\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' . -'\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' . -'\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' . -'\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' . -'\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' . -'\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' . -'\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' . -'\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' . -'\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' . -'\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' . -'\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' . -'\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' . -'\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' . -'\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' . -'\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' . -'\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' . -'\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' . -'\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' . -'\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' . -'\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' . -'\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' . -'\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' . -'\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' . -'\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' . -'\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' . -'\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' . -'\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' . -'\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' . -'\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' . -'\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' . -'\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' . -'\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' . -'\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' . -'\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' . -'\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' . -'\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' . -'\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' . -'\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' . -'\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' . -'\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' . -'\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' . -'\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' . -'\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' . -'\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' . -'\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' . -'\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' . -'\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' . -'\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' . -'\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' . -'\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' . -'\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' . -'\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' . -'\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' . -'\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' . -'\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' . -'\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' . -'\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' . -'\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' . -'\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' . -'\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' . -'\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' . -'\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' . -'\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' . -'\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' . -'\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' . -'\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' . -'\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' . -'\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' . -'\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' . -'\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' . -'\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' . -'\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' . -'\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' . -'\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' . -'\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' . -'\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' . -'\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' . -'\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' . -'\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' . -'\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' . -'\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' . -'\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' . -'\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' . -'\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' . -'\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' . -'\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' . -'\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' . -'\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' . -'\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' . -'\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' . -'\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' . -'\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' . -'\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' . -'\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' . -'\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' . -'\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' . -'\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' . -'\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' . -'\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' . -'\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' . -'\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' . -'\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' . -'\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' . -'\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' . -'\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' . -'\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' . -'\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' . -'\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' . -'\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' . -'\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' . -'\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' . -'\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' . -'\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' . -'\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' . -'\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' . -'\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' . -'\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' . -'\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' . -'\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' . -'\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' . -'\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' . -'\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' . -'\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' . -'\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' . -'\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' . -'\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' . -'\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' . -'\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' . -'\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' . -'\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' . -'\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' . -'\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' . -'\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' . -'\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' . -'\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' . -'\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' . -'\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' . -'\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' . -'\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' . -'\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' . -'\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' . -'\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' . -'\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' . -'\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' . -'\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' . -'\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' . -'\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' . -'\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' . -'\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' . -'\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' . -'\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' . -'\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' . -'\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' . -'\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' . -'\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' . -'\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' . -'\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' . -'\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' . -'\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' . -'\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' . -'\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' . -'\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' . -'\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' . -'\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' . -'\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' . -'\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' . -'\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' . -'\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' . -'\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' . -'\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' . -'\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' . -'\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' . -'\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' . -'\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' . -'\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' . -'\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' . -'\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' . -'\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' . -'\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' . -'\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' . -'\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' . -'\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' . -'\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' . -'\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' . -'\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' . -'\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' . -'\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' . -'\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' . -'\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' . -'\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' . -'\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' . -'\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' . -'\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' . -'\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' . -'\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' . -'\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' . -'\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' . -'\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' . -'\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' . -'\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' . -'\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' . -'\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' . -'\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' . -'\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' . -'\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' . -'\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' . -'\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' . -'\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' . -'\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' . -'\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' . -'\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' . -'\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' . -'\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' . -'\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' . -'\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' . -'\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' . -'\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' . -'\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' . -'\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' . -'\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' . -'\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' . -'\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' . -'\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' . -'\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' . -'\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' . -'\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' . -'\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' . -'\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' . -'\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' . -'\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' . -'\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' . -'\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' . -'\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' . -'\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' . -'\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' . -'\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' . -'\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' . -'\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' . -'\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' . -'\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' . -'\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' . -'\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' . -'\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' . -'\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' . -'\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' . -'\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' . -'\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' . -'\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' . -'\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' . -'\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' . -'\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' . -'\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' . -'\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' . -'\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' . -'\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' . -'\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' . -'\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' . -'\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' . -'\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' . -'\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' . -'\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' . -'\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' . -'\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' . -'\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' . -'\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' . -'\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' . -'\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' . -'\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' . -'\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' . -'\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' . -'\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' . -'\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' . -'\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' . -'\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' . -'\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' . -'\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' . -'\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' . -'\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' . -'\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' . -'\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' . -'\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' . -'\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' . -'\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' . -'\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' . -'\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' . -'\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' . -'\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' . -'\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' . -'\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' . -'\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' . -'\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' . -'\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' . -'\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' . -'\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' . -'\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' . -'\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' . -'\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' . -'\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' . -'\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' . -'\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' . -'\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' . -'\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' . -'\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' . -'\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' . -'\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' . -'\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' . -'\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' . -'\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' . -'\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' . -'\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' . -'\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' . -'\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' . -'\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' . -'\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' . -'\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' . -'\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' . -'\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' . -'\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' . -'\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' . -'\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' . -'\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' . -'\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' . -'\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' . -'\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' . -'\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' . -'\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' . -'\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' . -'\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' . -'\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' . -'\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' . -'\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' . -'\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' . -'\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' . -'\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' . -'\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' . -'\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' . -'\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' . -'\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' . -'\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' . -'\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' . -'\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' . -'\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' . -'\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' . -'\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' . -'\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' . -'\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' . -'\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' . -'\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' . -'\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' . -'\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' . -'\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' . -'\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' . -'\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' . -'\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' . -'\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' . -'\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' . -'\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' . -'\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' . -'\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' . -'\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' . -'\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' . -'\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' . -'\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' . -'\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' . -'\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' . -'\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' . -'\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' . -'\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' . -'\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' . -'\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' . -'\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' . -'\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' . -'\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' . -'\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' . -'\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' . -'\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' . -'\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' . -'\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' . -'\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' . -'\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' . -'\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' . -'\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . -'\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' . -'\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' . -'\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' . -'\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' . -'\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' . -'\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' . -'\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' . -'\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' . -'\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' . -'\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' . -'\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' . -'\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' . -'\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' . -'\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' . -'\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' . -'\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' . -'\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' . -'\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' . -'\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' . -'\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' . -'\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' . -'\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' . -'\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' . -'\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' . -'\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' . -'\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' . -'\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' . -'\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' . -'\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' . -'\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' . -'\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' . -'\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' . -'\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' . -'\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' . -'\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' . -'\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' . -'\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' . -'\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' . -'\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' . -'\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' . -'\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' . -'\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' . -'\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' . -'\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' . -'\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' . -'\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' . -'\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' . -'\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' . -'\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' . -'\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' . -'\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' . -'\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' . -'\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' . -'\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' . -'\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' . -'\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' . -'\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' . -'\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' . -'\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' . -'\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' . -'\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' . -'\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' . -'\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' . -'\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' . -'\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' . -'\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' . -'\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' . -'\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' . -'\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' . -'\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' . -'\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' . -'\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' . -'\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' . -'\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' . -'\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' . -'\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' . -'\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' . -'\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' . -'\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' . -'\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' . -'\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' . -'\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' . -'\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' . -'\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' . -'\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' . -'\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' . -'\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' . -'\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' . -'\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' . -'\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' . -'\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' . -'\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' . -'\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' . -'\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' . -'\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' . -'\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' . -'\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' . -'\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' . -'\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' . -'\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' . -'\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' . -'\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' . -'\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' . -'\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' . -'\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' . -'\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' . -'\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' . -'\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' . -'\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' . -'\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' . -'\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' . -'\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' . -'\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' . -'\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' . -'\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' . -'\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' . -'\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' . -'\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' . -'\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' . -'\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' . -'\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' . -'\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' . -'\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' . -'\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' . -'\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' . -'\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' . -'\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' . -'\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' . -'\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' . -'\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' . -'\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' . -'\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' . -'\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' . -'\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' . -'\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' . -'\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' . -'\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' . -'\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' . -'\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' . -'\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' . -'\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' . -'\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' . -'\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' . -'\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' . -'\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' . -'\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' . -'\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' . -'\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' . -'\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' . -'\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' . -'\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' . -'\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' . -'\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' . -'\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' . -'\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' . -'\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' . -'\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' . -'\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' . -'\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' . -'\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' . -'\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' . -'\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' . -'\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' . -'\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' . -'\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' . -'\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' . -'\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' . -'\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' . -'\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' . -'\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' . -'\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' . -'\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' . -'\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' . -'\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' . -'\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' . -'\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' . -'\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' . -'\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' . -'\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' . -'\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' . -'\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' . -'\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' . -'\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' . -'\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' . -'\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' . -'\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' . -'\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' . -'\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' . -'\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' . -'\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' . -'\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' . -'\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' . -'\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' . -'\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' . -'\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' . -'\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' . -'\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' . -'\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' . -'\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' . -'\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' . -'\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' . -'\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' . -'\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' . -'\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' . -'\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' . -'\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' . -'\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' . -'\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' . -'\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' . -'\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' . -'\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' . -'\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' . -'\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' . -'\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' . -'\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' . -'\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' . -'\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' . -'\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' . -'\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' . -'\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' . -'\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' . -'\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' . -'\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' . -'\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' . -'\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' . -'\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' . -'\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' . -'\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' . -'\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' . -'\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' . -'\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' . -'\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' . -'\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' . -'\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' . -'\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' . -'\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' . -'\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' . -'\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' . -'\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' . -'\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' . -'\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' . -'\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' . -'\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' . -'\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' . -'\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' . -'\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' . -'\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' . -'\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' . -'\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' . -'\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' . -'\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' . -'\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' . -'\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' . -'\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' . -'\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' . -'\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' . -'\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' . -'\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' . -'\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' . -'\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' . -'\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' . -'\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' . -'\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' . -'\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' . -'\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' . -'\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' . -'\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' . -'\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' . -'\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' . -'\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' . -'\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' . -'\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' . -'\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' . -'\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' . -'\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' . -'\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' . -'\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' . -'\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' . -'\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' . -'\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' . -'\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' . -'\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' . -'\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' . -'\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' . -'\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' . -'\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' . -'\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' . -'\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' . -'\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' . -'\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' . -'\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' . -'\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' . -'\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' . -'\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' . -'\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' . -'\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' . -'\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' . -'\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' . -'\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' . -'\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' . -'\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' . -'\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' . -'\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' . -'\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' . -'\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' . -'\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' . -'\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' . -'\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' . -'\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' . -'\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' . -'\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' . -'\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' . -'\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' . -'\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' . -'\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' . -'\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' . -'\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' . -'\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' . -'\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' . -'\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' . -'\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' . -'\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' . -'\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' . -'\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' . -'\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' . -'\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' . -'\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' . -'\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' . -'\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' . -'\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' . -'\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' . -'\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' . -'\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' . -'\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' . -'\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' . -'\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' . -'\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' . -'\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' . -'\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' . -'\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' . -'\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' . -'\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' . -'\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' . -'\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' . -'\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' . -'\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' . -'\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' . -'\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' . -'\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' . -'\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' . -'\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' . -'\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' . -'\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' . -'\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' . -'\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' . -'\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' . -'\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' . -'\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' . -'\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' . -'\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' . -'\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' . -'\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' . -'\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' . -'\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' . -'\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' . -'\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' . -'\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' . -'\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' . -'\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' . -'\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' . -'\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' . -'\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' . -'\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' . -'\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' . -'\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' . -'\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' . -'\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' . -'\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' . -'\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' . -'\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' . -'\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' . -'\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' . -'\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' . -'\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' . -'\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' . -'\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' . -'\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' . -'\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' . -'\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' . -'\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' . -'\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' . -'\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' . -'\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' . -'\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' . -'\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' . -'\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' . -'\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' . -'\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' . -'\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' . -'\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' . -'\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' . -'\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' . -'\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' . -'\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' . -'\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' . -'\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' . -'\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' . -'\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' . -'\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' . -'\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' . -'\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' . -'\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' . -'\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' . -'\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' . -'\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' . -'\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' . -'\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' . -'\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' . -'\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' . -'\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' . -'\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' . -'\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' . -'\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' . -'\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' . -'\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' . -'\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' . -'\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' . -'\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' . -'\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' . -'\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' . -'\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' . -'\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' . -'\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' . -'\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' . -'\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' . -'\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' . -'\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' . -'\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' . -'\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' . -'\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' . -'\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' . -'\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' . -'\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' . -'\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' . -'\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' . -'\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' . -'\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' . -'\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' . -'\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' . -'\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' . -'\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' . -'\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' . -'\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' . -'\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' . -'\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' . -'\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' . -'\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' . -'\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' . -'\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' . -'\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' . -'\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' . -'\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' . -'\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' . -'\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' . -'\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' . -'\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' . -'\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' . -'\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' . -'\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' . -'\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' . -'\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' . -'\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' . -'\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' . -'\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' . -'\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' . -'\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' . -'\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' . -'\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' . -'\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' . -'\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' . -'\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' . -'\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' . -'\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' . -'\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' . -'\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' . -'\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' . -'\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' . -'\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' . -'\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' . -'\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' . -'\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' . -'\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' . -'\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' . -'\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' . -'\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' . -'\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' . -'\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' . -'\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' . -'\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' . -'\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' . -'\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' . -'\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' . -'\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' . -'\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' . -'\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' . -'\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' . -'\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' . -'\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' . -'\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' . -'\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' . -'\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' . -'\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' . -'\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' . -'\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' . -'\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' . -'\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' . -'\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' . -'\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' . -'\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' . -'\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' . -'\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' . -'\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' . -'\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' . -'\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' . -'\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' . -'\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' . -'\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' . -'\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' . -'\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' . -'\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' . -'\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' . -'\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' . -'\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' . -'\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' . -'\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' . -'\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' . -'\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' . -'\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' . -'\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' . -'\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' . -'\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' . -'\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' . -'\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' . -'\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' . -'\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' . -'\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' . -'\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' . -'\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' . -'\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' . -'\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' . -'\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' . -'\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' . -'\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' . -'\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' . -'\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' . -'\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' . -'\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' . -'\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' . -'\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' . -'\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' . -'\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' . -'\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' . -'\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' . -'\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' . -'\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' . -'\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' . -'\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' . -'\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' . -'\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' . -'\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' . -'\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' . -'\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' . -'\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' . -'\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' . -'\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' . -'\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' . -'\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' . -'\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' . -'\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' . -'\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' . -'\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' . -'\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' . -'\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' . -'\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' . -'\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' . -'\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' . -'\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' . -'\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' . -'\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' . -'\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' . -'\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' . -'\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' . -'\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' . -'\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' . -'\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' . -'\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' . -'\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' . -'\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' . -'\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' . -'\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' . -'\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' . -'\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' . -'\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' . -'\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' . -'\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' . -'\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' . -'\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' . -'\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' . -'\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' . -'\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' . -'\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' . -'\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' . -'\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' . -'\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' . -'\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' . -'\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' . -'\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' . -'\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' . -'\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' . -'\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' . -'\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' . -'\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' . -'\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' . -'\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' . -'\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' . -'\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' . -'\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' . -'\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' . -'\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' . -'\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' . -'\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' . -'\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' . -'\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' . -'\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' . -'\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' . -'\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' . -'\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' . -'\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' . -'\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' . -'\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' . -'\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' . -'\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' . -'\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' . -'\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' . -'\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' . -'\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' . -'\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' . -'\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' . -'\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' . -'\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' . -'\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' . -'\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' . -'\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' . -'\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' . -'\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' . -'\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' . -'\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' . -'\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' . -'\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' . -'\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' . -'\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' . -'\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' . -'\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' . -'\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' . -'\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' . -'\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' . -'\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' . -'\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' . -'\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' . -'\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' . -'\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' . -'\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' . -'\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' . -'\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' . -'\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' . -'\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' . -'\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' . -'\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' . -'\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' . -'\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' . -'\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' . -'\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' . -'\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' . -'\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' . -'\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' . -'\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' . -'\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' . -'\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' . -'\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' . -'\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' . -'\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' . -'\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' . -'\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' . -'\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' . -'\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' . -'\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' . -'\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' . -'\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' . -'\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' . -'\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' . -'\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' . -'\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' . -'\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' . -'\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' . -'\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' . -'\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' . -'\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' . -'\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' . -'\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' . -'\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' . -'\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' . -'\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' . -'\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' . -'\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' . -'\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' . -'\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' . -'\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' . -'\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' . -'\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' . -'\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' . -'\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' . -'\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' . -'\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' . -'\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' . -'\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' . -'\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' . -'\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' . -'\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' . -'\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' . -'\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' . -'\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' . -'\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' . -'\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' . -'\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' . -'\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' . -'\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' . -'\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' . -'\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' . -'\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' . -'\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' . -'\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' . -'\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' . -'\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' . -'\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' . -'\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' . -'\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' . -'\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' . -'\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' . -'\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' . -'\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' . -'\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' . -'\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' . -'\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' . -'\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' . -'\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' . -'\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' . -'\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' . -'\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' . -'\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' . -'\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' . -'\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' . -'\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' . -'\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' . -'\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' . -'\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' . -'\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' . -'\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' . -'\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' . -'\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' . -'\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' . -'\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' . -'\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' . -'\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' . -'\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' . -'\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' . -'\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' . -'\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' . -'\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' . -'\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' . -'\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' . -'\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' . -'\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' . -'\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' . -'\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' . -'\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' . -'\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' . -'\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' . -'\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' . -'\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' . -'\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' . -'\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' . -'\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' . -'\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' . -'\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' . -'\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' . -'\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' . -'\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' . -'\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' . -'\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' . -'\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' . -'\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' . -'\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' . -'\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' . -'\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' . -'\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' . -'\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' . -'\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' . -'\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' . -'\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' . -'\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' . -'\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' . -'\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' . -'\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' . -'\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' . -'\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' . -'\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' . -'\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' . -'\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' . -'\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' . -'\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' . -'\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' . -'\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' . -'\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' . -'\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' . -'\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' . -'\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' . -'\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' . -'\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' . -'\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' . -'\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' . -'\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' . -'\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' . -'\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' . -'\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' . -'\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' . -'\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' . -'\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' . -'\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' . -'\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' . -'\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' . -'\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' . -'\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' . -'\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' . -'\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' . -'\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' . -'\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' . -'\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' . -'\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' . -'\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' . -'\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' . -'\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' . -'\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' . -'\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' . -'\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' . -'\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' . -'\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' . -'\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' . -'\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' . -'\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' . -'\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' . -'\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' . -'\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' . -'\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' . -'\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' . -'\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' . -'\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' . -'\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' . -'\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' . -'\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' . -'\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' . -'\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' . -'\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' . -'\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' . -'\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' . -'\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' . -'\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' . -'\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' . -'\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' . -'\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' . -'\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' . -'\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' . -'\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' . -'\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' . -'\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' . -'\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' . -'\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' . -'\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' . -'\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' . -'\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' . -'\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' . -'\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' . -'\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' . -'\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' . -'\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' . -'\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' . -'\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' . -'\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' . -'\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' . -'\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' . -'\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' . -'\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' . -'\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' . -'\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' . -'\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' . -'\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' . -'\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' . -'\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' . -'\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' . -'\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' . -'\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' . -'\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' . -'\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' . -'\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' . -'\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' . -'\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' . -'\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' . -'\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' . -'\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' . -'\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' . -'\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' . -'\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' . -'\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' . -'\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' . -'\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' . -'\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' . -'\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . -'\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' . -'\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' . -'\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' . -'\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' . -'\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' . -'\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' . -'\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' . -'\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' . -'\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' . -'\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' . -'\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' . -'\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' . -'\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' . -'\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' . -'\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' . -'\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' . -'\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' . -'\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' . -'\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' . -'\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' . -'\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' . -'\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' . -'\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' . -'\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' . -'\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' . -'\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' . -'\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' . -'\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' . -'\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' . -'\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' . -'\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' . -'\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' . -'\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' . -'\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' . -'\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' . -'\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' . -'\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' . -'\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' . -'\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' . -'\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' . -'\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' . -'\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' . -'\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' . -'\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' . -'\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' . -'\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' . -'\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' . -'\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' . -'\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' . -'\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' . -'\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' . -'\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' . -'\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' . -'\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' . -'\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' . -'\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' . -'\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' . -'\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' . -'\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' . -'\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' . -'\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' . -'\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' . -'\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' . -'\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' . -'\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' . -'\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' . -'\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' . -'\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' . -'\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu'); diff --git a/lib/Zend/Validate/Hostname/Com.php b/lib/Zend/Validate/Hostname/Com.php deleted file mode 100644 index 873dd522b7f..00000000000 --- a/lib/Zend/Validate/Hostname/Com.php +++ /dev/null @@ -1,196 +0,0 @@ - '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu', - 2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu', - 4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' . -'\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' . -'\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' . -'\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' . -'\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' . -'\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' . -'\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' . -'\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' . -'\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' . -'\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' . -'\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' . -'\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' . -'\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' . -'\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' . -'\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' . -'\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' . -'\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' . -'\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' . -'\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' . -'\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' . -'\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' . -'\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' . -'\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' . -'\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' . -'\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' . -'\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' . -'\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' . -'\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' . -'\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' . -'\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' . -'\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' . -'\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' . -'\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' . -'\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' . -'\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' . -'\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' . -'\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' . -'\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' . -'\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' . -'\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' . -'\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' . -'\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' . -'\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' . -'\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' . -'\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' . -'\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' . -'\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' . -'\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' . -'\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' . -'\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' . -'\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' . -'\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' . -'\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' . -'\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' . -'\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' . -'\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' . -'\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' . -'\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' . -'\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' . -'\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' . -'\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' . -'\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' . -'\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' . -'\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' . -'\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' . -'\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' . -'\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' . -'\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' . -'\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' . -'\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' . -'\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' . -'\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' . -'\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' . -'\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' . -'\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' . -'\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' . -'\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' . -'\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' . -'\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' . -'\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' . -'\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' . -'\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' . -'\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' . -'\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' . -'\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' . -'\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' . -'\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu', - 6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu', - 7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu', - 8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu', - 9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu', - 10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu', - 11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu', - 12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu', - 13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu', - 14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu', - 15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu', - 16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu', - 17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu', - 18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu', - 19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu', - 20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu', - 21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu', - 22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu', - 23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu', - 24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu', - 25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu', - 26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu', - 27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu', - 28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu', - 29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu', - 30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu', - 31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu', - 32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu', - 33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu', - 34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu', - 35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu', - 36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu', - 37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu', - 38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu', - 39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu', - 40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu', - 41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu', - 42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu', - 43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu', - 44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu', - 45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu', - 46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu', - 47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu', - 48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu', - 49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu', - 50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu', - 51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu', - 52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu', - 53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu', - 54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu', - 55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu', - 56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu', - 57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu', - 58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu', - 59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu', - 60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu', - 61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu', - 62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu', - 63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu', - 64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu', - 65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu', - 66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu', - 67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu', - 68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu', - 69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu', - 70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu', - 73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu', - 74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu', - 75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu', - 76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu', - 77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu', - 78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu', - 79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu', - 80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu' - -); diff --git a/lib/Zend/Validate/Hostname/Jp.php b/lib/Zend/Validate/Hostname/Jp.php deleted file mode 100644 index caca994b941..00000000000 --- a/lib/Zend/Validate/Hostname/Jp.php +++ /dev/null @@ -1,739 +0,0 @@ - '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' . -'\x{30A1}-\x{30F6}\x{30FC}' . -'\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . -'\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' . -'\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' . -'\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' . -'\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' . -'\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' . -'\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' . -'\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' . -'\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' . -'\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' . -'\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' . -'\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' . -'\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' . -'\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' . -'\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' . -'\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' . -'\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' . -'\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' . -'\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' . -'\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' . -'\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' . -'\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' . -'\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' . -'\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' . -'\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' . -'\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' . -'\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' . -'\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' . -'\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' . -'\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' . -'\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' . -'\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' . -'\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' . -'\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' . -'\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . -'\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' . -'\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' . -'\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' . -'\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' . -'\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' . -'\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' . -'\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' . -'\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' . -'\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' . -'\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' . -'\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' . -'\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' . -'\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' . -'\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' . -'\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' . -'\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' . -'\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' . -'\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' . -'\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' . -'\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' . -'\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' . -'\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' . -'\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' . -'\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' . -'\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' . -'\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' . -'\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' . -'\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' . -'\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' . -'\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' . -'\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' . -'\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' . -'\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' . -'\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' . -'\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' . -'\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' . -'\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' . -'\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' . -'\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' . -'\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' . -'\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' . -'\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' . -'\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' . -'\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' . -'\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' . -'\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' . -'\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' . -'\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' . -'\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' . -'\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' . -'\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' . -'\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' . -'\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' . -'\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' . -'\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' . -'\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' . -'\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' . -'\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' . -'\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' . -'\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' . -'\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' . -'\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' . -'\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' . -'\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' . -'\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' . -'\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' . -'\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' . -'\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' . -'\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' . -'\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' . -'\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' . -'\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' . -'\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' . -'\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' . -'\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' . -'\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' . -'\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' . -'\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' . -'\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' . -'\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' . -'\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' . -'\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' . -'\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' . -'\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' . -'\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' . -'\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' . -'\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' . -'\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' . -'\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' . -'\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' . -'\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' . -'\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' . -'\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' . -'\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' . -'\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' . -'\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' . -'\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' . -'\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' . -'\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' . -'\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' . -'\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' . -'\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' . -'\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' . -'\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' . -'\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' . -'\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' . -'\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' . -'\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' . -'\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' . -'\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' . -'\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' . -'\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' . -'\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' . -'\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' . -'\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' . -'\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' . -'\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' . -'\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' . -'\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' . -'\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' . -'\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' . -'\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' . -'\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' . -'\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' . -'\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' . -'\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' . -'\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' . -'\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' . -'\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' . -'\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' . -'\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' . -'\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' . -'\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' . -'\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' . -'\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' . -'\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' . -'\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' . -'\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' . -'\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' . -'\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' . -'\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' . -'\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' . -'\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' . -'\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' . -'\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' . -'\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' . -'\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' . -'\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' . -'\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' . -'\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' . -'\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' . -'\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' . -'\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' . -'\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' . -'\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' . -'\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' . -'\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' . -'\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' . -'\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' . -'\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' . -'\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' . -'\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . -'\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' . -'\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' . -'\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' . -'\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' . -'\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' . -'\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' . -'\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' . -'\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' . -'\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' . -'\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' . -'\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' . -'\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' . -'\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' . -'\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' . -'\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' . -'\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' . -'\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' . -'\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' . -'\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' . -'\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' . -'\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' . -'\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' . -'\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' . -'\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' . -'\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' . -'\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' . -'\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' . -'\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' . -'\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' . -'\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' . -'\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' . -'\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' . -'\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' . -'\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' . -'\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' . -'\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' . -'\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' . -'\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' . -'\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' . -'\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' . -'\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' . -'\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' . -'\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' . -'\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' . -'\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' . -'\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' . -'\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' . -'\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' . -'\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' . -'\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' . -'\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' . -'\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' . -'\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' . -'\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' . -'\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' . -'\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . -'\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' . -'\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' . -'\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' . -'\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' . -'\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' . -'\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' . -'\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' . -'\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' . -'\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' . -'\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' . -'\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' . -'\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' . -'\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' . -'\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' . -'\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' . -'\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' . -'\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' . -'\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' . -'\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' . -'\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' . -'\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' . -'\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' . -'\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' . -'\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' . -'\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' . -'\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' . -'\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' . -'\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' . -'\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' . -'\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' . -'\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' . -'\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' . -'\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' . -'\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' . -'\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' . -'\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' . -'\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' . -'\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' . -'\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' . -'\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' . -'\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' . -'\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' . -'\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' . -'\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' . -'\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' . -'\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' . -'\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' . -'\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' . -'\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' . -'\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' . -'\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' . -'\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' . -'\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' . -'\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' . -'\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' . -'\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' . -'\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' . -'\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' . -'\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' . -'\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' . -'\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' . -'\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' . -'\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' . -'\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' . -'\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' . -'\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' . -'\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' . -'\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' . -'\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' . -'\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' . -'\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' . -'\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' . -'\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' . -'\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' . -'\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' . -'\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' . -'\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' . -'\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' . -'\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' . -'\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' . -'\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' . -'\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' . -'\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' . -'\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' . -'\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' . -'\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' . -'\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' . -'\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' . -'\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' . -'\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' . -'\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' . -'\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' . -'\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' . -'\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' . -'\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' . -'\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' . -'\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' . -'\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' . -'\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' . -'\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' . -'\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' . -'\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' . -'\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' . -'\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' . -'\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' . -'\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' . -'\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' . -'\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' . -'\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' . -'\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' . -'\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' . -'\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' . -'\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' . -'\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' . -'\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' . -'\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' . -'\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' . -'\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' . -'\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' . -'\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' . -'\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' . -'\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' . -'\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' . -'\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' . -'\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' . -'\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' . -'\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' . -'\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' . -'\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' . -'\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' . -'\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' . -'\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' . -'\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' . -'\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' . -'\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' . -'\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' . -'\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' . -'\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' . -'\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' . -'\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' . -'\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' . -'\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' . -'\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' . -'\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' . -'\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' . -'\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' . -'\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' . -'\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' . -'\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' . -'\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' . -'\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' . -'\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' . -'\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' . -'\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' . -'\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' . -'\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' . -'\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' . -'\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . -'\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' . -'\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' . -'\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' . -'\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' . -'\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' . -'\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' . -'\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' . -'\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' . -'\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' . -'\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' . -'\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' . -'\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' . -'\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' . -'\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' . -'\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' . -'\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' . -'\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' . -'\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' . -'\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' . -'\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' . -'\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' . -'\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' . -'\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' . -'\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' . -'\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' . -'\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' . -'\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' . -'\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' . -'\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' . -'\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' . -'\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' . -'\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' . -'\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' . -'\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' . -'\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' . -'\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' . -'\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' . -'\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' . -'\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' . -'\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' . -'\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' . -'\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' . -'\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' . -'\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' . -'\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' . -'\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' . -'\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' . -'\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' . -'\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' . -'\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' . -'\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' . -'\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' . -'\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' . -'\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' . -'\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' . -'\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' . -'\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' . -'\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' . -'\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' . -'\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' . -'\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' . -'\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' . -'\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' . -'\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' . -'\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' . -'\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' . -'\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' . -'\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' . -'\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' . -'\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' . -'\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' . -'\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' . -'\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' . -'\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' . -'\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' . -'\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' . -'\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' . -'\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' . -'\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' . -'\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' . -'\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' . -'\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' . -'\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' . -'\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' . -'\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' . -'\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' . -'\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' . -'\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' . -'\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' . -'\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' . -'\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' . -'\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' . -'\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' . -'\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' . -'\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' . -'\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' . -'\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' . -'\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' . -'\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' . -'\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' . -'\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' . -'\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' . -'\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' . -'\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' . -'\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' . -'\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' . -'\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' . -'\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' . -'\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' . -'\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' . -'\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' . -'\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' . -'\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' . -'\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' . -'\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' . -'\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' . -'\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' . -'\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' . -'\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' . -'\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' . -'\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' . -'\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' . -'\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' . -'\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' . -'\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' . -'\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' . -'\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' . -'\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' . -'\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' . -'\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' . -'\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' . -'\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' . -'\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' . -'\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' . -'\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' . -'\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' . -'\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' . -'\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' . -'\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' . -'\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' . -'\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' . -'\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' . -'\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' . -'\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' . -'\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' . -'\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' . -'\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' . -'\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' . -'\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' . -'\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' . -'\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' . -'\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' . -'\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' . -'\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' . -'\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' . -'\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' . -'\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' . -'\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' . -'\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' . -'\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' . -'\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' . -'\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' . -'\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' . -'\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' . -'\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' . -'\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' . -'\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' . -'\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' . -'\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' . -'\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' . -'\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' . -'\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' . -'\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' . -'\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' . -'\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' . -'\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' . -'\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' . -'\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' . -'\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' . -'\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' . -'\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' . -'\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' . -'\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' . -'\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' . -'\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' . -'\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' . -'\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' . -'\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' . -'\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' . -'\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' . -'\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' . -'\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' . -'\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' . -'\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' . -'\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' . -'\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' . -'\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' . -'\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' . -'\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' . -'\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' . -'\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' . -'\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' . -'\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' . -'\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' . -'\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' . -'\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' . -'\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' . -'\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' . -'\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' . -'\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' . -'\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' . -'\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' . -'\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' . -'\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' . -'\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' . -'\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' . -'\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' . -'\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' . -'\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' . -'\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' . -'\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' . -'\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' . -'\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' . -'\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' . -'\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' . -'\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' . -'\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' . -'\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' . -'\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' . -'\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' . -'\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' . -'\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' . -'\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' . -'\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' . -'\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' . -'\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' . -'\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' . -'\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' . -'\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' . -'\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' . -'\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' . -'\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' . -'\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' . -'\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' . -'\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' . -'\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' . -'\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' . -'\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' . -'\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' . -'\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' . -'\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' . -'\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' . -'\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' . -'\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' . -'\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' . -'\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' . -'\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' . -'\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' . -'\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' . -'\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' . -'\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' . -'\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' . -'\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' . -'\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' . -'\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' . -'\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' . -'\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' . -'\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' . -'\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' . -'\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' . -'\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' . -'\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' . -'\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' . -'\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' . -'\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' . -'\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' . -'\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' . -'\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' . -'\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . -'\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' . -'\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' . -'\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' . -'\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' . -'\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' . -'\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' . -'\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' . -'\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' . -'\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' . -'\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' . -'\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' . -'\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' . -'\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' . -'\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' . -'\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' . -'\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' . -'\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu'); diff --git a/lib/Zend/Validate/Iban.php b/lib/Zend/Validate/Iban.php deleted file mode 100644 index a67bfff4bb8..00000000000 --- a/lib/Zend/Validate/Iban.php +++ /dev/null @@ -1,250 +0,0 @@ - "Unknown country within the IBAN '%value%'", - self::FALSEFORMAT => "'%value%' has a false IBAN format", - self::CHECKFAILED => "'%value%' has failed the IBAN check", - ); - - /** - * Optional locale - * - * @var string|Zend_Locale|null - */ - protected $_locale; - - /** - * IBAN regexes by region - * - * @var array - */ - protected $_ibanregex = array( - 'AD' => '/^AD[0-9]{2}[0-9]{8}[A-Z0-9]{12}$/', - 'AE' => '/^AE[0-9]{2}[0-9]{3}[0-9]{16}$/', - 'AL' => '/^AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/', - 'AT' => '/^AT[0-9]{2}[0-9]{5}[0-9]{11}$/', - 'AZ' => '/^AZ[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/', - 'BA' => '/^BA[0-9]{2}[0-9]{6}[0-9]{10}$/', - 'BE' => '/^BE[0-9]{2}[0-9]{3}[0-9]{9}$/', - 'BG' => '/^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$/', - 'BH' => '/^BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}$/', - 'BR' => '/^BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z]{1}[A-Z0-9]{1}$/', - 'CH' => '/^CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/', - 'CR' => '/^CR[0-9]{2}[0-9]{3}[0-9]{14}$/', - 'CS' => '/^CS[0-9]{2}[0-9]{3}[0-9]{15}$/', - 'CY' => '/^CY[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/', - 'CZ' => '/^CZ[0-9]{2}[0-9]{4}[0-9]{16}$/', - 'DE' => '/^DE[0-9]{2}[0-9]{8}[0-9]{10}$/', - 'DK' => '/^DK[0-9]{2}[0-9]{4}[0-9]{10}$/', - 'DO' => '/^DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}$/', - 'EE' => '/^EE[0-9]{2}[0-9]{4}[0-9]{12}$/', - 'ES' => '/^ES[0-9]{2}[0-9]{8}[0-9]{12}$/', - 'FR' => '/^FR[0-9]{2}[0-9]{10}[A-Z0-9]{11}[0-9]{2}$/', - 'FI' => '/^FI[0-9]{2}[0-9]{6}[0-9]{8}$/', - 'FO' => '/^FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/', - 'GB' => '/^GB[0-9]{2}[A-Z]{4}[0-9]{14}$/', - 'GE' => '/^GE[0-9]{2}[A-Z]{2}[0-9]{16}$/', - 'GI' => '/^GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}$/', - 'GL' => '/^GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/', - 'GR' => '/^GR[0-9]{2}[0-9]{7}[A-Z0-9]{16}$/', - 'GT' => '/^GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}$/', - 'HR' => '/^HR[0-9]{2}[0-9]{7}[0-9]{10}$/', - 'HU' => '/^HU[0-9]{2}[0-9]{7}[0-9]{1}[0-9]{15}[0-9]{1}$/', - 'IE' => '/^IE[0-9]{2}[A-Z0-9]{4}[0-9]{6}[0-9]{8}$/', - 'IL' => '/^IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}$/', - 'IS' => '/^IS[0-9]{2}[0-9]{4}[0-9]{18}$/', - 'IT' => '/^IT[0-9]{2}[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$/', - 'KW' => '/^KW[0-9]{2}[A-Z]{4}[0-9]{3}[0-9]{22}$/', - 'KZ' => '/^KZ[A-Z]{2}[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/', - 'LB' => '/^LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/', - 'LI' => '/^LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/', - 'LU' => '/^LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/', - 'LT' => '/^LT[0-9]{2}[0-9]{5}[0-9]{11}$/', - 'LV' => '/^LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}$/', - 'MC' => '/^MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$/', - 'MD' => '/^MD[0-9]{2}[A-Z0-9]{20}$/', - 'ME' => '/^ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/', - 'MK' => '/^MK[0-9]{2}[A-Z]{3}[A-Z0-9]{10}[0-9]{2}$/', - 'MR' => '/^MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}$/', - 'MU' => '/^MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{2}$/', - 'MT' => '/^MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$/', - 'NL' => '/^NL[0-9]{2}[A-Z]{4}[0-9]{10}$/', - 'NO' => '/^NO[0-9]{2}[0-9]{4}[0-9]{7}$/', - 'PK' => '/^PK[0-9]{2}[A-Z]{4}[0-9]{16}$/', - 'PL' => '/^PL[0-9]{2}[0-9]{8}[0-9]{16}$/', - 'PS' => '/^PS[0-9]{2}[A-Z]{4}[0-9]{21}$/', - 'PT' => '/^PT[0-9]{2}[0-9]{8}[0-9]{13}$/', - 'RO' => '/^RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}$/', - 'RS' => '/^RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/', - 'SA' => '/^SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}$/', - 'SE' => '/^SE[0-9]{2}[0-9]{3}[0-9]{17}$/', - 'SI' => '/^SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}$/', - 'SK' => '/^SK[0-9]{2}[0-9]{4}[0-9]{16}$/', - 'SM' => '/^SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}$/', - 'TN' => '/^TN[0-9]{2}[0-9]{5}[0-9]{15}$/', - 'TR' => '/^TR[0-9]{2}[0-9]{5}[A-Z0-9]{17}$/', - 'VG' => '/^VG[0-9]{2}[A-Z]{4}[0-9]{16}$/' - ); - - /** - * Sets validator options - * - * @param string|Zend_Config|Zend_Locale $locale OPTIONAL - */ - public function __construct($locale = null) - { - if ($locale instanceof Zend_Config) { - $locale = $locale->toArray(); - } - - if (is_array($locale)) { - if (array_key_exists('locale', $locale)) { - $locale = $locale['locale']; - } else { - $locale = null; - } - } - - if (empty($locale)) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Locale')) { - $locale = Zend_Registry::get('Zend_Locale'); - } - } - - if ($locale !== null) { - $this->setLocale($locale); - } - } - - /** - * Returns the locale option - * - * @return string|Zend_Locale|null - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale option - * - * @param string|Zend_Locale $locale - * @throws Zend_Locale_Exception - * @throws Zend_Validate_Exception - * @return Zend_Validate_Date provides a fluent interface - */ - public function setLocale($locale = null) - { - if ($locale !== false) { - #require_once 'Zend/Locale.php'; - $locale = Zend_Locale::findLocale($locale); - if (strlen($locale) < 4) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Region must be given for IBAN validation'); - } - } - - $this->_locale = $locale; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if $value is a valid IBAN - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $value = strtoupper($value); - $this->_setValue($value); - - if (empty($this->_locale)) { - $region = substr($value, 0, 2); - } else { - $region = new Zend_Locale($this->_locale); - $region = $region->getRegion(); - } - - if (!array_key_exists($region, $this->_ibanregex)) { - $this->_setValue($region); - $this->_error(self::NOTSUPPORTED); - return false; - } - - if (!preg_match($this->_ibanregex[$region], $value)) { - $this->_error(self::FALSEFORMAT); - return false; - } - - $format = substr($value, 4) . substr($value, 0, 4); - $format = str_replace( - array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'), - array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', - '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'), - $format); - - $temp = intval(substr($format, 0, 1)); - $len = strlen($format); - for ($x = 1; $x < $len; ++$x) { - $temp *= 10; - $temp += intval(substr($format, $x, 1)); - $temp %= 97; - } - - if ($temp != 1) { - $this->_error(self::CHECKFAILED); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Identical.php b/lib/Zend/Validate/Identical.php deleted file mode 100644 index cc4d119d304..00000000000 --- a/lib/Zend/Validate/Identical.php +++ /dev/null @@ -1,164 +0,0 @@ - "The two given tokens do not match", - self::MISSING_TOKEN => 'No token was provided to match against', - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'token' => '_tokenString' - ); - - /** - * Original token against which to validate - * @var string - */ - protected $_tokenString; - protected $_token; - protected $_strict = true; - - /** - * Sets validator options - * - * @param mixed $token - */ - public function __construct($token = null) - { - if ($token instanceof Zend_Config) { - $token = $token->toArray(); - } - - if (is_array($token) && array_key_exists('token', $token)) { - if (array_key_exists('strict', $token)) { - $this->setStrict($token['strict']); - } - - $this->setToken($token['token']); - } else if (null !== $token) { - $this->setToken($token); - } - } - - /** - * Retrieve token - * - * @return string - */ - public function getToken() - { - return $this->_token; - } - - /** - * Set token against which to compare - * - * @param mixed $token - * @return Zend_Validate_Identical - */ - public function setToken($token) - { - $this->_tokenString = $token; - $this->_token = $token; - return $this; - } - - /** - * Returns the strict parameter - * - * @return boolean - */ - public function getStrict() - { - return $this->_strict; - } - - /** - * Sets the strict parameter - * - * @param Zend_Validate_Identical - * @return $this - */ - public function setStrict($strict) - { - $this->_strict = (boolean) $strict; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if a token has been set and the provided value - * matches that token. - * - * @param mixed $value - * @param array $context - * @return boolean - */ - public function isValid($value, $context = null) - { - $this->_setValue($value); - - if (($context !== null) && isset($context) && array_key_exists($this->getToken(), $context)) { - $token = $context[$this->getToken()]; - } else { - $token = $this->getToken(); - } - - if ($token === null) { - $this->_error(self::MISSING_TOKEN); - return false; - } - - $strict = $this->getStrict(); - if (($strict && ($value !== $token)) || (!$strict && ($value != $token))) { - $this->_error(self::NOT_SAME); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/InArray.php b/lib/Zend/Validate/InArray.php deleted file mode 100644 index e81e863d397..00000000000 --- a/lib/Zend/Validate/InArray.php +++ /dev/null @@ -1,204 +0,0 @@ - "'%value%' was not found in the haystack", - ); - - /** - * Haystack of possible values - * - * @var array - */ - protected $_haystack; - - /** - * Whether a strict in_array() invocation is used - * - * @var boolean - */ - protected $_strict = false; - - /** - * Whether a recursive search should be done - * - * @var boolean - */ - protected $_recursive = false; - - /** - * Sets validator options - * - * @param array|Zend_Config $options Validator options - * @throws Zend_Validate_Exception - */ - public function __construct($options) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Array expected as parameter'); - } else { - $count = func_num_args(); - $temp = array(); - if ($count > 1) { - $temp['haystack'] = func_get_arg(0); - $temp['strict'] = func_get_arg(1); - $options = $temp; - } else { - $temp = func_get_arg(0); - if (!array_key_exists('haystack', $options)) { - $options = array(); - $options['haystack'] = $temp; - } else { - $options = $temp; - } - } - } - - $this->setHaystack($options['haystack']); - if (array_key_exists('strict', $options)) { - $this->setStrict($options['strict']); - } - - if (array_key_exists('recursive', $options)) { - $this->setRecursive($options['recursive']); - } - } - - /** - * Returns the haystack option - * - * @return mixed - */ - public function getHaystack() - { - return $this->_haystack; - } - - /** - * Sets the haystack option - * - * @param mixed $haystack - * @return Zend_Validate_InArray Provides a fluent interface - */ - public function setHaystack(array $haystack) - { - $this->_haystack = $haystack; - return $this; - } - - /** - * Returns the strict option - * - * @return boolean - */ - public function getStrict() - { - return $this->_strict; - } - - /** - * Sets the strict option - * - * @param boolean $strict - * @return Zend_Validate_InArray Provides a fluent interface - */ - public function setStrict($strict) - { - $this->_strict = (boolean) $strict; - return $this; - } - - /** - * Returns the recursive option - * - * @return boolean - */ - public function getRecursive() - { - return $this->_recursive; - } - - /** - * Sets the recursive option - * - * @param boolean $recursive - * @return Zend_Validate_InArray Provides a fluent interface - */ - public function setRecursive($recursive) - { - $this->_recursive = (boolean) $recursive; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is contained in the haystack option. If the strict - * option is true, then the type of $value is also checked. - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - if ($this->getRecursive()) { - $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($this->_haystack)); - foreach($iterator as $element) { - if ($this->_strict) { - if ($element === $value) { - return true; - } - } else if ($element == $value) { - return true; - } - } - } else { - if (in_array($value, $this->_haystack, $this->_strict)) { - return true; - } - } - - $this->_error(self::NOT_IN_ARRAY); - return false; - } -} diff --git a/lib/Zend/Validate/Int.php b/lib/Zend/Validate/Int.php deleted file mode 100644 index 413dd08e0ce..00000000000 --- a/lib/Zend/Validate/Int.php +++ /dev/null @@ -1,149 +0,0 @@ - "Invalid type given. String or integer expected", - self::NOT_INT => "'%value%' does not appear to be an integer", - ); - - protected $_locale; - - /** - * Constructor for the integer validator - * - * @param string|Zend_Config|Zend_Locale $locale - */ - public function __construct($locale = null) - { - if ($locale instanceof Zend_Config) { - $locale = $locale->toArray(); - } - - if (is_array($locale)) { - if (array_key_exists('locale', $locale)) { - $locale = $locale['locale']; - } else { - $locale = null; - } - } - - if (empty($locale)) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Locale')) { - $locale = Zend_Registry::get('Zend_Locale'); - } - } - - if ($locale !== null) { - $this->setLocale($locale); - } - } - - /** - * Returns the set locale - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale to use - * - * @param string|Zend_Locale $locale - * @return $this - */ - public function setLocale($locale = null) - { - #require_once 'Zend/Locale.php'; - $this->_locale = Zend_Locale::findLocale($locale); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid integer - * - * @param string|integer $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->_error(self::INVALID); - return false; - } - - if (is_int($value)) { - return true; - } - - $this->_setValue($value); - if ($this->_locale === null) { - $locale = localeconv(); - $valueFiltered = str_replace($locale['decimal_point'], '.', $value); - $valueFiltered = str_replace($locale['thousands_sep'], '', $valueFiltered); - - if (strval(intval($valueFiltered)) != $valueFiltered) { - $this->_error(self::NOT_INT); - return false; - } - - } else { - try { - if (!Zend_Locale_Format::isInteger($value, array('locale' => $this->_locale))) { - $this->_error(self::NOT_INT); - return false; - } - } catch (Zend_Locale_Exception $e) { - $this->_error(self::NOT_INT); - return false; - } - } - - return true; - } -} diff --git a/lib/Zend/Validate/Interface.php b/lib/Zend/Validate/Interface.php deleted file mode 100644 index f1d0883c305..00000000000 --- a/lib/Zend/Validate/Interface.php +++ /dev/null @@ -1,54 +0,0 @@ - "Invalid type given. String expected", - self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address", - ); - - /** - * internal options - * - * @var array - */ - protected $_options = array( - 'allowipv6' => true, - 'allowipv4' => true - ); - - /** - * Sets validator options - * - * @param array $options OPTIONAL Options to set, see the manual for all available options - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['allowipv6'] = array_shift($options); - if (!empty($options)) { - $temp['allowipv4'] = array_shift($options); - } - - $options = $temp; - } - - $options += $this->_options; - $this->setOptions($options); - } - - /** - * Returns all set options - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Sets the options for this validator - * - * @param array $options - * @throws Zend_Validate_Exception - * @return Zend_Validate_Ip - */ - public function setOptions($options) - { - if (array_key_exists('allowipv6', $options)) { - $this->_options['allowipv6'] = (boolean) $options['allowipv6']; - } - - if (array_key_exists('allowipv4', $options)) { - $this->_options['allowipv4'] = (boolean) $options['allowipv4']; - } - - if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Nothing to validate. Check your options'); - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid IP address - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) || - (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) || - ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) { - $this->_error(self::NOT_IP_ADDRESS); - return false; - } - - return true; - } - - /** - * Validates an IPv4 address - * - * @param string $value - * @return bool - */ - protected function _validateIPv4($value) { - $ip2long = ip2long($value); - if($ip2long === false) { - return false; - } - - return $value == long2ip($ip2long); - } - - /** - * Validates an IPv6 address - * - * @param string $value Value to check against - * @return boolean True when $value is a valid ipv6 address - * False otherwise - */ - protected function _validateIPv6($value) { - if (strlen($value) < 3) { - return $value == '::'; - } - - if (strpos($value, '.')) { - $lastcolon = strrpos($value, ':'); - if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) { - return false; - } - - $value = substr($value, 0, $lastcolon) . ':0:0'; - } - - if (strpos($value, '::') === false) { - return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); - } - - $colonCount = substr_count($value, ':'); - if ($colonCount < 8) { - return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); - } - - // special case with ending or starting double colon - if ($colonCount == 8) { - return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); - } - - return false; - } -} diff --git a/lib/Zend/Validate/Isbn.php b/lib/Zend/Validate/Isbn.php deleted file mode 100644 index 9940e77ef2d..00000000000 --- a/lib/Zend/Validate/Isbn.php +++ /dev/null @@ -1,278 +0,0 @@ - "Invalid type given. String or integer expected", - self::NO_ISBN => "'%value%' is not a valid ISBN number", - ); - - /** - * Allowed type. - * - * @var string - */ - protected $_type = self::AUTO; - - /** - * Separator character. - * - * @var string - */ - protected $_separator = ''; - - /** - * Set up options. - * - * @param Zend_Config|array $options - * @throws Zend_Validate_Exception When $options is not valid - */ - public function __construct($options = array()) - { - // prepare options - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - if (!is_array($options)) { - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid options provided.'); - } - - // set type - if (array_key_exists('type', $options)) { - $this->setType($options['type']); - } - - // set separator - if (array_key_exists('separator', $options)) { - $this->setSeparator($options['separator']); - } - } - - /** - * Detect input format. - * - * @return string - */ - protected function _detectFormat() - { - // prepare separator and pattern list - $sep = quotemeta($this->_separator); - $patterns = array(); - $lengths = array(); - - // check for ISBN-10 - if ($this->_type == self::ISBN10 || $this->_type == self::AUTO) { - if (empty($sep)) { - $pattern = '/^[0-9]{9}[0-9X]{1}$/'; - $length = 10; - } else { - $pattern = "/^[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9X]{1}$/"; - $length = 13; - } - - $patterns[$pattern] = self::ISBN10; - $lengths[$pattern] = $length; - } - - // check for ISBN-13 - if ($this->_type == self::ISBN13 || $this->_type == self::AUTO) { - if (empty($sep)) { - $pattern = '/^[0-9]{13}$/'; - $length = 13; - } else { - $pattern = "/^[0-9]{1,9}[{$sep}]{1}[0-9]{1,5}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1}$/"; - $length = 17; - } - - $patterns[$pattern] = self::ISBN13; - $lengths[$pattern] = $length; - } - - // check pattern list - foreach ($patterns as $pattern => $type) { - if ((strlen($this->_value) == $lengths[$pattern]) && preg_match($pattern, $this->_value)) { - return $type; - } - } - - return null; - } - - /** - * Defined by Zend_Validate_Interface. - * - * Returns true if and only if $value is a valid ISBN. - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value)) { - $this->_error(self::INVALID); - return false; - } - - $value = (string) $value; - $this->_setValue($value); - - switch ($this->_detectFormat()) { - case self::ISBN10: - // sum - $isbn10 = str_replace($this->_separator, '', $value); - $sum = 0; - for ($i = 0; $i < 9; $i++) { - $sum += (10 - $i) * $isbn10[$i]; - } - - // checksum - $checksum = 11 - ($sum % 11); - if ($checksum == 11) { - $checksum = '0'; - } elseif ($checksum == 10) { - $checksum = 'X'; - } - break; - - case self::ISBN13: - // sum - $isbn13 = str_replace($this->_separator, '', $value); - $sum = 0; - for ($i = 0; $i < 12; $i++) { - if ($i % 2 == 0) { - $sum += $isbn13[$i]; - } else { - $sum += 3 * $isbn13[$i]; - } - } - // checksum - $checksum = 10 - ($sum % 10); - if ($checksum == 10) { - $checksum = '0'; - } - break; - - default: - $this->_error(self::NO_ISBN); - return false; - } - - // validate - if (substr($this->_value, -1) != $checksum) { - $this->_error(self::NO_ISBN); - return false; - } - return true; - } - - /** - * Set separator characters. - * - * It is allowed only empty string, hyphen and space. - * - * @param string $separator - * @throws Zend_Validate_Exception When $separator is not valid - * @return Zend_Validate_Isbn Provides a fluent interface - */ - public function setSeparator($separator) - { - // check separator - if (!in_array($separator, array('-', ' ', ''))) { - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid ISBN separator.'); - } - - $this->_separator = $separator; - return $this; - } - - /** - * Get separator characters. - * - * @return string - */ - public function getSeparator() - { - return $this->_separator; - } - - /** - * Set allowed ISBN type. - * - * @param string $type - * @throws Zend_Validate_Exception When $type is not valid - * @return Zend_Validate_Isbn Provides a fluent interface - */ - public function setType($type) - { - // check type - if (!in_array($type, array(self::AUTO, self::ISBN10, self::ISBN13))) { - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid ISBN type'); - } - - $this->_type = $type; - return $this; - } - - /** - * Get allowed ISBN type. - * - * @return string - */ - public function getType() - { - return $this->_type; - } -} diff --git a/lib/Zend/Validate/Ldap/Dn.php b/lib/Zend/Validate/Ldap/Dn.php deleted file mode 100644 index 892b011f14f..00000000000 --- a/lib/Zend/Validate/Ldap/Dn.php +++ /dev/null @@ -1,65 +0,0 @@ - 'DN is malformed', - ); - - /** - * Defined by Zend_Validate_Interface. - * - * Returns true if and only if $value is a valid DN. - * - * @param string $value The value to be validated. - * - * @return boolean - */ - public function isValid($value) - { - $valid = Zend_Ldap_Dn::checkDn($value); - if ($valid === false) { - $this->_error(self::MALFORMED); - return false; - } - return true; - } -} diff --git a/lib/Zend/Validate/LessThan.php b/lib/Zend/Validate/LessThan.php deleted file mode 100644 index 72dee40c975..00000000000 --- a/lib/Zend/Validate/LessThan.php +++ /dev/null @@ -1,122 +0,0 @@ - "'%value%' is not less than '%max%'" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'max' => '_max' - ); - - /** - * Maximum value - * - * @var mixed - */ - protected $_max; - - /** - * Sets validator options - * - * @param mixed|Zend_Config $max - * @throws Zend_Validate_Exception - */ - public function __construct($max) - { - if ($max instanceof Zend_Config) { - $max = $max->toArray(); - } - - if (is_array($max)) { - if (array_key_exists('max', $max)) { - $max = $max['max']; - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Missing option 'max'"); - } - } - - $this->setMax($max); - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param mixed $max - * @return Zend_Validate_LessThan Provides a fluent interface - */ - public function setMax($max) - { - $this->_max = $max; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is less than max option - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - if ($this->_max <= $value) { - $this->_error(self::NOT_LESS); - return false; - } - return true; - } - -} diff --git a/lib/Zend/Validate/NotEmpty.php b/lib/Zend/Validate/NotEmpty.php deleted file mode 100644 index 2995fd9e718..00000000000 --- a/lib/Zend/Validate/NotEmpty.php +++ /dev/null @@ -1,279 +0,0 @@ - 'boolean', - self::INTEGER => 'integer', - self::FLOAT => 'float', - self::STRING => 'string', - self::ZERO => 'zero', - self::EMPTY_ARRAY => 'array', - self::NULL => 'null', - self::PHP => 'php', - self::SPACE => 'space', - self::OBJECT => 'object', - self::OBJECT_STRING => 'objectstring', - self::OBJECT_COUNT => 'objectcount', - self::ALL => 'all', - ); - - /** - * @var array - */ - protected $_messageTemplates = array( - self::IS_EMPTY => "Value is required and can't be empty", - self::INVALID => "Invalid type given. String, integer, float, boolean or array expected", - ); - - /** - * Internal type to detect - * - * @var integer - */ - protected $_type = 493; - - /** - * Constructor - * - * @param string|array|Zend_Config $options OPTIONAL - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp = array(); - if (!empty($options)) { - $temp['type'] = array_shift($options); - } - - $options = $temp; - } - - if (is_array($options) && array_key_exists('type', $options)) { - $this->setType($options['type']); - } - } - - /** - * Returns the set types - * - * @return array - */ - public function getType() - { - return $this->_type; - } - - /** - * Set the types - * - * @param integer|array $type - * @throws Zend_Validate_Exception - * @return Zend_Validate_NotEmpty - */ - public function setType($type = null) - { - if (is_array($type)) { - $detected = 0; - foreach($type as $value) { - if (is_int($value)) { - $detected += $value; - } else if (in_array($value, $this->_constants)) { - $detected += array_search($value, $this->_constants); - } - } - - $type = $detected; - } else if (is_string($type) && in_array($type, $this->_constants)) { - $type = array_search($type, $this->_constants); - } - - if (!is_int($type) || ($type < 0) || ($type > self::ALL)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Unknown type'); - } - - $this->_type = $type; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is not an empty value. - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if ($value !== null && !is_string($value) && !is_int($value) && !is_float($value) && - !is_bool($value) && !is_array($value) && !is_object($value)) { - $this->_error(self::INVALID); - return false; - } - - $type = $this->getType(); - $this->_setValue($value); - $object = false; - - // OBJECT_COUNT (countable object) - if ($type >= self::OBJECT_COUNT) { - $type -= self::OBJECT_COUNT; - $object = true; - - if (is_object($value) && ($value instanceof Countable) && (count($value) == 0)) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // OBJECT_STRING (object's toString) - if ($type >= self::OBJECT_STRING) { - $type -= self::OBJECT_STRING; - $object = true; - - if ((is_object($value) && (!method_exists($value, '__toString'))) || - (is_object($value) && (method_exists($value, '__toString')) && (((string) $value) == ""))) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // OBJECT (object) - if ($type >= self::OBJECT) { - $type -= self::OBJECT; - // fall trough, objects are always not empty - } else if ($object === false) { - // object not allowed but object given -> return false - if (is_object($value)) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // SPACE (' ') - if ($type >= self::SPACE) { - $type -= self::SPACE; - if (is_string($value) && (preg_match('/^\s+$/s', $value))) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // NULL (null) - if ($type >= self::NULL) { - $type -= self::NULL; - if ($value === null) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // EMPTY_ARRAY (array()) - if ($type >= self::EMPTY_ARRAY) { - $type -= self::EMPTY_ARRAY; - if (is_array($value) && ($value == array())) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // ZERO ('0') - if ($type >= self::ZERO) { - $type -= self::ZERO; - if (is_string($value) && ($value == '0')) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // STRING ('') - if ($type >= self::STRING) { - $type -= self::STRING; - if (is_string($value) && ($value == '')) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // FLOAT (0.0) - if ($type >= self::FLOAT) { - $type -= self::FLOAT; - if (is_float($value) && ($value == 0.0)) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // INTEGER (0) - if ($type >= self::INTEGER) { - $type -= self::INTEGER; - if (is_int($value) && ($value == 0)) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - // BOOLEAN (false) - if ($type >= self::BOOLEAN) { - $type -= self::BOOLEAN; - if (is_bool($value) && ($value == false)) { - $this->_error(self::IS_EMPTY); - return false; - } - } - - return true; - } -} diff --git a/lib/Zend/Validate/PostCode.php b/lib/Zend/Validate/PostCode.php deleted file mode 100644 index c5f48615a2e..00000000000 --- a/lib/Zend/Validate/PostCode.php +++ /dev/null @@ -1,210 +0,0 @@ - "Invalid type given. String or integer expected", - self::NO_MATCH => "'%value%' does not appear to be a postal code", - ); - - /** - * Locale to use - * - * @var string - */ - protected $_locale; - - /** - * Manual postal code format - * - * @var unknown_type - */ - protected $_format; - - /** - * Constructor for the integer validator - * - * Accepts either a string locale, a Zend_Locale object, or an array or - * Zend_Config object containing the keys "locale" and/or "format". - * - * @param string|Zend_Locale|array|Zend_Config $options - * @throws Zend_Validate_Exception On empty format - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } - - if (empty($options)) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Locale')) { - $this->setLocale(Zend_Registry::get('Zend_Locale')); - } - } elseif (is_array($options)) { - // Received - if (array_key_exists('locale', $options)) { - $this->setLocale($options['locale']); - } - - if (array_key_exists('format', $options)) { - $this->setFormat($options['format']); - } - } elseif ($options instanceof Zend_Locale || is_string($options)) { - // Received Locale object or string locale - $this->setLocale($options); - } - - $format = $this->getFormat(); - if (empty($format)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("A postcode-format string has to be given for validation"); - } - } - - /** - * Returns the set locale - * - * @return string|Zend_Locale The set locale - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale to use - * - * @param string|Zend_Locale $locale - * @throws Zend_Validate_Exception On unrecognised region - * @throws Zend_Validate_Exception On not detected format - * @return Zend_Validate_PostCode Provides a fluent interface - */ - public function setLocale($locale = null) - { - #require_once 'Zend/Locale.php'; - $this->_locale = Zend_Locale::findLocale($locale); - $locale = new Zend_Locale($this->_locale); - $region = $locale->getRegion(); - if (empty($region)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Unable to detect a region for the locale '$locale'"); - } - - $format = Zend_Locale::getTranslation( - $locale->getRegion(), - 'postaltoterritory', - $this->_locale - ); - - if (empty($format)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Unable to detect a postcode format for the region '{$locale->getRegion()}'"); - } - - $this->setFormat($format); - return $this; - } - - /** - * Returns the set postal code format - * - * @return string - */ - public function getFormat() - { - return $this->_format; - } - - /** - * Sets a self defined postal format as regex - * - * @param string $format - * @throws Zend_Validate_Exception On empty format - * @return Zend_Validate_PostCode Provides a fluent interface - */ - public function setFormat($format) - { - if (empty($format) || !is_string($format)) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("A postcode-format string has to be given for validation"); - } - - if ($format[0] !== '/') { - $format = '/^' . $format; - } - - if ($format[strlen($format) - 1] !== '/') { - $format .= '$/'; - } - - $this->_format = $format; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid postalcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - if (!is_string($value) && !is_int($value)) { - $this->_error(self::INVALID); - return false; - } - - $format = $this->getFormat(); - if (!preg_match($format, $value)) { - $this->_error(self::NO_MATCH); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Regex.php b/lib/Zend/Validate/Regex.php deleted file mode 100644 index aceaf961612..00000000000 --- a/lib/Zend/Validate/Regex.php +++ /dev/null @@ -1,146 +0,0 @@ - "Invalid type given. String, integer or float expected", - self::NOT_MATCH => "'%value%' does not match against pattern '%pattern%'", - self::ERROROUS => "There was an internal error while using the pattern '%pattern%'", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'pattern' => '_pattern' - ); - - /** - * Regular expression pattern - * - * @var string - */ - protected $_pattern; - - /** - * Sets validator options - * - * @param string|Zend_Config $pattern - * @throws Zend_Validate_Exception On missing 'pattern' parameter - */ - public function __construct($pattern) - { - if ($pattern instanceof Zend_Config) { - $pattern = $pattern->toArray(); - } - - if (is_array($pattern)) { - if (array_key_exists('pattern', $pattern)) { - $pattern = $pattern['pattern']; - } else { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Missing option 'pattern'"); - } - } - - $this->setPattern($pattern); - } - - /** - * Returns the pattern option - * - * @return string - */ - public function getPattern() - { - return $this->_pattern; - } - - /** - * Sets the pattern option - * - * @param string $pattern - * @throws Zend_Validate_Exception if there is a fatal error in pattern matching - * @return Zend_Validate_Regex Provides a fluent interface - */ - public function setPattern($pattern) - { - $this->_pattern = (string) $pattern; - $status = @preg_match($this->_pattern, "Test"); - - if (false === $status) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Internal error while using the pattern '$this->_pattern'"); - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value matches against the pattern option - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - - $status = @preg_match($this->_pattern, $value); - if (false === $status) { - $this->_error(self::ERROROUS); - return false; - } - - if (!$status) { - $this->_error(self::NOT_MATCH); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Sitemap/Changefreq.php b/lib/Zend/Validate/Sitemap/Changefreq.php deleted file mode 100644 index bf9a719af86..00000000000 --- a/lib/Zend/Validate/Sitemap/Changefreq.php +++ /dev/null @@ -1,95 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - * - * @category Zend - * @package Zend_Validate - * @subpackage Sitemap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Validate_Sitemap_Changefreq extends Zend_Validate_Abstract -{ - /** - * Validation key for not valid - * - */ - const NOT_VALID = 'sitemapChangefreqNotValid'; - const INVALID = 'sitemapChangefreqInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $_messageTemplates = array( - self::NOT_VALID => "'%value%' is not a valid sitemap changefreq", - self::INVALID => "Invalid type given. String expected", - ); - - /** - * Valid change frequencies - * - * @var array - */ - protected $_changeFreqs = array( - 'always', 'hourly', 'daily', 'weekly', - 'monthly', 'yearly', 'never' - ); - - /** - * Validates if a string is valid as a sitemap changefreq - * - * @link http://www.sitemaps.org/protocol.php#changefreqdef - * - * @param string $value value to validate - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - if (!is_string($value)) { - return false; - } - - if (!in_array($value, $this->_changeFreqs, true)) { - $this->_error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Sitemap/Lastmod.php b/lib/Zend/Validate/Sitemap/Lastmod.php deleted file mode 100644 index 7ae3845aa13..00000000000 --- a/lib/Zend/Validate/Sitemap/Lastmod.php +++ /dev/null @@ -1,88 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - * - * @category Zend - * @package Zend_Validate - * @subpackage Sitemap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Validate_Sitemap_Lastmod extends Zend_Validate_Abstract -{ - /** - * Regular expression to use when validating - * - */ - const LASTMOD_REGEX = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])(T([0-1][0-9]|2[0-3])(:[0-5][0-9])(:[0-5][0-9])?(\\+|-)([0-1][0-9]|2[0-3]):[0-5][0-9])?$/'; - - /** - * Validation key for not valid - * - */ - const NOT_VALID = 'sitemapLastmodNotValid'; - const INVALID = 'sitemapLastmodInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $_messageTemplates = array( - self::NOT_VALID => "'%value%' is not a valid sitemap lastmod", - self::INVALID => "Invalid type given. String expected", - ); - - /** - * Validates if a string is valid as a sitemap lastmod - * - * @link http://www.sitemaps.org/protocol.php#lastmoddef - * - * @param string $value value to validate - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - $result = @preg_match(self::LASTMOD_REGEX, $value); - if ($result != 1) { - $this->_error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Sitemap/Loc.php b/lib/Zend/Validate/Sitemap/Loc.php deleted file mode 100644 index f8976955230..00000000000 --- a/lib/Zend/Validate/Sitemap/Loc.php +++ /dev/null @@ -1,87 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - * - * @category Zend - * @package Zend_Validate - * @subpackage Sitemap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Validate_Sitemap_Loc extends Zend_Validate_Abstract -{ - /** - * Validation key for not valid - * - */ - const NOT_VALID = 'sitemapLocNotValid'; - const INVALID = 'sitemapLocInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $_messageTemplates = array( - self::NOT_VALID => "'%value%' is not a valid sitemap location", - self::INVALID => "Invalid type given. String expected", - ); - - /** - * Validates if a string is valid as a sitemap location - * - * @link http://www.sitemaps.org/protocol.php#locdef - * - * @param string $value value to validate - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - $result = Zend_Uri::check($value); - if ($result !== true) { - $this->_error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/Sitemap/Priority.php b/lib/Zend/Validate/Sitemap/Priority.php deleted file mode 100644 index e6c9724784d..00000000000 --- a/lib/Zend/Validate/Sitemap/Priority.php +++ /dev/null @@ -1,82 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - * - * @category Zend - * @package Zend_Validate - * @subpackage Sitemap - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_Validate_Sitemap_Priority extends Zend_Validate_Abstract -{ - /** - * Validation key for not valid - * - */ - const NOT_VALID = 'sitemapPriorityNotValid'; - const INVALID = 'sitemapPriorityInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $_messageTemplates = array( - self::NOT_VALID => "'%value%' is not a valid sitemap priority", - self::INVALID => "Invalid type given. Numeric string, integer or float expected", - ); - - /** - * Validates if a string is valid as a sitemap priority - * - * @link http://www.sitemaps.org/protocol.php#prioritydef - * - * @param string $value value to validate - * @return boolean - */ - public function isValid($value) - { - if (!is_numeric($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - $value = (float) $value; - if ($value < 0 || $value > 1) { - $this->_error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/Zend/Validate/StringLength.php b/lib/Zend/Validate/StringLength.php deleted file mode 100644 index 1e268956615..00000000000 --- a/lib/Zend/Validate/StringLength.php +++ /dev/null @@ -1,263 +0,0 @@ - "Invalid type given. String expected", - self::TOO_SHORT => "'%value%' is less than %min% characters long", - self::TOO_LONG => "'%value%' is more than %max% characters long", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum length - * - * @var integer - */ - protected $_min; - - /** - * Maximum length - * - * If null, there is no maximum length - * - * @var integer|null - */ - protected $_max; - - /** - * Encoding to use - * - * @var string|null - */ - protected $_encoding; - - /** - * Sets validator options - * - * @param integer|array|Zend_Config $options - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['min'] = array_shift($options); - if (!empty($options)) { - $temp['max'] = array_shift($options); - } - - if (!empty($options)) { - $temp['encoding'] = array_shift($options); - } - - $options = $temp; - } - - if (!array_key_exists('min', $options)) { - $options['min'] = 0; - } - - $this->setMin($options['min']); - if (array_key_exists('max', $options)) { - $this->setMax($options['max']); - } - - if (array_key_exists('encoding', $options)) { - $this->setEncoding($options['encoding']); - } - } - - /** - * Returns the min option - * - * @return integer - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param integer $min - * @throws Zend_Validate_Exception - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMin($min) - { - if (null !== $this->_max && $min > $this->_max) { - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum length, but $min >" - . " $this->_max"); - } - $this->_min = max(0, (integer) $min); - return $this; - } - - /** - * Returns the max option - * - * @return integer|null - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param integer|null $max - * @throws Zend_Validate_Exception - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMax($max) - { - if (null === $max) { - $this->_max = null; - } else if ($max < $this->_min) { - /** - * @see Zend_Validate_Exception - */ - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum length, but " - . "$max < $this->_min"); - } else { - $this->_max = (integer) $max; - } - - return $this; - } - - /** - * Returns the actual encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Sets a new encoding to use - * - * @param string $encoding - * @throws Zend_Validate_Exception - * @return Zend_Validate_StringLength - */ - public function setEncoding($encoding = null) - { - if ($encoding !== null) { - $orig = PHP_VERSION_ID < 50600 - ? iconv_get_encoding('internal_encoding') - : ini_get('default_charset'); - if (PHP_VERSION_ID < 50600) { - $result = iconv_set_encoding('internal_encoding', $encoding); - } else { - $result = ini_set('default_charset', $encoding); - } - if (!$result) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Given encoding not supported on this OS!'); - } - - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('internal_encoding', $orig); - } else { - ini_set('default_charset', $orig); - } - } - - $this->_encoding = $encoding; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the string length of $value is at least the min option and - * no greater than the max option (when the max option is not null). - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - if ($this->_encoding !== null) { - $length = iconv_strlen($value, $this->_encoding); - } else { - $length = iconv_strlen($value); - } - - if ($length < $this->_min) { - $this->_error(self::TOO_SHORT); - } - - if (null !== $this->_max && $this->_max < $length) { - $this->_error(self::TOO_LONG); - } - - if (count($this->_messages)) { - return false; - } else { - return true; - } - } -} diff --git a/lib/Zend/Version.php b/lib/Zend/Version.php deleted file mode 100644 index a5f244f711e..00000000000 --- a/lib/Zend/Version.php +++ /dev/null @@ -1,81 +0,0 @@ -\n") - * @method string formNote($name, $value = null) - * @method string formPassword($name, $value = null, $attribs = null) - * @method string formRadio($name, $value = null, $attribs = null, $options = null, $listsep = "
\n") - * @method string formReset($name = '', $value = 'Reset', $attribs = null) - * @method string formSelect($name, $value = null, $attribs = null, $options = null, $listsep = "
\n") - * @method string formSubmit($name, $value = null, $attribs = null) - * @method string formText($name, $value = null, $attribs = null) - * @method string formTextarea($name, $value = null, $attribs = null) - * @method Zend_View_Helper_Gravatar gravatar($email = "", $options = array(), $attribs = array()) - * @method Zend_View_Helper_HeadLink headLink(array $attributes = null, $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) - * @method Zend_View_Helper_HeadMeta headMeta($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) - * @method Zend_View_Helper_HeadScript headScript($mode = Zend_View_Helper_HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') - * @method Zend_View_Helper_HeadStyle headStyle($content = null, $placement = 'APPEND', $attributes = array()) - * @method Zend_View_Helper_HeadTitle headTitle($title = null, $setType = null) - * @method string htmlFlash($data, array $attribs = array(), array $params = array(), $content = null) - * @method string htmlList(array $items, $ordered = false, $attribs = false, $escape = true) - * @method string htmlObject($data, $type, array $attribs = array(), array $params = array(), $content = null) - * @method string htmlPage($data, array $attribs = array(), array $params = array(), $content = null) - * @method string htmlQuicktime($data, array $attribs = array(), array $params = array(), $content = null) - * @method Zend_View_Helper_InlineScript inlineScript($mode = Zend_View_Helper_HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') - * @method string|void json($data, $keepLayouts = false, $encodeData = true) - * @method Zend_View_Helper_Layout layout() - * @method Zend_View_Helper_Navigation navigation(Zend_Navigation_Container $container = null) - * @method string paginationControl(Zend_Paginator $paginator = null, $scrollingStyle = null, $partial = null, $params = null) - * @method string partial($name = null, $module = null, $model = null) - * @method string partialLoop($name = null, $module = null, $model = null) - * @method Zend_View_Helper_Placeholder_Container_Abstract placeholder($name) - * @method void renderToPlaceholder($script, $placeholder) - * @method string serverUrl($requestUri = null) - * @method string translate($messageid = null) - * @method string url(array $urlOptions = array(), $name = null, $reset = false, $encode = true) - * @method Zend_Http_UserAgent userAgent(Zend_Http_UserAgent $userAgent = null) - */ -class Zend_View extends Zend_View_Abstract -{ - /** - * Whether or not to use streams to mimic short tags - * @var bool - */ - private $_useViewStream = false; - - /** - * Whether or not to use stream wrapper if short_open_tag is false - * @var bool - */ - private $_useStreamWrapper = false; - - /** - * Constructor - * - * Register Zend_View_Stream stream wrapper if short tags are disabled. - * - * @param array $config - * @return void - */ - public function __construct($config = array()) - { - $this->_useViewStream = (bool) ini_get('short_open_tag') ? false : true; - if ($this->_useViewStream) { - if (!in_array('zend.view', stream_get_wrappers())) { - #require_once 'Zend/View/Stream.php'; - stream_wrapper_register('zend.view', 'Zend_View_Stream'); - } - } - - if (array_key_exists('useStreamWrapper', $config)) { - $this->setUseStreamWrapper($config['useStreamWrapper']); - } - - parent::__construct($config); - } - - /** - * Set flag indicating if stream wrapper should be used if short_open_tag is off - * - * @param bool $flag - * @return Zend_View - */ - public function setUseStreamWrapper($flag) - { - $this->_useStreamWrapper = (bool) $flag; - return $this; - } - - /** - * Should the stream wrapper be used if short_open_tag is off? - * - * @return bool - */ - public function useStreamWrapper() - { - return $this->_useStreamWrapper; - } - - /** - * Includes the view script in a scope with only public $this variables. - * - * @param string The view script to execute. - */ - protected function _run() - { - if ($this->_useViewStream && $this->useStreamWrapper()) { - include 'zend.view://' . func_get_arg(0); - } else { - include func_get_arg(0); - } - } -} diff --git a/lib/Zend/View/Abstract.php b/lib/Zend/View/Abstract.php deleted file mode 100644 index e36c0f8a174..00000000000 --- a/lib/Zend/View/Abstract.php +++ /dev/null @@ -1,1200 +0,0 @@ - array(), - 'helper' => array(), - 'filter' => array(), - ); - - /** - * Script file name to execute - * - * @var string - */ - private $_file = null; - - /** - * Instances of helper objects. - * - * @var array - */ - private $_helper = array(); - - /** - * Map of helper => class pairs to help in determining helper class from - * name - * @var array - */ - private $_helperLoaded = array(); - - /** - * Map of helper => classfile pairs to aid in determining helper classfile - * @var array - */ - private $_helperLoadedDir = array(); - - /** - * Stack of Zend_View_Filter names to apply as filters. - * @var array - */ - private $_filter = array(); - - /** - * Stack of Zend_View_Filter objects that have been loaded - * @var array - */ - private $_filterClass = array(); - - /** - * Map of filter => class pairs to help in determining filter class from - * name - * @var array - */ - private $_filterLoaded = array(); - - /** - * Map of filter => classfile pairs to aid in determining filter classfile - * @var array - */ - private $_filterLoadedDir = array(); - - /** - * Callback for escaping. - * - * @var string - */ - private $_escape = 'htmlspecialchars'; - - /** - * Encoding to use in escaping mechanisms; defaults to utf-8 - * @var string - */ - private $_encoding = 'UTF-8'; - - /** - * Flag indicating whether or not LFI protection for rendering view scripts is enabled - * @var bool - */ - private $_lfiProtectionOn = true; - - /** - * Plugin loaders - * @var array - */ - private $_loaders = array(); - - /** - * Plugin types - * @var array - */ - private $_loaderTypes = array('filter', 'helper'); - - /** - * Strict variables flag; when on, undefined variables accessed in the view - * scripts will trigger notices - * @var boolean - */ - private $_strictVars = false; - - /** - * Constructor. - * - * @param array $config Configuration key-value pairs. - */ - public function __construct($config = array()) - { - // set inital paths and properties - $this->setScriptPath(null); - - // $this->setHelperPath(null); - $this->setFilterPath(null); - - // user-defined escaping callback - if (array_key_exists('escape', $config)) { - $this->setEscape($config['escape']); - } - - // encoding - if (array_key_exists('encoding', $config)) { - $this->setEncoding($config['encoding']); - } - - // base path - if (array_key_exists('basePath', $config)) { - $prefix = 'Zend_View'; - if (array_key_exists('basePathPrefix', $config)) { - $prefix = $config['basePathPrefix']; - } - $this->setBasePath($config['basePath'], $prefix); - } - - // user-defined view script path - if (array_key_exists('scriptPath', $config)) { - $this->addScriptPath($config['scriptPath']); - } - - // user-defined helper path - if (array_key_exists('helperPath', $config)) { - if (is_array($config['helperPath'])) { - foreach ($config['helperPath'] as $prefix => $path) { - $this->addHelperPath($path, $prefix); - } - } else { - $prefix = 'Zend_View_Helper'; - if (array_key_exists('helperPathPrefix', $config)) { - $prefix = $config['helperPathPrefix']; - } - $this->addHelperPath($config['helperPath'], $prefix); - } - } - - // user-defined filter path - if (array_key_exists('filterPath', $config)) { - if (is_array($config['filterPath'])) { - foreach ($config['filterPath'] as $prefix => $path) { - $this->addFilterPath($path, $prefix); - } - } else { - $prefix = 'Zend_View_Filter'; - if (array_key_exists('filterPathPrefix', $config)) { - $prefix = $config['filterPathPrefix']; - } - $this->addFilterPath($config['filterPath'], $prefix); - } - } - - // user-defined filters - if (array_key_exists('filter', $config)) { - $this->addFilter($config['filter']); - } - - // strict vars - if (array_key_exists('strictVars', $config)) { - $this->strictVars($config['strictVars']); - } - - // LFI protection flag - if (array_key_exists('lfiProtectionOn', $config)) { - $this->setLfiProtection($config['lfiProtectionOn']); - } - - if (array_key_exists('assign', $config) - && is_array($config['assign']) - ) { - foreach ($config['assign'] as $key => $value) { - $this->assign($key, $value); - } - } - - $this->init(); - } - - /** - * Return the template engine object - * - * Returns the object instance, as it is its own template engine - * - * @return Zend_View_Abstract - */ - public function getEngine() - { - return $this; - } - - /** - * Allow custom object initialization when extending Zend_View_Abstract or - * Zend_View - * - * Triggered by {@link __construct() the constructor} as its final action. - * - * @return void - */ - public function init() - { - } - - /** - * Prevent E_NOTICE for nonexistent values - * - * If {@link strictVars()} is on, raises a notice. - * - * @param string $key - * @return null - */ - public function __get($key) - { - if ($this->_strictVars) { - trigger_error('Key "' . $key . '" does not exist', E_USER_NOTICE); - } - - return null; - } - - /** - * Allows testing with empty() and isset() to work inside - * templates. - * - * @param string $key - * @return boolean - */ - public function __isset($key) - { - if ('_' != substr($key, 0, 1)) { - return isset($this->$key); - } - - return false; - } - - /** - * Directly assigns a variable to the view script. - * - * Checks first to ensure that the caller is not attempting to set a - * protected or private member (by checking for a prefixed underscore); if - * not, the public member is set; otherwise, an exception is raised. - * - * @param string $key The variable name. - * @param mixed $val The variable value. - * @return void - * @throws Zend_View_Exception if an attempt to set a private or protected - * member is detected - */ - public function __set($key, $val) - { - if ('_' != substr($key, 0, 1)) { - $this->$key = $val; - return; - } - - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Setting private or protected class members is not allowed'); - $e->setView($this); - throw $e; - } - - /** - * Allows unset() on object properties to work - * - * @param string $key - * @return void - */ - public function __unset($key) - { - if ('_' != substr($key, 0, 1) && isset($this->$key)) { - unset($this->$key); - } - } - - /** - * Accesses a helper object from within a script. - * - * If the helper class has a 'view' property, sets it with the current view - * object. - * - * @param string $name The helper name. - * @param array $args The parameters for the helper. - * @return string The result of the helper output. - */ - public function __call($name, $args) - { - // is the helper already loaded? - $helper = $this->getHelper($name); - - // call the helper method - return call_user_func_array( - array($helper, $name), - $args - ); - } - - /** - * Given a base path, sets the script, helper, and filter paths relative to it - * - * Assumes a directory structure of: - * - * basePath/ - * scripts/ - * helpers/ - * filters/ - * - * - * @param string $path - * @param string $prefix Prefix to use for helper and filter paths - * @return Zend_View_Abstract - */ - public function setBasePath($path, $classPrefix = 'Zend_View') - { - $path = rtrim($path, '/'); - $path = rtrim($path, '\\'); - $path .= DIRECTORY_SEPARATOR; - $classPrefix = rtrim($classPrefix, '_') . '_'; - $this->setScriptPath($path . 'scripts'); - $this->setHelperPath($path . 'helpers', $classPrefix . 'Helper'); - $this->setFilterPath($path . 'filters', $classPrefix . 'Filter'); - return $this; - } - - /** - * Given a base path, add script, helper, and filter paths relative to it - * - * Assumes a directory structure of: - * - * basePath/ - * scripts/ - * helpers/ - * filters/ - * - * - * @param string $path - * @param string $prefix Prefix to use for helper and filter paths - * @return Zend_View_Abstract - */ - public function addBasePath($path, $classPrefix = 'Zend_View') - { - $path = rtrim($path, '/'); - $path = rtrim($path, '\\'); - $path .= DIRECTORY_SEPARATOR; - $classPrefix = rtrim($classPrefix, '_') . '_'; - $this->addScriptPath($path . 'scripts'); - $this->addHelperPath($path . 'helpers', $classPrefix . 'Helper'); - $this->addFilterPath($path . 'filters', $classPrefix . 'Filter'); - return $this; - } - - /** - * Adds to the stack of view script paths in LIFO order. - * - * @param string|array The directory (-ies) to add. - * @return Zend_View_Abstract - */ - public function addScriptPath($path) - { - $this->_addPath('script', $path); - return $this; - } - - /** - * Resets the stack of view script paths. - * - * To clear all paths, use Zend_View::setScriptPath(null). - * - * @param string|array The directory (-ies) to set as the path. - * @return Zend_View_Abstract - */ - public function setScriptPath($path) - { - $this->_path['script'] = array(); - $this->_addPath('script', $path); - return $this; - } - - /** - * Return full path to a view script specified by $name - * - * @param string $name - * @return false|string False if script not found - * @throws Zend_View_Exception if no script directory set - */ - public function getScriptPath($name) - { - try { - $path = $this->_script($name); - return $path; - } catch (Zend_View_Exception $e) { - if (strstr($e->getMessage(), 'no view script directory set')) { - throw $e; - } - - return false; - } - } - - /** - * Returns an array of all currently set script paths - * - * @return array - */ - public function getScriptPaths() - { - return $this->_getPaths('script'); - } - - /** - * Set plugin loader for a particular plugin type - * - * @param Zend_Loader_PluginLoader $loader - * @param string $type - * @return Zend_View_Abstract - */ - public function setPluginLoader(Zend_Loader_PluginLoader $loader, $type) - { - $type = strtolower($type); - if (!in_array($type, $this->_loaderTypes)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Invalid plugin loader type "%s"', $type)); - $e->setView($this); - throw $e; - } - - $this->_loaders[$type] = $loader; - return $this; - } - - /** - * Retrieve plugin loader for a specific plugin type - * - * @param string $type - * @return Zend_Loader_PluginLoader - */ - public function getPluginLoader($type) - { - $type = strtolower($type); - if (!in_array($type, $this->_loaderTypes)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Invalid plugin loader type "%s"; cannot retrieve', $type)); - $e->setView($this); - throw $e; - } - - if (!array_key_exists($type, $this->_loaders)) { - $prefix = 'Zend_View_'; - $pathPrefix = 'Zend/View/'; - - $pType = ucfirst($type); - switch ($type) { - case 'filter': - case 'helper': - default: - $prefix .= $pType; - $pathPrefix .= $pType; - $loader = new Zend_Loader_PluginLoader(array( - $prefix => $pathPrefix - )); - $this->_loaders[$type] = $loader; - break; - } - } - return $this->_loaders[$type]; - } - - /** - * Adds to the stack of helper paths in LIFO order. - * - * @param string|array The directory (-ies) to add. - * @param string $classPrefix Class prefix to use with classes in this - * directory; defaults to Zend_View_Helper - * @return Zend_View_Abstract - */ - public function addHelperPath($path, $classPrefix = 'Zend_View_Helper_') - { - return $this->_addPluginPath('helper', $classPrefix, (array) $path); - } - - /** - * Resets the stack of helper paths. - * - * To clear all paths, use Zend_View::setHelperPath(null). - * - * @param string|array $path The directory (-ies) to set as the path. - * @param string $classPrefix The class prefix to apply to all elements in - * $path; defaults to Zend_View_Helper - * @return Zend_View_Abstract - */ - public function setHelperPath($path, $classPrefix = 'Zend_View_Helper_') - { - unset($this->_loaders['helper']); - return $this->addHelperPath($path, $classPrefix); - } - - /** - * Get full path to a helper class file specified by $name - * - * @param string $name - * @return string|false False on failure, path on success - */ - public function getHelperPath($name) - { - return $this->_getPluginPath('helper', $name); - } - - /** - * Returns an array of all currently set helper paths - * - * @return array - */ - public function getHelperPaths() - { - return $this->getPluginLoader('helper')->getPaths(); - } - - /** - * Registers a helper object, bypassing plugin loader - * - * @param Zend_View_Helper_Abstract|object $helper - * @param string $name - * @return Zend_View_Abstract - * @throws Zend_View_Exception - */ - public function registerHelper($helper, $name) - { - if (!is_object($helper)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('View helper must be an object'); - $e->setView($this); - throw $e; - } - - if (!$helper instanceof Zend_View_Interface) { - if (!method_exists($helper, $name)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception( - 'View helper must implement Zend_View_Interface or have a method matching the name provided' - ); - $e->setView($this); - throw $e; - } - } - - if (method_exists($helper, 'setView')) { - $helper->setView($this); - } - - $name = ucfirst($name); - $this->_helper[$name] = $helper; - return $this; - } - - /** - * Get a helper by name - * - * @param string $name - * @return object - */ - public function getHelper($name) - { - return $this->_getPlugin('helper', $name); - } - - /** - * Get array of all active helpers - * - * Only returns those that have already been instantiated. - * - * @return array - */ - public function getHelpers() - { - return $this->_helper; - } - - /** - * Adds to the stack of filter paths in LIFO order. - * - * @param string|array The directory (-ies) to add. - * @param string $classPrefix Class prefix to use with classes in this - * directory; defaults to Zend_View_Filter - * @return Zend_View_Abstract - */ - public function addFilterPath($path, $classPrefix = 'Zend_View_Filter_') - { - return $this->_addPluginPath('filter', $classPrefix, (array) $path); - } - - /** - * Resets the stack of filter paths. - * - * To clear all paths, use Zend_View::setFilterPath(null). - * - * @param string|array The directory (-ies) to set as the path. - * @param string $classPrefix The class prefix to apply to all elements in - * $path; defaults to Zend_View_Filter - * @return Zend_View_Abstract - */ - public function setFilterPath($path, $classPrefix = 'Zend_View_Filter_') - { - unset($this->_loaders['filter']); - return $this->addFilterPath($path, $classPrefix); - } - - /** - * Get full path to a filter class file specified by $name - * - * @param string $name - * @return string|false False on failure, path on success - */ - public function getFilterPath($name) - { - return $this->_getPluginPath('filter', $name); - } - - /** - * Get a filter object by name - * - * @param string $name - * @return object - */ - public function getFilter($name) - { - return $this->_getPlugin('filter', $name); - } - - /** - * Return array of all currently active filters - * - * Only returns those that have already been instantiated. - * - * @return array - */ - public function getFilters() - { - return $this->_filter; - } - - /** - * Returns an array of all currently set filter paths - * - * @return array - */ - public function getFilterPaths() - { - return $this->getPluginLoader('filter')->getPaths(); - } - - /** - * Return associative array of path types => paths - * - * @return array - */ - public function getAllPaths() - { - $paths = $this->_path; - $paths['helper'] = $this->getHelperPaths(); - $paths['filter'] = $this->getFilterPaths(); - return $paths; - } - - /** - * Add one or more filters to the stack in FIFO order. - * - * @param string|array One or more filters to add. - * @return Zend_View_Abstract - */ - public function addFilter($name) - { - foreach ((array) $name as $val) { - $this->_filter[] = $val; - } - return $this; - } - - /** - * Resets the filter stack. - * - * To clear all filters, use Zend_View::setFilter(null). - * - * @param string|array One or more filters to set. - * @return Zend_View_Abstract - */ - public function setFilter($name) - { - $this->_filter = array(); - $this->addFilter($name); - return $this; - } - - /** - * Sets the _escape() callback. - * - * @param mixed $spec The callback for _escape() to use. - * @return Zend_View_Abstract - */ - public function setEscape($spec) - { - $this->_escape = $spec; - return $this; - } - - /** - * Set LFI protection flag - * - * @param bool $flag - * @return Zend_View_Abstract - */ - public function setLfiProtection($flag) - { - $this->_lfiProtectionOn = (bool) $flag; - return $this; - } - - /** - * Return status of LFI protection flag - * - * @return bool - */ - public function isLfiProtectionOn() - { - return $this->_lfiProtectionOn; - } - - /** - * Assigns variables to the view script via differing strategies. - * - * Zend_View::assign('name', $value) assigns a variable called 'name' - * with the corresponding $value. - * - * Zend_View::assign($array) assigns the array keys as variable - * names (with the corresponding array values). - * - * @see __set() - * @param string|array The assignment strategy to use. - * @param mixed (Optional) If assigning a named variable, use this - * as the value. - * @return Zend_View_Abstract Fluent interface - * @throws Zend_View_Exception if $spec is neither a string nor an array, - * or if an attempt to set a private or protected member is detected - */ - public function assign($spec, $value = null) - { - // which strategy to use? - if (is_string($spec)) { - // assign by name and value - if ('_' == substr($spec, 0, 1)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Setting private or protected class members is not allowed'); - $e->setView($this); - throw $e; - } - $this->$spec = $value; - } elseif (is_array($spec)) { - // assign from associative array - $error = false; - foreach ($spec as $key => $val) { - if ('_' == substr($key, 0, 1)) { - $error = true; - break; - } - $this->$key = $val; - } - if ($error) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Setting private or protected class members is not allowed'); - $e->setView($this); - throw $e; - } - } else { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('assign() expects a string or array, received ' . gettype($spec)); - $e->setView($this); - throw $e; - } - - return $this; - } - - /** - * Return list of all assigned variables - * - * Returns all public properties of the object. Reflection is not used - * here as testing reflection properties for visibility is buggy. - * - * @return array - */ - public function getVars() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ('_' == substr($key, 0, 1)) { - unset($vars[$key]); - } - } - - return $vars; - } - - /** - * Clear all assigned variables - * - * Clears all variables assigned to Zend_View either via {@link assign()} or - * property overloading ({@link __set()}). - * - * @return void - */ - public function clearVars() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ('_' != substr($key, 0, 1)) { - unset($this->$key); - } - } - } - - /** - * Processes a view script and returns the output. - * - * @param string $name The script name to process. - * @return string The script output. - */ - public function render($name) - { - // find the script file name using the parent private method - $this->_file = $this->_script($name); - unset($name); // remove $name from local scope - - ob_start(); - $this->_run($this->_file); - - return $this->_filter(ob_get_clean()); // filter output - } - - /** - * Escapes a value for output in a view script. - * - * If escaping mechanism is one of htmlspecialchars or htmlentities, uses - * {@link $_encoding} setting. - * - * @param mixed $var The output to escape. - * @return mixed The escaped value. - */ - public function escape($var) - { - if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities'))) { - return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_encoding); - } - - if (1 == func_num_args()) { - return call_user_func($this->_escape, $var); - } - $args = func_get_args(); - return call_user_func_array($this->_escape, $args); - } - - /** - * Set encoding to use with htmlentities() and htmlspecialchars() - * - * @param string $encoding - * @return Zend_View_Abstract - */ - public function setEncoding($encoding) - { - $this->_encoding = $encoding; - return $this; - } - - /** - * Return current escape encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Enable or disable strict vars - * - * If strict variables are enabled, {@link __get()} will raise a notice - * when a variable is not defined. - * - * Use in conjunction with {@link Zend_View_Helper_DeclareVars the declareVars() helper} - * to enforce strict variable handling in your view scripts. - * - * @param boolean $flag - * @return Zend_View_Abstract - */ - public function strictVars($flag = true) - { - $this->_strictVars = ($flag) ? true : false; - - return $this; - } - - /** - * Finds a view script from the available directories. - * - * @param string $name The base name of the script. - * @return void - */ - protected function _script($name) - { - if ($this->isLfiProtectionOn() && preg_match('#\.\.[\\\/]#', $name)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Requested scripts may not include parent directory traversal ("../", "..\\" notation)'); - $e->setView($this); - throw $e; - } - - if (0 == count($this->_path['script'])) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('no view script directory set; unable to determine location for view script'); - $e->setView($this); - throw $e; - } - - foreach ($this->_path['script'] as $dir) { - if (is_readable($dir . $name)) { - return $dir . $name; - } - } - - #require_once 'Zend/View/Exception.php'; - $message = "script '$name' not found in path (" - . implode(PATH_SEPARATOR, $this->_path['script']) - . ")"; - $e = new Zend_View_Exception($message); - $e->setView($this); - throw $e; - } - - /** - * Applies the filter callback to a buffer. - * - * @param string $buffer The buffer contents. - * @return string The filtered buffer. - */ - private function _filter($buffer) - { - // loop through each filter class - foreach ($this->_filter as $name) { - // load and apply the filter class - $filter = $this->getFilter($name); - $buffer = call_user_func(array($filter, 'filter'), $buffer); - } - - // done! - return $buffer; - } - - /** - * Adds paths to the path stack in LIFO order. - * - * Zend_View::_addPath($type, 'dirname') adds one directory - * to the path stack. - * - * Zend_View::_addPath($type, $array) adds one directory for - * each array element value. - * - * In the case of filter and helper paths, $prefix should be used to - * specify what class prefix to use with the given path. - * - * @param string $type The path type ('script', 'helper', or 'filter'). - * @param string|array $path The path specification. - * @param string $prefix Class prefix to use with path (helpers and filters - * only) - * @return void - */ - private function _addPath($type, $path, $prefix = null) - { - foreach ((array) $path as $dir) { - // attempt to strip any possible separator and - // append the system directory separator - $dir = rtrim($dir, '/'); - $dir = rtrim($dir, '\\'); - $dir .= '/'; - - switch ($type) { - case 'script': - // add to the top of the stack. - array_unshift($this->_path[$type], $dir); - break; - case 'filter': - case 'helper': - default: - // add as array with prefix and dir keys - array_unshift($this->_path[$type], array('prefix' => $prefix, 'dir' => $dir)); - break; - } - } - } - - /** - * Resets the path stack for helpers and filters. - * - * @param string $type The path type ('helper' or 'filter'). - * @param string|array $path The directory (-ies) to set as the path. - * @param string $classPrefix Class prefix to apply to elements of $path - */ - private function _setPath($type, $path, $classPrefix = null) - { - $dir = DIRECTORY_SEPARATOR . ucfirst($type) . DIRECTORY_SEPARATOR; - - switch ($type) { - case 'script': - $this->_path[$type] = array(dirname(__FILE__) . $dir); - $this->_addPath($type, $path); - break; - case 'filter': - case 'helper': - default: - $this->_path[$type] = array(array( - 'prefix' => 'Zend_View_' . ucfirst($type) . '_', - 'dir' => dirname(__FILE__) . $dir - )); - $this->_addPath($type, $path, $classPrefix); - break; - } - } - - /** - * Return all paths for a given path type - * - * @param string $type The path type ('helper', 'filter', 'script') - * @return array - */ - private function _getPaths($type) - { - return $this->_path[$type]; - } - - /** - * Register helper class as loaded - * - * @param string $name - * @param string $class - * @param string $file path to class file - * @return void - */ - private function _setHelperClass($name, $class, $file) - { - $this->_helperLoadedDir[$name] = $file; - $this->_helperLoaded[$name] = $class; - } - - /** - * Register filter class as loaded - * - * @param string $name - * @param string $class - * @param string $file path to class file - * @return void - */ - private function _setFilterClass($name, $class, $file) - { - $this->_filterLoadedDir[$name] = $file; - $this->_filterLoaded[$name] = $class; - } - - /** - * Add a prefixPath for a plugin type - * - * @param string $type - * @param string $classPrefix - * @param array $paths - * @return Zend_View_Abstract - */ - private function _addPluginPath($type, $classPrefix, array $paths) - { - $loader = $this->getPluginLoader($type); - foreach ($paths as $path) { - $loader->addPrefixPath($classPrefix, $path); - } - return $this; - } - - /** - * Get a path to a given plugin class of a given type - * - * @param string $type - * @param string $name - * @return string|false - */ - private function _getPluginPath($type, $name) - { - $loader = $this->getPluginLoader($type); - if ($loader->isLoaded($name)) { - return $loader->getClassPath($name); - } - - try { - $loader->load($name); - return $loader->getClassPath($name); - } catch (Zend_Loader_Exception $e) { - return false; - } - } - - /** - * Retrieve a plugin object - * - * @param string $type - * @param string $name - * @return object - */ - private function _getPlugin($type, $name) - { - $name = ucfirst($name); - switch ($type) { - case 'filter': - $storeVar = '_filterClass'; - $store = $this->_filterClass; - break; - case 'helper': - $storeVar = '_helper'; - $store = $this->_helper; - break; - } - - if (!isset($store[$name])) { - $class = $this->getPluginLoader($type)->load($name); - $store[$name] = new $class(); - if (method_exists($store[$name], 'setView')) { - $store[$name]->setView($this); - } - } - - $this->$storeVar = $store; - return $store[$name]; - } - - /** - * Use to include the view script in a scope that only allows public - * members. - * - * @return mixed - */ - abstract protected function _run(); -} diff --git a/lib/Zend/View/Exception.php b/lib/Zend/View/Exception.php deleted file mode 100644 index e5eb47f9218..00000000000 --- a/lib/Zend/View/Exception.php +++ /dev/null @@ -1,51 +0,0 @@ -view = $view; - return $this; - } - - public function getView() - { - return $this->view; - } -} diff --git a/lib/Zend/View/Helper/Abstract.php b/lib/Zend/View/Helper/Abstract.php deleted file mode 100644 index 7e5c5d624b4..00000000000 --- a/lib/Zend/View/Helper/Abstract.php +++ /dev/null @@ -1,64 +0,0 @@ -view = $view; - return $this; - } - - /** - * Strategy pattern: currently unutilized - * - * @return void - */ - public function direct() - { - } -} diff --git a/lib/Zend/View/Helper/Action.php b/lib/Zend/View/Helper/Action.php deleted file mode 100644 index 6a99486d295..00000000000 --- a/lib/Zend/View/Helper/Action.php +++ /dev/null @@ -1,164 +0,0 @@ -getControllerDirectory(); - if (empty($modules)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Action helper depends on valid front controller instance'); - $e->setView($this->view); - throw $e; - } - - $request = $front->getRequest(); - $response = $front->getResponse(); - - if (empty($request) || empty($response)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Action view helper requires both a registered request and response object in the front controller instance'); - $e->setView($this->view); - throw $e; - } - - $this->request = clone $request; - $this->response = clone $response; - $this->dispatcher = clone $front->getDispatcher(); - $this->defaultModule = $front->getDefaultModule(); - } - - /** - * Reset object states - * - * @return void - */ - public function resetObjects() - { - $params = $this->request->getUserParams(); - foreach (array_keys($params) as $key) { - $this->request->setParam($key, null); - } - - $this->response->clearBody(); - $this->response->clearHeaders() - ->clearRawHeaders(); - } - - /** - * Retrieve rendered contents of a controller action - * - * If the action results in a forward or redirect, returns empty string. - * - * @param string $action - * @param string $controller - * @param string $module Defaults to default module - * @param array $params - * @return string - */ - public function action($action, $controller, $module = null, array $params = array()) - { - $this->resetObjects(); - if (null === $module) { - $module = $this->defaultModule; - } - - // clone the view object to prevent over-writing of view variables - $viewRendererObj = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); - Zend_Controller_Action_HelperBroker::addHelper(clone $viewRendererObj); - - $this->request->setParams($params) - ->setModuleName($module) - ->setControllerName($controller) - ->setActionName($action) - ->setDispatched(true); - - $this->dispatcher->dispatch($this->request, $this->response); - - // reset the viewRenderer object to it's original state - Zend_Controller_Action_HelperBroker::addHelper($viewRendererObj); - - - if (!$this->request->isDispatched() - || $this->response->isRedirect()) - { - // forwards and redirects render nothing - return ''; - } - - $return = $this->response->getBody(); - $this->resetObjects(); - return $return; - } - - /** - * Clone the current View - * - * @return Zend_View_Interface - */ - public function cloneView() - { - $view = clone $this->view; - $view->clearVars(); - return $view; - } -} diff --git a/lib/Zend/View/Helper/BaseUrl.php b/lib/Zend/View/Helper/BaseUrl.php deleted file mode 100644 index 845a0486a35..00000000000 --- a/lib/Zend/View/Helper/BaseUrl.php +++ /dev/null @@ -1,116 +0,0 @@ -getBaseUrl(); - - // Remove trailing slashes - if (null !== $file) { - $file = '/' . ltrim($file, '/\\'); - } - - return $baseUrl . $file; - } - - /** - * Set BaseUrl - * - * @param string $base - * @return Zend_View_Helper_BaseUrl - */ - public function setBaseUrl($base) - { - $this->_baseUrl = rtrim($base, '/\\'); - return $this; - } - - /** - * Get BaseUrl - * - * @return string - */ - public function getBaseUrl() - { - if ($this->_baseUrl === null) { - /** @see Zend_Controller_Front */ - #require_once 'Zend/Controller/Front.php'; - $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl(); - - // Remove scriptname, eg. index.php from baseUrl - $baseUrl = $this->_removeScriptName($baseUrl); - - $this->setBaseUrl($baseUrl); - } - - return $this->_baseUrl; - } - - /** - * Remove Script filename from baseurl - * - * @param string $url - * @return string - */ - protected function _removeScriptName($url) - { - if (!isset($_SERVER['SCRIPT_NAME'])) { - // We can't do much now can we? (Well, we could parse out by ".") - return $url; - } - - if (($pos = strripos($url, basename($_SERVER['SCRIPT_NAME']))) !== false) { - $url = substr($url, 0, $pos); - } - - return $url; - } -} diff --git a/lib/Zend/View/Helper/Currency.php b/lib/Zend/View/Helper/Currency.php deleted file mode 100644 index 9cec1d9841f..00000000000 --- a/lib/Zend/View/Helper/Currency.php +++ /dev/null @@ -1,120 +0,0 @@ -setCurrency($currency); - } - - /** - * Output a formatted currency - * - * @param integer|float $value Currency value to output - * @param string|Zend_Locale|array $currency OPTIONAL Currency to use for - * this call - * @return string Formatted currency - */ - public function currency($value = null, $currency = null) - { - if ($value === null) { - return $this; - } - - if (is_string($currency) || ($currency instanceof Zend_Locale)) { - #require_once 'Zend/Locale.php'; - if (Zend_Locale::isLocale($currency)) { - $currency = array('locale' => $currency); - } - } - - if (is_string($currency)) { - $currency = array('currency' => $currency); - } - - if (is_array($currency)) { - return $this->_currency->toCurrency($value, $currency); - } - - return $this->_currency->toCurrency($value); - } - - /** - * Sets a currency to use - * - * @param Zend_Currency|String|Zend_Locale $currency Currency to use - * @throws Zend_View_Exception When no or a false currency was set - * @return Zend_View_Helper_Currency - */ - public function setCurrency($currency = null) - { - if (!$currency instanceof Zend_Currency) { - #require_once 'Zend/Currency.php'; - $currency = new Zend_Currency($currency); - } - $this->_currency = $currency; - - return $this; - } - - /** - * Retrieve currency object - * - * @return Zend_Currency|null - */ - public function getCurrency() - { - return $this->_currency; - } -} diff --git a/lib/Zend/View/Helper/Cycle.php b/lib/Zend/View/Helper/Cycle.php deleted file mode 100644 index eb5fd5132bc..00000000000 --- a/lib/Zend/View/Helper/Cycle.php +++ /dev/null @@ -1,225 +0,0 @@ --1) ; - - /** - * Array of values - * - * @var array - */ - protected $_data = array(self::DEFAULT_NAME=>array()); - - /** - * Actual name of cycle - * - * @var string - */ - protected $_name = self::DEFAULT_NAME; - - /** - * Add elements to alternate - * - * @param array $data - * @param string $name - * @return Zend_View_Helper_Cycle - */ - public function cycle(array $data = array(), $name = self::DEFAULT_NAME) - { - if(!empty($data)) - $this->_data[$name] = $data; - - $this->setName($name); - return $this; - } - - /** - * Add elements to alternate - * - * @param array $data - * @param string $name - * @return Zend_View_Helper_Cycle - */ - public function assign(Array $data , $name = self::DEFAULT_NAME) - { - $this->setName($name); - $this->_data[$name] = $data; - $this->rewind(); - return $this; - } - - /** - * Sets actual name of cycle - * - * @param string $name - * @return Zend_View_Helper_Cycle - */ - public function setName($name = self::DEFAULT_NAME) - { - $this->_name = $name; - - if(!isset($this->_data[$this->_name])) - $this->_data[$this->_name] = array(); - - if(!isset($this->_pointers[$this->_name])) - $this->rewind(); - - return $this; - } - - /** - * Gets actual name of cycle - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - - /** - * Return all elements - * - * @return array - */ - public function getAll() - { - return $this->_data[$this->_name]; - } - - /** - * Turn helper into string - * - * @return string - */ - public function toString() - { - return (string) $this->_data[$this->_name][$this->key()]; - } - - /** - * Cast to string - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Move to next value - * - * @return Zend_View_Helper_Cycle - */ - public function next() - { - $count = count($this->_data[$this->_name]); - if ($this->_pointers[$this->_name] == ($count - 1)) - $this->_pointers[$this->_name] = 0; - else - $this->_pointers[$this->_name] = ++$this->_pointers[$this->_name]; - return $this; - } - - /** - * Move to previous value - * - * @return Zend_View_Helper_Cycle - */ - public function prev() - { - $count = count($this->_data[$this->_name]); - if ($this->_pointers[$this->_name] <= 0) - $this->_pointers[$this->_name] = $count - 1; - else - $this->_pointers[$this->_name] = --$this->_pointers[$this->_name]; - return $this; - } - - /** - * Return iteration number - * - * @return int - */ - public function key() - { - if ($this->_pointers[$this->_name] < 0) - return 0; - else - return $this->_pointers[$this->_name]; - } - - /** - * Rewind pointer - * - * @return Zend_View_Helper_Cycle - */ - public function rewind() - { - $this->_pointers[$this->_name] = -1; - return $this; - } - - /** - * Check if element is valid - * - * @return bool - */ - public function valid() - { - return isset($this->_data[$this->_name][$this->key()]); - } - - /** - * Return current element - * - * @return mixed - */ - public function current() - { - return $this->_data[$this->_name][$this->key()]; - } -} diff --git a/lib/Zend/View/Helper/DeclareVars.php b/lib/Zend/View/Helper/DeclareVars.php deleted file mode 100644 index 330c40a5e96..00000000000 --- a/lib/Zend/View/Helper/DeclareVars.php +++ /dev/null @@ -1,95 +0,0 @@ - - * $this->declareVars( - * 'varName1', - * 'varName2', - * array('varName3' => 'defaultValue', - * 'varName4' => array() - * ) - * ); - * - * - * @param string|array variable number of arguments, all string names of variables to test - * @return void - */ - public function declareVars() - { - $args = func_get_args(); - foreach($args as $key) { - if (is_array($key)) { - foreach ($key as $name => $value) { - $this->_declareVar($name, $value); - } - } else if (!isset($view->$key)) { - $this->_declareVar($key); - } - } - } - - /** - * Set a view variable - * - * Checks to see if a $key is set in the view object; if not, sets it to $value. - * - * @param string $key - * @param string $value Defaults to an empty string - * @return void - */ - protected function _declareVar($key, $value = '') - { - if (!isset($this->view->$key)) { - $this->view->$key = $value; - } - } -} diff --git a/lib/Zend/View/Helper/Doctype.php b/lib/Zend/View/Helper/Doctype.php deleted file mode 100644 index 854ba16efbd..00000000000 --- a/lib/Zend/View/Helper/Doctype.php +++ /dev/null @@ -1,242 +0,0 @@ -_regKey)) { - $this->_registry = new ArrayObject(array( - 'doctypes' => array( - self::XHTML11 => '', - self::XHTML1_STRICT => '', - self::XHTML1_TRANSITIONAL => '', - self::XHTML1_FRAMESET => '', - self::XHTML1_RDFA => '', - self::XHTML1_RDFA11 => '', - self::XHTML_BASIC1 => '', - self::XHTML5 => '', - self::HTML4_STRICT => '', - self::HTML4_LOOSE => '', - self::HTML4_FRAMESET => '', - self::HTML5 => '', - ) - )); - Zend_Registry::set($this->_regKey, $this->_registry); - $this->setDoctype($this->_defaultDoctype); - } else { - $this->_registry = Zend_Registry::get($this->_regKey); - } - } - - /** - * Set or retrieve doctype - * - * @param string $doctype - * @return Zend_View_Helper_Doctype - */ - public function doctype($doctype = null) - { - if (null !== $doctype) { - switch ($doctype) { - case self::XHTML11: - case self::XHTML1_STRICT: - case self::XHTML1_TRANSITIONAL: - case self::XHTML1_FRAMESET: - case self::XHTML_BASIC1: - case self::XHTML1_RDFA: - case self::XHTML1_RDFA11: - case self::XHTML5: - case self::HTML4_STRICT: - case self::HTML4_LOOSE: - case self::HTML4_FRAMESET: - case self::HTML5: - $this->setDoctype($doctype); - break; - default: - if (substr($doctype, 0, 9) != 'setView($this->view); - throw $e; - } - if (stristr($doctype, 'xhtml')) { - $type = self::CUSTOM_XHTML; - } else { - $type = self::CUSTOM; - } - $this->setDoctype($type); - $this->_registry['doctypes'][$type] = $doctype; - break; - } - } - - return $this; - } - - /** - * Set doctype - * - * @param string $doctype - * @return Zend_View_Helper_Doctype - */ - public function setDoctype($doctype) - { - $this->_registry['doctype'] = $doctype; - return $this; - } - - /** - * Retrieve doctype - * - * @return string - */ - public function getDoctype() - { - return $this->_registry['doctype']; - } - - /** - * Get doctype => string mappings - * - * @return array - */ - public function getDoctypes() - { - return $this->_registry['doctypes']; - } - - /** - * Is doctype XHTML? - * - * @return boolean - */ - public function isXhtml() - { - return (stristr($this->getDoctype(), 'xhtml') ? true : false); - } - - /** - * Is doctype strict? - * - * @return boolean - */ - public function isStrict() - { - switch ( $this->getDoctype() ) - { - case self::XHTML1_STRICT: - case self::XHTML11: - case self::HTML4_STRICT: - return true; - default: - return false; - } - } - - /** - * Is doctype HTML5? (HeadMeta uses this for validation) - * - * @return booleean - */ - public function isHtml5() { - return (stristr($this->doctype(), '') ? true : false); - } - - /** - * Is doctype RDFa? - * - * @return booleean - */ - public function isRdfa() { - return (stristr($this->getDoctype(), 'rdfa') ? true : false); - } - - /** - * String representation of doctype - * - * @return string - */ - public function __toString() - { - $doctypes = $this->getDoctypes(); - return $doctypes[$this->getDoctype()]; - } -} diff --git a/lib/Zend/View/Helper/Fieldset.php b/lib/Zend/View/Helper/Fieldset.php deleted file mode 100644 index 48ce9c6e86c..00000000000 --- a/lib/Zend/View/Helper/Fieldset.php +++ /dev/null @@ -1,79 +0,0 @@ -_getInfo($name, $content, $attribs); - extract($info); - - // get legend - $legend = ''; - if (isset($attribs['legend'])) { - $legendString = trim($attribs['legend']); - if (!empty($legendString)) { - $legend = '' - . (($escape) ? $this->view->escape($legendString) : $legendString) - . '' . PHP_EOL; - } - unset($attribs['legend']); - } - - // get id - if (!empty($id)) { - $id = ' id="' . $this->view->escape($id) . '"'; - } else { - $id = ''; - } - - // render fieldset - $xhtml = '_htmlAttribs($attribs) - . '>' - . $legend - . $content - . ''; - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/Form.php b/lib/Zend/View/Helper/Form.php deleted file mode 100644 index d0910db734c..00000000000 --- a/lib/Zend/View/Helper/Form.php +++ /dev/null @@ -1,86 +0,0 @@ -_getInfo($name, $content, $attribs); - extract($info); - - if (!empty($id)) { - $id = ' id="' . $this->view->escape($id) . '"'; - } else { - $id = ''; - } - - if (array_key_exists('id', $attribs) && empty($attribs['id'])) { - unset($attribs['id']); - } - - if (!empty($name) && !($this->_isXhtml() && $this->_isStrictDoctype())) { - $name = ' name="' . $this->view->escape($name) . '"'; - } else { - $name = ''; - } - - if ($this->_isHtml5() && array_key_exists('action', $attribs) && !$attribs['action']) { - unset($attribs['action']); - } - - if ( array_key_exists('name', $attribs) && empty($attribs['id'])) { - unset($attribs['id']); - } - - $xhtml = '_htmlAttribs($attribs) - . '>'; - - if (false !== $content) { - $xhtml .= $content - . ''; - } - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormButton.php b/lib/Zend/View/Helper/FormButton.php deleted file mode 100644 index 605aefbb307..00000000000 --- a/lib/Zend/View/Helper/FormButton.php +++ /dev/null @@ -1,105 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, id, value, attribs, options, listsep, disable, escape - - // Get content - $content = ''; - if (isset($attribs['content'])) { - $content = $attribs['content']; - unset($attribs['content']); - } else { - $content = $value; - } - - // Ensure type is sane - $type = 'button'; - if (isset($attribs['type'])) { - $attribs['type'] = strtolower($attribs['type']); - if (in_array($attribs['type'], array('submit', 'reset', 'button'))) { - $type = $attribs['type']; - } - unset($attribs['type']); - } - - // build the element - if ($disable) { - $attribs['disabled'] = 'disabled'; - } - - $content = ($escape) ? $this->view->escape($content) : $content; - - $xhtml = 'view->escape($value) . '"'; - } - - // add attributes and close start tag - $xhtml .= $this->_htmlAttribs($attribs) . '>'; - - // add content and end tag - $xhtml .= $content . ''; - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormCheckbox.php b/lib/Zend/View/Helper/FormCheckbox.php deleted file mode 100644 index c0392263e5b..00000000000 --- a/lib/Zend/View/Helper/FormCheckbox.php +++ /dev/null @@ -1,164 +0,0 @@ - '1', - 'uncheckedValue' => '0' - ); - - /** - * Generates a 'checkbox' element. - * - * @access public - * - * @param string|array $name If a string, the element name. If an - * array, all other parameters are ignored, and the array elements - * are extracted in place of added parameters. - * @param mixed $value The element value. - * @param array $attribs Attributes for the element tag. - * @return string The element XHTML. - */ - public function formCheckbox($name, $value = null, $attribs = null, array $checkedOptions = null) - { - $info = $this->_getInfo($name, $value, $attribs); - extract($info); // name, id, value, attribs, options, listsep, disable - - $checked = false; - if (isset($attribs['checked']) && $attribs['checked']) { - $checked = true; - unset($attribs['checked']); - } elseif (isset($attribs['checked'])) { - $checked = false; - unset($attribs['checked']); - } - - $checkedOptions = self::determineCheckboxInfo($value, $checked, $checkedOptions); - - // is the element disabled? - $disabled = ''; - if ($disable) { - $disabled = ' disabled="disabled"'; - } - - // build the element - $xhtml = ''; - if ((!$disable && !strstr($name, '[]')) - && (empty($attribs['disableHidden']) || !$attribs['disableHidden']) - ) { - $xhtml = $this->_hidden($name, $checkedOptions['uncheckedValue']); - } - - if (array_key_exists('disableHidden', $attribs)) { - unset($attribs['disableHidden']); - } - - $xhtml .= '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } - - /** - * Determine checkbox information - * - * @param string $value - * @param bool $checked - * @param array|null $checkedOptions - * @return array - */ - public static function determineCheckboxInfo($value, $checked, array $checkedOptions = null) - { - // Checked/unchecked values - $checkedValue = null; - $uncheckedValue = null; - if (is_array($checkedOptions)) { - if (array_key_exists('checkedValue', $checkedOptions)) { - $checkedValue = (string) $checkedOptions['checkedValue']; - unset($checkedOptions['checkedValue']); - } - if (array_key_exists('uncheckedValue', $checkedOptions)) { - $uncheckedValue = (string) $checkedOptions['uncheckedValue']; - unset($checkedOptions['uncheckedValue']); - } - if (null === $checkedValue) { - $checkedValue = (string) array_shift($checkedOptions); - } - if (null === $uncheckedValue) { - $uncheckedValue = (string) array_shift($checkedOptions); - } - } elseif ($value !== null) { - $uncheckedValue = self::$_defaultCheckedOptions['uncheckedValue']; - } else { - $checkedValue = self::$_defaultCheckedOptions['checkedValue']; - $uncheckedValue = self::$_defaultCheckedOptions['uncheckedValue']; - } - - // is the element checked? - $checkedString = ''; - if ($checked || ((string) $value === $checkedValue)) { - $checkedString = ' checked="checked"'; - $checked = true; - } else { - $checked = false; - } - - // Checked value should be value if no checked options provided - if ($checkedValue == null) { - $checkedValue = $value; - } - - return array( - 'checked' => $checked, - 'checkedString' => $checkedString, - 'checkedValue' => $checkedValue, - 'uncheckedValue' => $uncheckedValue, - ); - } -} diff --git a/lib/Zend/View/Helper/FormElement.php b/lib/Zend/View/Helper/FormElement.php deleted file mode 100644 index 980e3455271..00000000000 --- a/lib/Zend/View/Helper/FormElement.php +++ /dev/null @@ -1,204 +0,0 @@ -_translator; - } - - /** - * Set translator - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - * @return Zend_View_Helper_FormElement - */ - public function setTranslator($translator = null) - { - if (null === $translator) { - $this->_translator = null; - } elseif ($translator instanceof Zend_Translate_Adapter) { - $this->_translator = $translator; - } elseif ($translator instanceof Zend_Translate) { - $this->_translator = $translator->getAdapter(); - } else { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid translator specified'); - $e->setView($this->view); - throw $e; - } - return $this; - } - - /** - * Converts parameter arguments to an element info array. - * - * E.g, formExample($name, $value, $attribs, $options, $listsep) is - * the same thing as formExample(array('name' => ...)). - * - * Note that you cannot pass a 'disable' param; you need to pass - * it as an 'attribs' key. - * - * @access protected - * - * @return array An element info array with keys for name, value, - * attribs, options, listsep, disable, and escape. - */ - protected function _getInfo($name, $value = null, $attribs = null, - $options = null, $listsep = null - ) { - // the baseline info. note that $name serves a dual purpose; - // if an array, it's an element info array that will override - // these baseline values. as such, ignore it for the 'name' - // if it's an array. - $info = array( - 'name' => is_array($name) ? '' : $name, - 'id' => is_array($name) ? '' : $name, - 'value' => $value, - 'attribs' => $attribs, - 'options' => $options, - 'listsep' => $listsep, - 'disable' => false, - 'escape' => true, - ); - - // override with named args - if (is_array($name)) { - // only set keys that are already in info - foreach ($info as $key => $val) { - if (isset($name[$key])) { - $info[$key] = $name[$key]; - } - } - - // If all helper options are passed as an array, attribs may have - // been as well - if (null === $attribs) { - $attribs = $info['attribs']; - } - } - - $attribs = (array)$attribs; - - // Normalize readonly tag - if (array_key_exists('readonly', $attribs)) { - $attribs['readonly'] = 'readonly'; - } - - // Disable attribute - if (array_key_exists('disable', $attribs)) { - if (is_scalar($attribs['disable'])) { - // disable the element - $info['disable'] = (bool)$attribs['disable']; - } else if (is_array($attribs['disable'])) { - $info['disable'] = $attribs['disable']; - } - } - - // Set ID for element - if (array_key_exists('id', $attribs)) { - $info['id'] = (string)$attribs['id']; - } else if ('' !== $info['name']) { - $info['id'] = trim(strtr($info['name'], - array('[' => '-', ']' => '')), '-'); - } - - // Remove NULL name attribute override - if (array_key_exists('name', $attribs) && is_null($attribs['name'])) { - unset($attribs['name']); - } - - // Override name in info if specified in attribs - if (array_key_exists('name', $attribs) && $attribs['name'] != $info['name']) { - $info['name'] = $attribs['name']; - } - - // Determine escaping from attributes - if (array_key_exists('escape', $attribs)) { - $info['escape'] = (bool)$attribs['escape']; - } - - // Determine listsetp from attributes - if (array_key_exists('listsep', $attribs)) { - $info['listsep'] = (string)$attribs['listsep']; - } - - // Remove attribs that might overwrite the other keys. We do this LAST - // because we needed the other attribs values earlier. - foreach ($info as $key => $val) { - if (array_key_exists($key, $attribs)) { - unset($attribs[$key]); - } - } - $info['attribs'] = $attribs; - - // done! - return $info; - } - - /** - * Creates a hidden element. - * - * We have this as a common method because other elements often - * need hidden elements for their operation. - * - * @access protected - * - * @param string $name The element name. - * @param string $value The element value. - * @param array $attribs Attributes for the element. - * - * @return string A hidden element. - */ - protected function _hidden($name, $value = null, $attribs = null) - { - return '_htmlAttribs($attribs) . $this->getClosingBracket(); - } -} diff --git a/lib/Zend/View/Helper/FormErrors.php b/lib/Zend/View/Helper/FormErrors.php deleted file mode 100644 index ecffa9f5288..00000000000 --- a/lib/Zend/View/Helper/FormErrors.php +++ /dev/null @@ -1,167 +0,0 @@ -'; - protected $_htmlElementStart = '
  • '; - protected $_htmlElementSeparator = '
  • '; - /**#@-*/ - - /** - * Render form errors - * - * @param string|array $errors Error(s) to render - * @param array $options - * @return string - */ - public function formErrors($errors, array $options = null) - { - $escape = true; - if (isset($options['escape'])) { - $escape = (bool) $options['escape']; - unset($options['escape']); - } - - if (empty($options['class'])) { - $options['class'] = 'errors'; - } - - if (isset($options['elementStart'])) { - $this->setElementStart($options['elementStart']); - } - if (isset($options['elementEnd'])) { - $this->setElementEnd($options['elementEnd']); - } - if (isset($options['elementSeparator'])) { - $this->setElementSeparator($options['elementSeparator']); - } - - $start = $this->getElementStart(); - if (strstr($start, '%s')) { - $attribs = $this->_htmlAttribs($options); - $start = sprintf($start, $attribs); - } - - if ($escape) { - foreach ($errors as $key => $error) { - $errors[$key] = $this->view->escape($error); - } - } - - $html = $start - . implode($this->getElementSeparator(), (array) $errors) - . $this->getElementEnd(); - - return $html; - } - - /** - * Set end string for displaying errors - * - * @param string $string - * @return Zend_View_Helper_FormErrors - */ - public function setElementEnd($string) - { - $this->_htmlElementEnd = (string) $string; - return $this; - } - - /** - * Retrieve end string for displaying errors - * - * @return string - */ - public function getElementEnd() - { - return $this->_htmlElementEnd; - } - - /** - * Set separator string for displaying errors - * - * @param string $string - * @return Zend_View_Helper_FormErrors - */ - public function setElementSeparator($string) - { - $this->_htmlElementSeparator = (string) $string; - return $this; - } - - /** - * Retrieve separator string for displaying errors - * - * @return string - */ - public function getElementSeparator() - { - return $this->_htmlElementSeparator; - } - - /** - * Set start string for displaying errors - * - * @param string $string - * @return Zend_View_Helper_FormErrors - */ - public function setElementStart($string) - { - $this->_htmlElementStart = (string) $string; - return $this; - } - - /** - * Retrieve start string for displaying errors - * - * @return string - */ - public function getElementStart() - { - return $this->_htmlElementStart; - } - -} diff --git a/lib/Zend/View/Helper/FormFile.php b/lib/Zend/View/Helper/FormFile.php deleted file mode 100644 index 84d43a0b6d6..00000000000 --- a/lib/Zend/View/Helper/FormFile.php +++ /dev/null @@ -1,75 +0,0 @@ -_getInfo($name, null, $attribs); - extract($info); // name, id, value, attribs, options, listsep, disable - - // is it disabled? - $disabled = ''; - if ($disable) { - $disabled = ' disabled="disabled"'; - } - - // build the element - $xhtml = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormHidden.php b/lib/Zend/View/Helper/FormHidden.php deleted file mode 100644 index 4a29f5aa95a..00000000000 --- a/lib/Zend/View/Helper/FormHidden.php +++ /dev/null @@ -1,66 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - if (isset($id)) { - if (isset($attribs) && is_array($attribs)) { - $attribs['id'] = $id; - } else { - $attribs = array('id' => $id); - } - } - return $this->_hidden($name, $value, $attribs); - } -} diff --git a/lib/Zend/View/Helper/FormImage.php b/lib/Zend/View/Helper/FormImage.php deleted file mode 100644 index 96e333728af..00000000000 --- a/lib/Zend/View/Helper/FormImage.php +++ /dev/null @@ -1,95 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - - // Determine if we should use the value or the src attribute - if (isset($attribs['src'])) { - $src = ' src="' . $this->view->escape($attribs['src']) . '"'; - unset($attribs['src']); - } else { - $src = ' src="' . $this->view->escape($value) . '"'; - unset($value); - } - - // Do we have a value? - if (isset($value) && !empty($value)) { - $value = ' value="' . $this->view->escape($value) . '"'; - } else { - $value = ''; - } - - // Disabled? - $disabled = ''; - if ($disable) { - $disabled = ' disabled="disabled"'; - } - - // build the element - $xhtml = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormLabel.php b/lib/Zend/View/Helper/FormLabel.php deleted file mode 100644 index 96b7fad7346..00000000000 --- a/lib/Zend/View/Helper/FormLabel.php +++ /dev/null @@ -1,72 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable, escape - - // build the element - if ($disable) { - // disabled; display nothing - return ''; - } - - $value = ($escape) ? $this->view->escape($value) : $value; - $for = (empty($attribs['disableFor']) || !$attribs['disableFor']) - ? ' for="' . $this->view->escape($id) . '"' - : ''; - if (array_key_exists('disableFor', $attribs)) { - unset($attribs['disableFor']); - } - - // enabled; display label - $xhtml = '_htmlAttribs($attribs) - . '>' . $value . ''; - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormMultiCheckbox.php b/lib/Zend/View/Helper/FormMultiCheckbox.php deleted file mode 100644 index 06aece2a9f7..00000000000 --- a/lib/Zend/View/Helper/FormMultiCheckbox.php +++ /dev/null @@ -1,74 +0,0 @@ -\n") - { - return $this->formRadio($name, $value, $attribs, $options, $listsep); - } -} diff --git a/lib/Zend/View/Helper/FormNote.php b/lib/Zend/View/Helper/FormNote.php deleted file mode 100644 index 8d4e187c96b..00000000000 --- a/lib/Zend/View/Helper/FormNote.php +++ /dev/null @@ -1,61 +0,0 @@ -_getInfo($name, $value); - extract($info); // name, value, attribs, options, listsep, disable - return $value; - } -} diff --git a/lib/Zend/View/Helper/FormPassword.php b/lib/Zend/View/Helper/FormPassword.php deleted file mode 100644 index f83ee3a5a7c..00000000000 --- a/lib/Zend/View/Helper/FormPassword.php +++ /dev/null @@ -1,89 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - - // is it disabled? - $disabled = ''; - if ($disable) { - // disabled - $disabled = ' disabled="disabled"'; - } - - // determine the XHTML value - $valueString = ' value=""'; - if (array_key_exists('renderPassword', $attribs)) { - if ($attribs['renderPassword']) { - $valueString = ' value="' . $this->view->escape($value) . '"'; - } - unset($attribs['renderPassword']); - } - - // render the element - $xhtml = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } - -} diff --git a/lib/Zend/View/Helper/FormRadio.php b/lib/Zend/View/Helper/FormRadio.php deleted file mode 100644 index 95db8e32717..00000000000 --- a/lib/Zend/View/Helper/FormRadio.php +++ /dev/null @@ -1,187 +0,0 @@ -\n") - { - - $info = $this->_getInfo($name, $value, $attribs, $options, $listsep); - extract($info); // name, value, attribs, options, listsep, disable - - // retrieve attributes for labels (prefixed with 'label_' or 'label') - $label_attribs = array(); - foreach ($attribs as $key => $val) { - $tmp = false; - $keyLen = strlen($key); - if ((6 < $keyLen) && (substr($key, 0, 6) == 'label_')) { - $tmp = substr($key, 6); - } elseif ((5 < $keyLen) && (substr($key, 0, 5) == 'label')) { - $tmp = substr($key, 5); - } - - if ($tmp) { - // make sure first char is lowercase - $tmp[0] = strtolower($tmp[0]); - $label_attribs[$tmp] = $val; - unset($attribs[$key]); - } - } - - $labelPlacement = 'append'; - foreach ($label_attribs as $key => $val) { - switch (strtolower($key)) { - case 'placement': - unset($label_attribs[$key]); - $val = strtolower($val); - if (in_array($val, array('prepend', 'append'))) { - $labelPlacement = $val; - } - break; - } - } - - // the radio button values and labels - $options = (array) $options; - - // build the element - $xhtml = ''; - $list = array(); - - // should the name affect an array collection? - $name = $this->view->escape($name); - if ($this->_isArray && ('[]' != substr($name, -2))) { - $name .= '[]'; - } - - // ensure value is an array to allow matching multiple times - $value = (array) $value; - - // Set up the filter - Alnum + hyphen + underscore - #require_once 'Zend/Filter/PregReplace.php'; - $pattern = @preg_match('/\pL/u', 'a') - ? '/[^\p{L}\p{N}\-\_]/u' // Unicode - : '/[^a-zA-Z0-9\-\_]/'; // No Unicode - $filter = new Zend_Filter_PregReplace($pattern, ""); - - // add radio buttons to the list. - foreach ($options as $opt_value => $opt_label) { - - // Should the label be escaped? - if ($escape) { - $opt_label = $this->view->escape($opt_label); - } - - // is it disabled? - $disabled = ''; - if (true === $disable) { - $disabled = ' disabled="disabled"'; - } elseif (is_array($disable) && in_array($opt_value, $disable)) { - $disabled = ' disabled="disabled"'; - } - - // is it checked? - $checked = ''; - if (in_array($opt_value, $value)) { - $checked = ' checked="checked"'; - } - - // generate ID - $optId = $id . '-' . $filter->filter($opt_value); - - // Wrap the radios in labels - $radio = '_htmlAttribs($label_attribs) . '>' - . (('prepend' == $labelPlacement) ? $opt_label : '') - . '_htmlAttribs($attribs) - . $this->getClosingBracket() - . (('append' == $labelPlacement) ? $opt_label : '') - . ''; - - // add to the array of radio buttons - $list[] = $radio; - } - - // XHTML or HTML for standard list separator? - if (!$this->_isXhtml() && false !== strpos($listsep, '
    ')) { - $listsep = str_replace('
    ', '
    ', $listsep); - } - - // done! - $xhtml .= implode($listsep, $list); - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormReset.php b/lib/Zend/View/Helper/FormReset.php deleted file mode 100644 index ff039cd4207..00000000000 --- a/lib/Zend/View/Helper/FormReset.php +++ /dev/null @@ -1,82 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - - // check if disabled - $disabled = ''; - if ($disable) { - $disabled = ' disabled="disabled"'; - } - - // Render button - $xhtml = 'view->escape($value) . '"'; - } - - // add attributes, close, and return - $xhtml .= $this->_htmlAttribs($attribs) . $this->getClosingBracket(); - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormSelect.php b/lib/Zend/View/Helper/FormSelect.php deleted file mode 100644 index feae758826f..00000000000 --- a/lib/Zend/View/Helper/FormSelect.php +++ /dev/null @@ -1,200 +0,0 @@ -\n") - { - $info = $this->_getInfo($name, $value, $attribs, $options, $listsep); - extract($info); // name, id, value, attribs, options, listsep, disable - - // force $value to array so we can compare multiple values to multiple - // options; also ensure it's a string for comparison purposes. - $value = array_map('strval', (array) $value); - - // check if element may have multiple values - $multiple = ''; - - if (substr($name, -2) == '[]') { - // multiple implied by the name - $multiple = ' multiple="multiple"'; - } - - if (isset($attribs['multiple'])) { - // Attribute set - if ($attribs['multiple']) { - // True attribute; set multiple attribute - $multiple = ' multiple="multiple"'; - - // Make sure name indicates multiple values are allowed - if (!empty($multiple) && (substr($name, -2) != '[]')) { - $name .= '[]'; - } - } else { - // False attribute; ensure attribute not set - $multiple = ''; - } - unset($attribs['multiple']); - } - - // handle the options classes - $optionClasses = array(); - if (isset($attribs['optionClasses'])) { - $optionClasses = $attribs['optionClasses']; - unset($attribs['optionClasses']); - } - - // now start building the XHTML. - $disabled = ''; - if (true === $disable) { - $disabled = ' disabled="disabled"'; - } - - // Build the surrounding select element first. - $xhtml = '_htmlAttribs($attribs) - . ">\n "; - - // build the list of options - $list = array(); - $translator = $this->getTranslator(); - foreach ((array) $options as $opt_value => $opt_label) { - if (is_array($opt_label)) { - $opt_disable = ''; - if (is_array($disable) && in_array($opt_value, $disable)) { - $opt_disable = ' disabled="disabled"'; - } - if (null !== $translator) { - $opt_value = $translator->translate($opt_value); - } - $opt_id = ' id="' . $this->view->escape($id) . '-optgroup-' - . $this->view->escape($opt_value) . '"'; - $list[] = ''; - foreach ($opt_label as $val => $lab) { - $list[] = $this->_build($val, $lab, $value, $disable, $optionClasses); - } - $list[] = ''; - } else { - $list[] = $this->_build($opt_value, $opt_label, $value, $disable, $optionClasses); - } - } - - // add the options to the xhtml and close the select - $xhtml .= implode("\n ", $list) . "\n"; - - return $xhtml; - } - - /** - * Builds the actual "; - - return $opt; - } - -} diff --git a/lib/Zend/View/Helper/FormSubmit.php b/lib/Zend/View/Helper/FormSubmit.php deleted file mode 100644 index b1a338f1026..00000000000 --- a/lib/Zend/View/Helper/FormSubmit.php +++ /dev/null @@ -1,81 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable, id - // check if disabled - $disabled = ''; - if ($disable) { - $disabled = ' disabled="disabled"'; - } - - if ($id) { - $id = ' id="' . $this->view->escape($id) . '"'; - } - - // Render the button. - $xhtml = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormText.php b/lib/Zend/View/Helper/FormText.php deleted file mode 100644 index d5a45a25bf5..00000000000 --- a/lib/Zend/View/Helper/FormText.php +++ /dev/null @@ -1,78 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - - // build the element - $disabled = ''; - if ($disable) { - // disabled - $disabled = ' disabled="disabled"'; - } - - $xhtml = '_htmlAttribs($attribs) - . $this->getClosingBracket(); - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/FormTextarea.php b/lib/Zend/View/Helper/FormTextarea.php deleted file mode 100644 index 0b112b36516..00000000000 --- a/lib/Zend/View/Helper/FormTextarea.php +++ /dev/null @@ -1,104 +0,0 @@ -_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - - // is it disabled? - $disabled = ''; - if ($disable) { - // disabled. - $disabled = ' disabled="disabled"'; - } - - // Make sure that there are 'rows' and 'cols' values - // as required by the spec. noted by Orjan Persson. - if (empty($attribs['rows'])) { - $attribs['rows'] = (int) $this->rows; - } - if (empty($attribs['cols'])) { - $attribs['cols'] = (int) $this->cols; - } - - // build the element - $xhtml = ''; - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/Gravatar.php b/lib/Zend/View/Helper/Gravatar.php deleted file mode 100644 index 85d7b565fa5..00000000000 --- a/lib/Zend/View/Helper/Gravatar.php +++ /dev/null @@ -1,363 +0,0 @@ - 80, - 'default_img' => self::DEFAULT_MM, - 'rating' => self::RATING_G, - 'secure' => null, - ); - - /** - * Email Adress - * - * @var string - */ - protected $_email; - - /** - * Attributes for HTML image tag - * - * @var array - */ - protected $_attribs; - - /** - * Returns an avatar from gravatar's service. - * - * $options may include the following: - * - 'img_size' int height of img to return - * - 'default_img' string img to return if email adress has not found - * - 'rating' string rating parameter for avatar - * - 'secure' bool load from the SSL or Non-SSL location - * - * @see http://pl.gravatar.com/site/implement/url - * @see http://pl.gravatar.com/site/implement/url More information about gravatar's service. - * @param string|null $email Email adress. - * @param null|array $options Options - * @param array $attribs Attributes for image tag (title, alt etc.) - * @return Zend_View_Helper_Gravatar - */ - public function gravatar($email = "", $options = array(), $attribs = array()) - { - $this->setEmail($email); - $this->setOptions($options); - $this->setAttribs($attribs); - return $this; - } - - /** - * Configure state - * - * @param array $options - * @return Zend_View_Helper_Gravatar - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - $method = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); - if (method_exists($this, $method)) { - $this->{$method}($value); - } - } - return $this; - } - - /** - * Get img size - * - * @return int The img size - */ - public function getImgSize() - { - return $this->_options['img_size']; - } - - /** - * Set img size in pixels - * - * @param int $imgSize Size of img must be between 1 and 512 - * @return Zend_View_Helper_Gravatar - */ - public function setImgSize($imgSize) - { - $this->_options['img_size'] = (int) $imgSize; - return $this; - } - - /** - * Get default img - * - * @return string - */ - public function getDefaultImg() - { - return $this->_options['default_img']; - } - - /** - * Set default img - * - * Can be either an absolute URL to an image, or one of the DEFAULT_* constants - * - * @param string $defaultImg - * @link http://pl.gravatar.com/site/implement/url More information about default image. - * @return Zend_View_Helper_Gravatar - */ - public function setDefaultImg($defaultImg) - { - $this->_options['default_img'] = urlencode($defaultImg); - return $this; - } - - /** - * Set rating value - * - * Must be one of the RATING_* constants - * - * @param string $rating Value for rating. Allowed values are: g, px, r,x - * @link http://pl.gravatar.com/site/implement/url More information about rating. - * @throws Zend_View_Exception - */ - public function setRating($rating) - { - switch ($rating) { - case self::RATING_G: - case self::RATING_PG: - case self::RATING_R: - case self::RATING_X: - $this->_options['rating'] = $rating; - break; - default: - #require_once 'Zend/View/Exception.php'; - throw new Zend_View_Exception(sprintf( - 'The rating value "%s" is not allowed', - $rating - )); - } - return $this; - } - - /** - * Get rating value - * - * @return string - */ - public function getRating() - { - return $this->_options['rating']; - } - - /** - * Set email adress - * - * @param string $email - * @return Zend_View_Helper_Gravatar - */ - public function setEmail( $email ) - { - $this->_email = $email; - return $this; - } - - /** - * Get email adress - * - * @return string - */ - public function getEmail() - { - return $this->_email; - } - - /** - * Load from an SSL or No-SSL location? - * - * @param bool $flag - * @return Zend_View_Helper_Gravatar - */ - public function setSecure($flag) - { - $this->_options['secure'] = ($flag === null) ? null : (bool) $flag; - return $this; - } - - /** - * Get an SSL or a No-SSL location - * - * @return bool - */ - public function getSecure() - { - if ($this->_options['secure'] === null) { - return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); - } - return $this->_options['secure']; - } - - /** - * Get attribs of image - * - * Warning! - * If you set src attrib, you get it, but this value will be overwritten in - * protected method _setSrcAttribForImg(). And finally your get other src - * value! - * - * @return array - */ - public function getAttribs() - { - return $this->_attribs; - } - - /** - * Set attribs for image tag - * - * Warning! You shouldn't set src attrib for image tag. - * This attrib is overwritten in protected method _setSrcAttribForImg(). - * This method(_setSrcAttribForImg) is called in public method getImgTag(). - - * @param array $attribs - * @return Zend_View_Helper_Gravatar - */ - public function setAttribs(array $attribs) - { - $this->_attribs = $attribs; - return $this; - } - - /** - * Get URL to gravatar's service. - * - * @return string URL - */ - protected function _getGravatarUrl() - { - return ($this->getSecure() === false) ? self::GRAVATAR_URL : self::GRAVATAR_URL_SECURE; - } - - /** - * Get avatar url (including size, rating and default image oprions) - * - * @return string - */ - protected function _getAvatarUrl() - { - $src = $this->_getGravatarUrl() - . '/' - . md5(strtolower(trim($this->getEmail()))) - . '?s=' - . $this->getImgSize() - . '&d=' - . $this->getDefaultImg() - . '&r=' - . $this->getRating(); - return $src; - } - - /** - * Set src attrib for image. - * - * You shouldn't set a own url value! - * It sets value, uses protected method _getAvatarUrl. - * - * If already exsist overwritten. - */ - protected function _setSrcAttribForImg() - { - $attribs = $this->getAttribs(); - $attribs['src'] = $this->_getAvatarUrl(); - $this->setAttribs($attribs); - } - - /** - * Return valid image tag - * - * @return string - */ - public function getImgTag() - { - $this->_setSrcAttribForImg(); - $html = '_htmlAttribs($this->getAttribs()) - . $this->getClosingBracket(); - - return $html; - } - - /** - * Return valid image tag - * - * @return string - */ - public function __toString() - { - return $this->getImgTag(); - - } -} diff --git a/lib/Zend/View/Helper/HeadLink.php b/lib/Zend/View/Helper/HeadLink.php deleted file mode 100644 index fd6e180111b..00000000000 --- a/lib/Zend/View/Helper/HeadLink.php +++ /dev/null @@ -1,478 +0,0 @@ -setSeparator(PHP_EOL); - } - - /** - * headLink() - View Helper Method - * - * Returns current object instance. Optionally, allows passing array of - * values to build link. - * - * @return Zend_View_Helper_HeadLink - */ - public function headLink(array $attributes = null, $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) - { - if (null !== $attributes) { - $item = $this->createData($attributes); - switch ($placement) { - case Zend_View_Helper_Placeholder_Container_Abstract::SET: - $this->set($item); - break; - case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: - $this->prepend($item); - break; - case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: - default: - $this->append($item); - break; - } - } - return $this; - } - - /** - * Overload method access - * - * Creates the following virtual methods: - * - appendStylesheet($href, $media, $conditionalStylesheet, $extras) - * - offsetSetStylesheet($index, $href, $media, $conditionalStylesheet, $extras) - * - prependStylesheet($href, $media, $conditionalStylesheet, $extras) - * - setStylesheet($href, $media, $conditionalStylesheet, $extras) - * - appendAlternate($href, $type, $title, $extras) - * - offsetSetAlternate($index, $href, $type, $title, $extras) - * - prependAlternate($href, $type, $title, $extras) - * - setAlternate($href, $type, $title, $extras) - * - * Items that may be added in the future: - * - Navigation? need to find docs on this - * - public function appendStart() - * - public function appendContents() - * - public function appendPrev() - * - public function appendNext() - * - public function appendIndex() - * - public function appendEnd() - * - public function appendGlossary() - * - public function appendAppendix() - * - public function appendHelp() - * - public function appendBookmark() - * - Other? - * - public function appendCopyright() - * - public function appendChapter() - * - public function appendSection() - * - public function appendSubsection() - * - * @param mixed $method - * @param mixed $args - * @return void - */ - public function __call($method, $args) - { - if (preg_match('/^(?Pset|(ap|pre)pend|offsetSet)(?PStylesheet|Alternate)$/', $method, $matches)) { - $argc = count($args); - $action = $matches['action']; - $type = $matches['type']; - $index = null; - - if ('offsetSet' == $action) { - if (0 < $argc) { - $index = array_shift($args); - --$argc; - } - } - - if (1 > $argc) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('%s requires at least one argument', $method)); - $e->setView($this->view); - throw $e; - } - - if (is_array($args[0])) { - $item = $this->createData($args[0]); - } else { - $dataMethod = 'createData' . $type; - $item = $this->$dataMethod($args); - } - - if ($item) { - if ('offsetSet' == $action) { - $this->offsetSet($index, $item); - } else { - $this->$action($item); - } - } - - return $this; - } - - return parent::__call($method, $args); - } - - /** - * Check if value is valid - * - * @param mixed $value - * @return boolean - */ - protected function _isValid($value) - { - if (!$value instanceof stdClass) { - return false; - } - - $vars = get_object_vars($value); - $keys = array_keys($vars); - $intersection = array_intersect($this->_itemKeys, $keys); - if (empty($intersection)) { - return false; - } - - return true; - } - - /** - * append() - * - * @param array $value - * @return void - */ - public function append($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('append() expects a data token; please use one of the custom append*() methods'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->append($value); - } - - /** - * offsetSet() - * - * @param string|int $index - * @param array $value - * @return void - */ - public function offsetSet($index, $value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('offsetSet() expects a data token; please use one of the custom offsetSet*() methods'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->offsetSet($index, $value); - } - - /** - * prepend() - * - * @param array $value - * @return Zend_Layout_ViewHelper_HeadLink - */ - public function prepend($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('prepend() expects a data token; please use one of the custom prepend*() methods'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->prepend($value); - } - - /** - * set() - * - * @param array $value - * @return Zend_Layout_ViewHelper_HeadLink - */ - public function set($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('set() expects a data token; please use one of the custom set*() methods'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->set($value); - } - - - /** - * Create HTML link element from data item - * - * @param stdClass $item - * @return string - */ - public function itemToString(stdClass $item) - { - $attributes = (array) $item; - $link = '_itemKeys as $itemKey) { - if (isset($attributes[$itemKey])) { - if(is_array($attributes[$itemKey])) { - foreach($attributes[$itemKey] as $key => $value) { - $link .= sprintf('%s="%s" ', $key, ($this->_autoEscape) ? $this->_escape($value) : $value); - } - } else { - $link .= sprintf('%s="%s" ', $itemKey, ($this->_autoEscape) ? $this->_escape($attributes[$itemKey]) : $attributes[$itemKey]); - } - } - } - - if ($this->view instanceof Zend_View_Abstract) { - $link .= ($this->view->doctype()->isXhtml()) ? '/>' : '>'; - } else { - $link .= '/>'; - } - - if (($link == '') || ($link == '')) { - return ''; - } - - if (isset($attributes['conditionalStylesheet']) - && !empty($attributes['conditionalStylesheet']) - && is_string($attributes['conditionalStylesheet'])) - { - if (str_replace(' ', '', $attributes['conditionalStylesheet']) === '!IE') { - $link = '' . $link . ''; - } - - return $link; - } - - /** - * Render link elements as string - * - * @param string|int $indent - * @return string - */ - public function toString($indent = null) - { - $indent = (null !== $indent) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - $items = array(); - $this->getContainer()->ksort(); - foreach ($this as $item) { - $items[] = $this->itemToString($item); - } - - return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items); - } - - /** - * Create data item for stack - * - * @param array $attributes - * @return stdClass - */ - public function createData(array $attributes) - { - $data = (object) $attributes; - return $data; - } - - /** - * Create item for stylesheet link item - * - * @param array $args - * @return stdClass|false Returns fals if stylesheet is a duplicate - */ - public function createDataStylesheet(array $args) - { - $rel = 'stylesheet'; - $type = 'text/css'; - $media = 'screen'; - $conditionalStylesheet = false; - $href = array_shift($args); - - if ($this->_isDuplicateStylesheet($href)) { - return false; - } - - if (0 < count($args)) { - $media = array_shift($args); - if(is_array($media)) { - $media = implode(',', $media); - } else { - $media = (string) $media; - } - } - if (0 < count($args)) { - $conditionalStylesheet = array_shift($args); - if(!empty($conditionalStylesheet) && is_string($conditionalStylesheet)) { - $conditionalStylesheet = (string) $conditionalStylesheet; - } else { - $conditionalStylesheet = null; - } - } - - if(0 < count($args) && is_array($args[0])) { - $extras = array_shift($args); - $extras = (array) $extras; - } - - $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet', 'extras'); - return $this->createData($this->_applyExtras($attributes)); - } - - /** - * Is the linked stylesheet a duplicate? - * - * @param string $uri - * @return bool - */ - protected function _isDuplicateStylesheet($uri) - { - foreach ($this->getContainer() as $item) { - if (($item->rel == 'stylesheet') && ($item->href == $uri)) { - return true; - } - } - return false; - } - - /** - * Create item for alternate link item - * - * @param array $args - * @return stdClass - */ - public function createDataAlternate(array $args) - { - if (3 > count($args)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Alternate tags require 3 arguments; %s provided', count($args))); - $e->setView($this->view); - throw $e; - } - - $rel = 'alternate'; - $href = array_shift($args); - $type = array_shift($args); - $title = array_shift($args); - - if(0 < count($args) && is_array($args[0])) { - $extras = array_shift($args); - $extras = (array) $extras; - - if(isset($extras['media']) && is_array($extras['media'])) { - $extras['media'] = implode(',', $extras['media']); - } - } - - $href = (string) $href; - $type = (string) $type; - $title = (string) $title; - - $attributes = compact('rel', 'href', 'type', 'title', 'extras'); - return $this->createData($this->_applyExtras($attributes)); - } - - /** - * Apply any overrides specified in the 'extras' array - * @param array $attributes - * @return array - */ - protected function _applyExtras($attributes) - { - if (isset($attributes['extras'])) { - foreach ($attributes['extras'] as $eKey=>$eVal) { - if (isset($attributes[$eKey])) { - $attributes[$eKey] = $eVal; - unset($attributes['extras'][$eKey]); - } - } - } - return $attributes; - } -} diff --git a/lib/Zend/View/Helper/HeadMeta.php b/lib/Zend/View/Helper/HeadMeta.php deleted file mode 100644 index c589987a6b4..00000000000 --- a/lib/Zend/View/Helper/HeadMeta.php +++ /dev/null @@ -1,449 +0,0 @@ -setSeparator(PHP_EOL); - } - - /** - * Retrieve object instance; optionally add meta tag - * - * @param string $content - * @param string $keyValue - * @param string $keyType - * @param array $modifiers - * @param string $placement - * @return Zend_View_Helper_HeadMeta - */ - public function headMeta($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) - { - if ((null !== $content) && (null !== $keyValue)) { - $item = $this->createData($keyType, $keyValue, $content, $modifiers); - $action = strtolower($placement); - switch ($action) { - case 'append': - case 'prepend': - case 'set': - $this->$action($item); - break; - default: - $this->append($item); - break; - } - } - - return $this; - } - - protected function _normalizeType($type) - { - switch ($type) { - case 'Name': - return 'name'; - case 'HttpEquiv': - return 'http-equiv'; - case 'Property': - return 'property'; - default: - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Invalid type "%s" passed to _normalizeType', $type)); - $e->setView($this->view); - throw $e; - } - } - - /** - * Overload method access - * - * Allows the following 'virtual' methods: - * - appendName($keyValue, $content, $modifiers = array()) - * - offsetGetName($index, $keyValue, $content, $modifers = array()) - * - prependName($keyValue, $content, $modifiers = array()) - * - setName($keyValue, $content, $modifiers = array()) - * - appendHttpEquiv($keyValue, $content, $modifiers = array()) - * - offsetGetHttpEquiv($index, $keyValue, $content, $modifers = array()) - * - prependHttpEquiv($keyValue, $content, $modifiers = array()) - * - setHttpEquiv($keyValue, $content, $modifiers = array()) - * - appendProperty($keyValue, $content, $modifiers = array()) - * - offsetGetProperty($index, $keyValue, $content, $modifiers = array()) - * - prependProperty($keyValue, $content, $modifiers = array()) - * - setProperty($keyValue, $content, $modifiers = array()) - * - * @param string $method - * @param array $args - * @return Zend_View_Helper_HeadMeta - */ - public function __call($method, $args) - { - if (preg_match('/^(?Pset|(pre|ap)pend|offsetSet)(?PName|HttpEquiv|Property)$/', $method, $matches)) { - $action = $matches['action']; - $type = $this->_normalizeType($matches['type']); - $argc = count($args); - $index = null; - - if ('offsetSet' == $action) { - if (0 < $argc) { - $index = array_shift($args); - --$argc; - } - } - - if (2 > $argc) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Too few arguments provided; requires key value, and content'); - $e->setView($this->view); - throw $e; - } - - if (3 > $argc) { - $args[] = array(); - } - - $item = $this->createData($type, $args[0], $args[1], $args[2]); - - if ('offsetSet' == $action) { - return $this->offsetSet($index, $item); - } - - $this->$action($item); - return $this; - } - - return parent::__call($method, $args); - } - - /** - * Create an HTML5-style meta charset tag. Something like - * - * Not valid in a non-HTML5 doctype - * - * @param string $charset - * @return Zend_View_Helper_HeadMeta Provides a fluent interface - */ - public function setCharset($charset) - { - $item = new stdClass; - $item->type = 'charset'; - $item->charset = $charset; - $item->content = null; - $item->modifiers = array(); - $this->set($item); - return $this; - } - - /** - * Determine if item is valid - * - * @param mixed $item - * @return boolean - */ - protected function _isValid($item) - { - if ((!$item instanceof stdClass) - || !isset($item->type) - || !isset($item->modifiers)) - { - return false; - } - - $isHtml5 = is_null($this->view) ? false : $this->view->doctype()->isHtml5(); - - if (!isset($item->content) - && (! $isHtml5 || (! $isHtml5 && $item->type !== 'charset'))) { - return false; - } - - // is only supported with doctype RDFa - if ( !is_null($this->view) && !$this->view->doctype()->isRdfa() - && $item->type === 'property') { - return false; - } - - return true; - } - - /** - * Append - * - * @param string $value - * @return void - * @throws Zend_View_Exception - */ - public function append($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to append; please use appendMeta()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->append($value); - } - - /** - * OffsetSet - * - * @param string|int $index - * @param string $value - * @return void - * @throws Zend_View_Exception - */ - public function offsetSet($index, $value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetName() or offsetSetHttpEquiv()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->offsetSet($index, $value); - } - - /** - * OffsetUnset - * - * @param string|int $index - * @return void - * @throws Zend_View_Exception - */ - public function offsetUnset($index) - { - if (!in_array($index, $this->getContainer()->getKeys())) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid index passed to offsetUnset()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->offsetUnset($index); - } - - /** - * Prepend - * - * @param string $value - * @return void - * @throws Zend_View_Exception - */ - public function prepend($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to prepend; please use prependMeta()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->prepend($value); - } - - /** - * Set - * - * @param string $value - * @return void - * @throws Zend_View_Exception - */ - public function set($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to set; please use setMeta()'); - $e->setView($this->view); - throw $e; - } - - $container = $this->getContainer(); - foreach ($container->getArrayCopy() as $index => $item) { - if ($item->type == $value->type && $item->{$item->type} == $value->{$value->type}) { - $this->offsetUnset($index); - } - } - - return $this->append($value); - } - - /** - * Build meta HTML string - * - * @param string $type - * @param string $typeValue - * @param string $content - * @param array $modifiers - * @return string - */ - public function itemToString(stdClass $item) - { - if (!in_array($item->type, $this->_typeKeys)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Invalid type "%s" provided for meta', $item->type)); - $e->setView($this->view); - throw $e; - } - $type = $item->type; - - $modifiersString = ''; - foreach ($item->modifiers as $key => $value) { - if (!is_null($this->view) && $this->view->doctype()->isHtml5() - && $key == 'scheme') { - #require_once 'Zend/View/Exception.php'; - throw new Zend_View_Exception('Invalid modifier ' - . '"scheme" provided; not supported by HTML5'); - } - if (!in_array($key, $this->_modifierKeys)) { - continue; - } - $modifiersString .= $key . '="' . $this->_escape($value) . '" '; - } - - if ($this->view instanceof Zend_View_Abstract) { - if ($this->view->doctype()->isHtml5() - && $type == 'charset') { - $tpl = ($this->view->doctype()->isXhtml()) - ? '' - : ''; - } elseif ($this->view->doctype()->isXhtml()) { - $tpl = ''; - } else { - $tpl = ''; - } - } else { - $tpl = ''; - } - - $meta = sprintf( - $tpl, - $type, - $this->_escape($item->$type), - $this->_escape($item->content), - $modifiersString - ); - - if (isset($item->modifiers['conditional']) - && !empty($item->modifiers['conditional']) - && is_string($item->modifiers['conditional'])) - { - if (str_replace(' ', '', $item->modifiers['conditional']) === '!IE') { - $meta = '' . $meta . ''; - } - - return $meta; - } - - /** - * Render placeholder as string - * - * @param string|int $indent - * @return string - */ - public function toString($indent = null) - { - $indent = (null !== $indent) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - $items = array(); - $this->getContainer()->ksort(); - try { - foreach ($this as $item) { - $items[] = $this->itemToString($item); - } - } catch (Zend_View_Exception $e) { - trigger_error($e->getMessage(), E_USER_WARNING); - return ''; - } - return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items); - } - - /** - * Create data item for inserting into stack - * - * @param string $type - * @param string $typeValue - * @param string $content - * @param array $modifiers - * @return stdClass - */ - public function createData($type, $typeValue, $content, array $modifiers) - { - $data = new stdClass; - $data->type = $type; - $data->$type = $typeValue; - $data->content = $content; - $data->modifiers = $modifiers; - return $data; - } -} diff --git a/lib/Zend/View/Helper/HeadScript.php b/lib/Zend/View/Helper/HeadScript.php deleted file mode 100644 index 83235a7f188..00000000000 --- a/lib/Zend/View/Helper/HeadScript.php +++ /dev/null @@ -1,520 +0,0 @@ -setSeparator(PHP_EOL); - } - - /** - * Return headScript object - * - * Returns headScript helper object; optionally, allows specifying a script - * or script file to include. - * - * @param string $mode Script or file - * @param string $spec Script/url - * @param string $placement Append, prepend, or set - * @param array $attrs Array of script attributes - * @param string $type Script type and/or array of script attributes - * @return Zend_View_Helper_HeadScript - */ - public function headScript($mode = Zend_View_Helper_HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') - { - if ((null !== $spec) && is_string($spec)) { - $action = ucfirst(strtolower($mode)); - $placement = strtolower($placement); - switch ($placement) { - case 'set': - case 'prepend': - case 'append': - $action = $placement . $action; - break; - default: - $action = 'append' . $action; - break; - } - $this->$action($spec, $type, $attrs); - } - - return $this; - } - - /** - * Start capture action - * - * @param mixed $captureType - * @param string $typeOrAttrs - * @return void - */ - public function captureStart($captureType = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $type = 'text/javascript', $attrs = array()) - { - if ($this->_captureLock) { - #require_once 'Zend/View/Helper/Placeholder/Container/Exception.php'; - $e = new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest headScript captures'); - $e->setView($this->view); - throw $e; - } - - $this->_captureLock = true; - $this->_captureType = $captureType; - $this->_captureScriptType = $type; - $this->_captureScriptAttrs = $attrs; - ob_start(); - } - - /** - * End capture action and store - * - * @return void - */ - public function captureEnd() - { - $content = ob_get_clean(); - $type = $this->_captureScriptType; - $attrs = $this->_captureScriptAttrs; - $this->_captureScriptType = null; - $this->_captureScriptAttrs = null; - $this->_captureLock = false; - - switch ($this->_captureType) { - case Zend_View_Helper_Placeholder_Container_Abstract::SET: - case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: - case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: - $action = strtolower($this->_captureType) . 'Script'; - break; - default: - $action = 'appendScript'; - break; - } - $this->$action($content, $type, $attrs); - } - - /** - * Overload method access - * - * Allows the following method calls: - * - appendFile($src, $type = 'text/javascript', $attrs = array()) - * - offsetSetFile($index, $src, $type = 'text/javascript', $attrs = array()) - * - prependFile($src, $type = 'text/javascript', $attrs = array()) - * - setFile($src, $type = 'text/javascript', $attrs = array()) - * - appendScript($script, $type = 'text/javascript', $attrs = array()) - * - offsetSetScript($index, $src, $type = 'text/javascript', $attrs = array()) - * - prependScript($script, $type = 'text/javascript', $attrs = array()) - * - setScript($script, $type = 'text/javascript', $attrs = array()) - * - * @param string $method - * @param array $args - * @return Zend_View_Helper_HeadScript - * @throws Zend_View_Exception if too few arguments or invalid method - */ - public function __call($method, $args) - { - if (preg_match('/^(?Pset|(ap|pre)pend|offsetSet)(?PFile|Script)$/', $method, $matches)) { - if (1 > count($args)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Method "%s" requires at least one argument', $method)); - $e->setView($this->view); - throw $e; - } - - $action = $matches['action']; - $mode = strtolower($matches['mode']); - $type = 'text/javascript'; - $attrs = array(); - - if ('offsetSet' == $action) { - $index = array_shift($args); - if (1 > count($args)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Method "%s" requires at least two arguments, an index and source', $method)); - $e->setView($this->view); - throw $e; - } - } - - $content = $args[0]; - - if (isset($args[1])) { - $type = (string) $args[1]; - } - if (isset($args[2])) { - $attrs = (array) $args[2]; - } - - switch ($mode) { - case 'script': - $item = $this->createData($type, $attrs, $content); - if ('offsetSet' == $action) { - $this->offsetSet($index, $item); - } else { - $this->$action($item); - } - break; - case 'file': - default: - if (!$this->_isDuplicate($content) || $action=='set') { - $attrs['src'] = $content; - $item = $this->createData($type, $attrs); - if ('offsetSet' == $action) { - $this->offsetSet($index, $item); - } else { - $this->$action($item); - } - } - break; - } - - return $this; - } - - return parent::__call($method, $args); - } - - /** - * Is the file specified a duplicate? - * - * @param string $file - * @return bool - */ - protected function _isDuplicate($file) - { - foreach ($this->getContainer() as $item) { - if (($item->source === null) - && array_key_exists('src', $item->attributes) - && ($file == $item->attributes['src'])) - { - return true; - } - } - return false; - } - - /** - * Is the script provided valid? - * - * @param mixed $value - * @param string $method - * @return bool - */ - protected function _isValid($value) - { - if ((!$value instanceof stdClass) - || !isset($value->type) - || (!isset($value->source) && !isset($value->attributes))) - { - return false; - } - - return true; - } - - /** - * Override append - * - * @param string $value - * @return void - */ - public function append($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid argument passed to append(); please use one of the helper methods, appendScript() or appendFile()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->append($value); - } - - /** - * Override prepend - * - * @param string $value - * @return void - */ - public function prepend($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid argument passed to prepend(); please use one of the helper methods, prependScript() or prependFile()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->prepend($value); - } - - /** - * Override set - * - * @param string $value - * @return void - */ - public function set($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid argument passed to set(); please use one of the helper methods, setScript() or setFile()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->set($value); - } - - /** - * Override offsetSet - * - * @param string|int $index - * @param mixed $value - * @return void - */ - public function offsetSet($index, $value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid argument passed to offsetSet(); please use one of the helper methods, offsetSetScript() or offsetSetFile()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->offsetSet($index, $value); - } - - /** - * Set flag indicating if arbitrary attributes are allowed - * - * @param bool $flag - * @return Zend_View_Helper_HeadScript - */ - public function setAllowArbitraryAttributes($flag) - { - $this->_arbitraryAttributes = (bool) $flag; - return $this; - } - - /** - * Are arbitrary attributes allowed? - * - * @return bool - */ - public function arbitraryAttributesAllowed() - { - return $this->_arbitraryAttributes; - } - - /** - * Create script HTML - * - * @param string $type - * @param array $attributes - * @param string $content - * @param string|int $indent - * @return string - */ - public function itemToString($item, $indent, $escapeStart, $escapeEnd) - { - $attrString = ''; - if (!empty($item->attributes)) { - foreach ($item->attributes as $key => $value) { - if ((!$this->arbitraryAttributesAllowed() && !in_array($key, $this->_optionalAttributes)) - || in_array($key, array('conditional', 'noescape'))) - { - continue; - } - if ('defer' == $key) { - $value = 'defer'; - } - $attrString .= sprintf(' %s="%s"', $key, ($this->_autoEscape) ? $this->_escape($value) : $value); - } - } - - $addScriptEscape = !(isset($item->attributes['noescape']) && filter_var($item->attributes['noescape'], FILTER_VALIDATE_BOOLEAN)); - - $type = ($this->_autoEscape) ? $this->_escape($item->type) : $item->type; - $html = ''; - - if (isset($item->attributes['conditional']) - && !empty($item->attributes['conditional']) - && is_string($item->attributes['conditional'])) - { - // inner wrap with comment end and start if !IE - if (str_replace(' ', '', $item->attributes['conditional']) === '!IE') { - $html = '' . $html . ''; - } else { - $html = $indent . $html; - } - - return $html; - } - - /** - * Retrieve string representation - * - * @param string|int $indent - * @return string - */ - public function toString($indent = null) - { - $indent = (null !== $indent) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - if ($this->view) { - $useCdata = $this->view->doctype()->isXhtml() ? true : false; - } else { - $useCdata = $this->useCdata ? true : false; - } - $escapeStart = ($useCdata) ? '//' : '//-->'; - - $items = array(); - $this->getContainer()->ksort(); - foreach ($this as $item) { - if (!$this->_isValid($item)) { - continue; - } - - $items[] = $this->itemToString($item, $indent, $escapeStart, $escapeEnd); - } - - $return = implode($this->getSeparator(), $items); - return $return; - } - - /** - * Create data item containing all necessary components of script - * - * @param string $type - * @param array $attributes - * @param string $content - * @return stdClass - */ - public function createData($type, array $attributes, $content = null) - { - $data = new stdClass(); - $data->type = $type; - $data->attributes = $attributes; - $data->source = $content; - return $data; - } -} diff --git a/lib/Zend/View/Helper/HeadStyle.php b/lib/Zend/View/Helper/HeadStyle.php deleted file mode 100644 index de54cf97631..00000000000 --- a/lib/Zend/View/Helper/HeadStyle.php +++ /dev/null @@ -1,433 +0,0 @@ -setSeparator(PHP_EOL); - } - - /** - * Return headStyle object - * - * Returns headStyle helper object; optionally, allows specifying - * - * @param string $content Stylesheet contents - * @param string $placement Append, prepend, or set - * @param string|array $attributes Optional attributes to utilize - * @return Zend_View_Helper_HeadStyle - */ - public function headStyle($content = null, $placement = 'APPEND', $attributes = array()) - { - if ((null !== $content) && is_string($content)) { - switch (strtoupper($placement)) { - case 'SET': - $action = 'setStyle'; - break; - case 'PREPEND': - $action = 'prependStyle'; - break; - case 'APPEND': - default: - $action = 'appendStyle'; - break; - } - $this->$action($content, $attributes); - } - - return $this; - } - - /** - * Overload method calls - * - * Allows the following method calls: - * - appendStyle($content, $attributes = array()) - * - offsetSetStyle($index, $content, $attributes = array()) - * - prependStyle($content, $attributes = array()) - * - setStyle($content, $attributes = array()) - * - * @param string $method - * @param array $args - * @return void - * @throws Zend_View_Exception When no $content provided or invalid method - */ - public function __call($method, $args) - { - if (preg_match('/^(?Pset|(ap|pre)pend|offsetSet)(Style)$/', $method, $matches)) { - $index = null; - $argc = count($args); - $action = $matches['action']; - - if ('offsetSet' == $action) { - if (0 < $argc) { - $index = array_shift($args); - --$argc; - } - } - - if (1 > $argc) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf('Method "%s" requires minimally content for the stylesheet', $method)); - $e->setView($this->view); - throw $e; - } - - $content = $args[0]; - $attrs = array(); - if (isset($args[1])) { - $attrs = (array) $args[1]; - } - - $item = $this->createData($content, $attrs); - - if ('offsetSet' == $action) { - $this->offsetSet($index, $item); - } else { - $this->$action($item); - } - - return $this; - } - - return parent::__call($method, $args); - } - - /** - * Determine if a value is a valid style tag - * - * @param mixed $value - * @param string $method - * @return boolean - */ - protected function _isValid($value) - { - if ((!$value instanceof stdClass) - || !isset($value->content) - || !isset($value->attributes)) - { - return false; - } - - return true; - } - - /** - * Override append to enforce style creation - * - * @param mixed $value - * @return void - */ - public function append($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to append; please use appendStyle()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->append($value); - } - - /** - * Override offsetSet to enforce style creation - * - * @param string|int $index - * @param mixed $value - * @return void - */ - public function offsetSet($index, $value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetStyle()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->offsetSet($index, $value); - } - - /** - * Override prepend to enforce style creation - * - * @param mixed $value - * @return void - */ - public function prepend($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to prepend; please use prependStyle()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->prepend($value); - } - - /** - * Override set to enforce style creation - * - * @param mixed $value - * @return void - */ - public function set($value) - { - if (!$this->_isValid($value)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Invalid value passed to set; please use setStyle()'); - $e->setView($this->view); - throw $e; - } - - return $this->getContainer()->set($value); - } - - /** - * Start capture action - * - * @param mixed $captureType - * @param string $typeOrAttrs - * @return void - */ - public function captureStart($type = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $attrs = null) - { - if ($this->_captureLock) { - #require_once 'Zend/View/Helper/Placeholder/Container/Exception.php'; - $e = new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest headStyle captures'); - $e->setView($this->view); - throw $e; - } - - $this->_captureLock = true; - $this->_captureAttrs = $attrs; - $this->_captureType = $type; - ob_start(); - } - - /** - * End capture action and store - * - * @return void - */ - public function captureEnd() - { - $content = ob_get_clean(); - $attrs = $this->_captureAttrs; - $this->_captureAttrs = null; - $this->_captureLock = false; - - switch ($this->_captureType) { - case Zend_View_Helper_Placeholder_Container_Abstract::SET: - $this->setStyle($content, $attrs); - break; - case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: - $this->prependStyle($content, $attrs); - break; - case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: - default: - $this->appendStyle($content, $attrs); - break; - } - } - - /** - * Convert content and attributes into valid style tag - * - * @param stdClass $item Item to render - * @param string $indent Indentation to use - * @return string - */ - public function itemToString(stdClass $item, $indent) - { - $attrString = ''; - if (!empty($item->attributes)) { - $enc = 'UTF-8'; - if ($this->view instanceof Zend_View_Interface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - foreach ($item->attributes as $key => $value) { - if (!in_array($key, $this->_optionalAttributes)) { - continue; - } - if ('media' == $key) { - if(false === strpos($value, ',')) { - if (!in_array($value, $this->_mediaTypes)) { - continue; - } - } else { - $media_types = explode(',', $value); - $value = ''; - foreach($media_types as $type) { - $type = trim($type); - if (!in_array($type, $this->_mediaTypes)) { - continue; - } - $value .= $type .','; - } - $value = substr($value, 0, -1); - } - } - $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, $enc)); - } - } - - $escapeStart = $indent . ''. PHP_EOL; - if (isset($item->attributes['conditional']) - && !empty($item->attributes['conditional']) - && is_string($item->attributes['conditional']) - ) { - $escapeStart = null; - $escapeEnd = null; - } - - $html = ''; - - if (null == $escapeStart && null == $escapeEnd) { - if (str_replace(' ', '', $item->attributes['conditional']) === '!IE') { - $html = '' . $html . ''; - } - - return $html; - } - - /** - * Create string representation of placeholder - * - * @param string|int $indent - * @return string - */ - public function toString($indent = null) - { - $indent = (null !== $indent) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - $items = array(); - $this->getContainer()->ksort(); - foreach ($this as $item) { - if (!$this->_isValid($item)) { - continue; - } - $items[] = $this->itemToString($item, $indent); - } - - $return = $indent . implode($this->getSeparator() . $indent, $items); - $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return); - return $return; - } - - /** - * Create data item for use in stack - * - * @param string $content - * @param array $attributes - * @return stdClass - */ - public function createData($content, array $attributes) - { - if (!isset($attributes['media'])) { - $attributes['media'] = 'screen'; - } else if(is_array($attributes['media'])) { - $attributes['media'] = implode(',', $attributes['media']); - } - - $data = new stdClass(); - $data->content = $content; - $data->attributes = $attributes; - - return $data; - } -} diff --git a/lib/Zend/View/Helper/HeadTitle.php b/lib/Zend/View/Helper/HeadTitle.php deleted file mode 100644 index 6c24ee91ba5..00000000000 --- a/lib/Zend/View/Helper/HeadTitle.php +++ /dev/null @@ -1,222 +0,0 @@ -getDefaultAttachOrder()) - ? Zend_View_Helper_Placeholder_Container_Abstract::APPEND - : $this->getDefaultAttachOrder(); - } - $title = (string) $title; - if ($title !== '') { - if ($setType == Zend_View_Helper_Placeholder_Container_Abstract::SET) { - $this->set($title); - } elseif ($setType == Zend_View_Helper_Placeholder_Container_Abstract::PREPEND) { - $this->prepend($title); - } else { - $this->append($title); - } - } - - return $this; - } - - /** - * Set a default order to add titles - * - * @param string $setType - */ - public function setDefaultAttachOrder($setType) - { - if (!in_array($setType, array( - Zend_View_Helper_Placeholder_Container_Abstract::APPEND, - Zend_View_Helper_Placeholder_Container_Abstract::SET, - Zend_View_Helper_Placeholder_Container_Abstract::PREPEND - ))) { - #require_once 'Zend/View/Exception.php'; - throw new Zend_View_Exception("You must use a valid attach order: 'PREPEND', 'APPEND' or 'SET'"); - } - - $this->_defaultAttachOrder = $setType; - return $this; - } - - /** - * Get the default attach order, if any. - * - * @return mixed - */ - public function getDefaultAttachOrder() - { - return $this->_defaultAttachOrder; - } - - /** - * Sets a translation Adapter for translation - * - * @param Zend_Translate|Zend_Translate_Adapter $translate - * @return Zend_View_Helper_HeadTitle - */ - public function setTranslator($translate) - { - if ($translate instanceof Zend_Translate_Adapter) { - $this->_translator = $translate; - } elseif ($translate instanceof Zend_Translate) { - $this->_translator = $translate->getAdapter(); - } else { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception("You must set an instance of Zend_Translate or Zend_Translate_Adapter"); - $e->setView($this->view); - throw $e; - } - return $this; - } - - /** - * Retrieve translation object - * - * If none is currently registered, attempts to pull it from the registry - * using the key 'Zend_Translate'. - * - * @return Zend_Translate_Adapter|null - */ - public function getTranslator() - { - if (null === $this->_translator) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Translate')) { - $this->setTranslator(Zend_Registry::get('Zend_Translate')); - } - } - return $this->_translator; - } - - /** - * Enables translation - * - * @return Zend_View_Helper_HeadTitle - */ - public function enableTranslation() - { - $this->_translate = true; - return $this; - } - - /** - * Disables translation - * - * @return Zend_View_Helper_HeadTitle - */ - public function disableTranslation() - { - $this->_translate = false; - return $this; - } - - /** - * Turn helper into string - * - * @param string|null $indent - * @param string|null $locale - * @return string - */ - public function toString($indent = null, $locale = null) - { - $indent = (null !== $indent) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - $items = array(); - - if($this->_translate && $translator = $this->getTranslator()) { - foreach ($this as $item) { - $items[] = $translator->translate($item, $locale); - } - } else { - foreach ($this as $item) { - $items[] = $item; - } - } - - $separator = $this->getSeparator(); - $output = ''; - if(($prefix = $this->getPrefix())) { - $output .= $prefix; - } - $output .= implode($separator, $items); - if(($postfix = $this->getPostfix())) { - $output .= $postfix; - } - - $output = ($this->_autoEscape) ? $this->_escape($output) : $output; - - return $indent . '' . $output . ''; - } -} diff --git a/lib/Zend/View/Helper/HtmlElement.php b/lib/Zend/View/Helper/HtmlElement.php deleted file mode 100644 index 394a23608ea..00000000000 --- a/lib/Zend/View/Helper/HtmlElement.php +++ /dev/null @@ -1,167 +0,0 @@ -_closingBracket) { - if ($this->_isXhtml()) { - $this->_closingBracket = ' />'; - } else { - $this->_closingBracket = '>'; - } - } - - return $this->_closingBracket; - } - - /** - * Is doctype XHTML? - * - * @return boolean - */ - protected function _isXhtml() - { - $doctype = $this->view->doctype(); - return $doctype->isXhtml(); - } - - /** - * Is doctype HTML5? - * - * @return boolean - */ - protected function _isHtml5() - { - $doctype = $this->view->doctype(); - return $doctype->isHtml5(); - } - - /** - * Is doctype strict? - * - * @return boolean - */ - protected function _isStrictDoctype() - { - $doctype = $this->view->doctype(); - return $doctype->isStrict(); - } - - /** - * Converts an associative array to a string of tag attributes. - * - * @access public - * - * @param array $attribs From this array, each key-value pair is - * converted to an attribute name and value. - * - * @return string The XHTML for the attributes. - */ - protected function _htmlAttribs($attribs) - { - $xhtml = ''; - foreach ((array) $attribs as $key => $val) { - $key = $this->view->escape($key); - - if (('on' == substr($key, 0, 2)) || ('constraints' == $key)) { - // Don't escape event attributes; _do_ substitute double quotes with singles - if (!is_scalar($val)) { - // non-scalar data should be cast to JSON first - #require_once 'Zend/Json.php'; - $val = Zend_Json::encode($val); - } - // Escape single quotes inside event attribute values. - // This will create html, where the attribute value has - // single quotes around it, and escaped single quotes or - // non-escaped double quotes inside of it - $val = str_replace('\'', ''', $val); - } else { - if (is_array($val)) { - $val = implode(' ', $val); - } - $val = $this->view->escape($val); - } - - if ('id' == $key) { - $val = $this->_normalizeId($val); - } - - if (strpos($val, '"') !== false) { - $xhtml .= " $key='$val'"; - } else { - $xhtml .= " $key=\"$val\""; - } - - } - return $xhtml; - } - - /** - * Normalize an ID - * - * @param string $value - * @return string - */ - protected function _normalizeId($value) - { - if (strstr($value, '[')) { - if ('[]' == substr($value, -2)) { - $value = substr($value, 0, strlen($value) - 2); - } - $value = trim($value, ']'); - $value = str_replace('][', '-', $value); - $value = str_replace('[', '-', $value); - } - return $value; - } -} diff --git a/lib/Zend/View/Helper/HtmlFlash.php b/lib/Zend/View/Helper/HtmlFlash.php deleted file mode 100644 index 9dc000c6518..00000000000 --- a/lib/Zend/View/Helper/HtmlFlash.php +++ /dev/null @@ -1,60 +0,0 @@ - $data, - 'quality' => 'high'), $params); - - return $this->htmlObject($data, self::TYPE, $attribs, $params, $content); - } -} diff --git a/lib/Zend/View/Helper/HtmlList.php b/lib/Zend/View/Helper/HtmlList.php deleted file mode 100644 index 188a8f1fe46..00000000000 --- a/lib/Zend/View/Helper/HtmlList.php +++ /dev/null @@ -1,90 +0,0 @@ -setView($this->view); - throw $e; - } - - $list = ''; - - foreach ($items as $item) { - if (!is_array($item)) { - if ($escape) { - $item = $this->view->escape($item); - } - $list .= '
  • ' . $item . '
  • ' . self::EOL; - } else { - if (6 < strlen($list)) { - $list = substr($list, 0, strlen($list) - 6) - . $this->htmlList($item, $ordered, $attribs, $escape) . '' . self::EOL; - } else { - $list .= '
  • ' . $this->htmlList($item, $ordered, $attribs, $escape) . '
  • ' . self::EOL; - } - } - } - - if ($attribs) { - $attribs = $this->_htmlAttribs($attribs); - } else { - $attribs = ''; - } - - $tag = 'ul'; - if ($ordered) { - $tag = 'ol'; - } - - return '<' . $tag . $attribs . '>' . self::EOL . $list . '' . self::EOL; - } -} diff --git a/lib/Zend/View/Helper/HtmlObject.php b/lib/Zend/View/Helper/HtmlObject.php deleted file mode 100644 index 732146fd4a3..00000000000 --- a/lib/Zend/View/Helper/HtmlObject.php +++ /dev/null @@ -1,80 +0,0 @@ - $data, - 'type' => $type), $attribs); - - // Params - $paramHtml = array(); - $closingBracket = $this->getClosingBracket(); - - foreach ($params as $param => $options) { - if (is_string($options)) { - $options = array('value' => $options); - } - - $options = array_merge(array('name' => $param), $options); - - $paramHtml[] = '_htmlAttribs($options) . $closingBracket; - } - - // Content - if (is_array($content)) { - $content = implode(self::EOL, $content); - } - - // Object header - $xhtml = '_htmlAttribs($attribs) . '>' . self::EOL - . implode(self::EOL, $paramHtml) . self::EOL - . ($content ? $content . self::EOL : '') - . ''; - - return $xhtml; - } -} diff --git a/lib/Zend/View/Helper/HtmlPage.php b/lib/Zend/View/Helper/HtmlPage.php deleted file mode 100644 index 9b14c833318..00000000000 --- a/lib/Zend/View/Helper/HtmlPage.php +++ /dev/null @@ -1,75 +0,0 @@ - self::ATTRIB_CLASSID); - - /** - * Output a html object tag - * - * @param string $data The html url - * @param array $attribs Attribs for the object tag - * @param array $params Params for in the object tag - * @param string $content Alternative content - * @return string - */ - public function htmlPage($data, array $attribs = array(), array $params = array(), $content = null) - { - // Attrs - $attribs = array_merge($this->_attribs, $attribs); - - // Params - $params = array_merge(array('data' => $data), $params); - - return $this->htmlObject($data, self::TYPE, $attribs, $params, $content); - } -} diff --git a/lib/Zend/View/Helper/HtmlQuicktime.php b/lib/Zend/View/Helper/HtmlQuicktime.php deleted file mode 100644 index db0789970e7..00000000000 --- a/lib/Zend/View/Helper/HtmlQuicktime.php +++ /dev/null @@ -1,82 +0,0 @@ - self::ATTRIB_CLASSID, - 'codebase' => self::ATTRIB_CODEBASE); - - /** - * Output a quicktime movie object tag - * - * @param string $data The quicktime file - * @param array $attribs Attribs for the object tag - * @param array $params Params for in the object tag - * @param string $content Alternative content - * @return string - */ - public function htmlQuicktime($data, array $attribs = array(), array $params = array(), $content = null) - { - // Attrs - $attribs = array_merge($this->_attribs, $attribs); - - // Params - $params = array_merge(array('src' => $data), $params); - - return $this->htmlObject($data, self::TYPE, $attribs, $params, $content); - } -} diff --git a/lib/Zend/View/Helper/InlineScript.php b/lib/Zend/View/Helper/InlineScript.php deleted file mode 100644 index 863c5e4eec7..00000000000 --- a/lib/Zend/View/Helper/InlineScript.php +++ /dev/null @@ -1,61 +0,0 @@ -headScript($mode, $spec, $placement, $attrs, $type); - } -} diff --git a/lib/Zend/View/Helper/Interface.php b/lib/Zend/View/Helper/Interface.php deleted file mode 100644 index c7e761b2a56..00000000000 --- a/lib/Zend/View/Helper/Interface.php +++ /dev/null @@ -1,46 +0,0 @@ -true|false - * this array can contains a 'keepLayout'=>true|false and/or 'encodeData'=>true|false - * that will not be passed to Zend_Json::encode method but will be used here - * @param bool $encodeData - * @return string|void - */ - public function json($data, $keepLayouts = false, $encodeData = true) - { - $options = array(); - if (is_array($keepLayouts)) { - $options = $keepLayouts; - - $keepLayouts = false; - if (array_key_exists('keepLayouts', $options)) { - $keepLayouts = $options['keepLayouts']; - unset($options['keepLayouts']); - } - - if (array_key_exists('encodeData', $options)) { - $encodeData = $options['encodeData']; - unset($options['encodeData']); - } - } - - if ($encodeData) { - $data = Zend_Json::encode($data, null, $options); - } - if (!$keepLayouts) { - #require_once 'Zend/Layout.php'; - $layout = Zend_Layout::getMvcInstance(); - if ($layout instanceof Zend_Layout) { - $layout->disableLayout(); - } - } - - $response = Zend_Controller_Front::getInstance()->getResponse(); - $response->setHeader('Content-Type', 'application/json', true); - return $data; - } -} diff --git a/lib/Zend/View/Helper/Layout.php b/lib/Zend/View/Helper/Layout.php deleted file mode 100644 index 7a95bbf971e..00000000000 --- a/lib/Zend/View/Helper/Layout.php +++ /dev/null @@ -1,81 +0,0 @@ -_layout) { - #require_once 'Zend/Layout.php'; - $this->_layout = Zend_Layout::getMvcInstance(); - if (null === $this->_layout) { - // Implicitly creates layout object - $this->_layout = new Zend_Layout(); - } - } - - return $this->_layout; - } - - /** - * Set layout object - * - * @param Zend_Layout $layout - * @return Zend_Layout_Controller_Action_Helper_Layout - */ - public function setLayout(Zend_Layout $layout) - { - $this->_layout = $layout; - return $this; - } - - /** - * Return layout object - * - * Usage: $this->layout()->setLayout('alternate'); - * - * @return Zend_Layout - */ - public function layout() - { - return $this->getLayout(); - } -} diff --git a/lib/Zend/View/Helper/Navigation.php b/lib/Zend/View/Helper/Navigation.php deleted file mode 100644 index ccafa1d4b4a..00000000000 --- a/lib/Zend/View/Helper/Navigation.php +++ /dev/null @@ -1,350 +0,0 @@ -setContainer($container); - } - - return $this; - } - - /** - * Magic overload: Proxy to other navigation helpers or the container - * - * Examples of usage from a view script or layout: - * - * // proxy to Menu helper and render container: - * echo $this->navigation()->menu(); - * - * // proxy to Breadcrumbs helper and set indentation: - * $this->navigation()->breadcrumbs()->setIndent(8); - * - * // proxy to container and find all pages with 'blog' route: - * $blogPages = $this->navigation()->findAllByRoute('blog'); - * - * - * @param string $method helper name or method name in - * container - * @param array $arguments [optional] arguments to pass - * @return mixed returns what the proxied call returns - * @throws Zend_View_Exception if proxying to a helper, and the - * helper is not an instance of the - * interface specified in - * {@link findHelper()} - * @throws Zend_Navigation_Exception if method does not exist in container - */ - public function __call($method, array $arguments = array()) - { - // check if call should proxy to another helper - if ($helper = $this->findHelper($method, false)) { - return call_user_func_array(array($helper, $method), $arguments); - } - - // default behaviour: proxy call to container - return parent::__call($method, $arguments); - } - - /** - * Returns the helper matching $proxy - * - * The helper must implement the interface - * {@link Zend_View_Helper_Navigation_Helper}. - * - * @param string $proxy helper name - * @param bool $strict [optional] whether - * exceptions should be - * thrown if something goes - * wrong. Default is true. - * @return Zend_View_Helper_Navigation_Helper helper instance - * @throws Zend_Loader_PluginLoader_Exception if $strict is true and - * helper cannot be found - * @throws Zend_View_Exception if $strict is true and - * helper does not implement - * the specified interface - */ - public function findHelper($proxy, $strict = true) - { - if (isset($this->_helpers[$proxy])) { - return $this->_helpers[$proxy]; - } - - if (!$this->view->getPluginLoader('helper')->getPaths(self::NS)) { - // Add navigation helper path at the beginning - $paths = $this->view->getHelperPaths(); - $this->view->setHelperPath(null); - - $this->view->addHelperPath( - str_replace('_', '/', self::NS), - self::NS); - - foreach ($paths as $ns => $path) { - $this->view->addHelperPath($path, $ns); - } - } - - if ($strict) { - $helper = $this->view->getHelper($proxy); - } else { - try { - $helper = $this->view->getHelper($proxy); - } catch (Zend_Loader_PluginLoader_Exception $e) { - return null; - } - } - - if (!$helper instanceof Zend_View_Helper_Navigation_Helper) { - if ($strict) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - 'Proxy helper "%s" is not an instance of ' . - 'Zend_View_Helper_Navigation_Helper', - get_class($helper))); - $e->setView($this->view); - throw $e; - } - - return null; - } - - $this->_inject($helper); - $this->_helpers[$proxy] = $helper; - - return $helper; - } - - /** - * Injects container, ACL, and translator to the given $helper if this - * helper is configured to do so - * - * @param Zend_View_Helper_Navigation_Helper $helper helper instance - * @return void - */ - protected function _inject(Zend_View_Helper_Navigation_Helper $helper) - { - if ($this->getInjectContainer() && !$helper->hasContainer()) { - $helper->setContainer($this->getContainer()); - } - - if ($this->getInjectAcl()) { - if (!$helper->hasAcl()) { - $helper->setAcl($this->getAcl()); - } - if (!$helper->hasRole()) { - $helper->setRole($this->getRole()); - } - } - - if ($this->getInjectTranslator() && !$helper->hasTranslator()) { - $helper->setTranslator($this->getTranslator()); - } - } - - // Accessors: - - /** - * Sets the default proxy to use in {@link render()} - * - * @param string $proxy default proxy - * @return Zend_View_Helper_Navigation fluent interface, returns self - */ - public function setDefaultProxy($proxy) - { - $this->_defaultProxy = (string) $proxy; - return $this; - } - - /** - * Returns the default proxy to use in {@link render()} - * - * @return string the default proxy to use in {@link render()} - */ - public function getDefaultProxy() - { - return $this->_defaultProxy; - } - - /** - * Sets whether container should be injected when proxying - * - * @param bool $injectContainer [optional] whether container should - * be injected when proxying. Default - * is true. - * @return Zend_View_Helper_Navigation fluent interface, returns self - */ - public function setInjectContainer($injectContainer = true) - { - $this->_injectContainer = (bool) $injectContainer; - return $this; - } - - /** - * Returns whether container should be injected when proxying - * - * @return bool whether container should be injected when proxying - */ - public function getInjectContainer() - { - return $this->_injectContainer; - } - - /** - * Sets whether ACL should be injected when proxying - * - * @param bool $injectAcl [optional] whether ACL should be - * injected when proxying. Default is - * true. - * @return Zend_View_Helper_Navigation fluent interface, returns self - */ - public function setInjectAcl($injectAcl = true) - { - $this->_injectAcl = (bool) $injectAcl; - return $this; - } - - /** - * Returns whether ACL should be injected when proxying - * - * @return bool whether ACL should be injected when proxying - */ - public function getInjectAcl() - { - return $this->_injectAcl; - } - - /** - * Sets whether translator should be injected when proxying - * - * @param bool $injectTranslator [optional] whether translator should - * be injected when proxying. Default - * is true. - * @return Zend_View_Helper_Navigation fluent interface, returns self - */ - public function setInjectTranslator($injectTranslator = true) - { - $this->_injectTranslator = (bool) $injectTranslator; - return $this; - } - - /** - * Returns whether translator should be injected when proxying - * - * @return bool whether translator should be injected when proxying - */ - public function getInjectTranslator() - { - return $this->_injectTranslator; - } - - // Zend_View_Helper_Navigation_Helper: - - /** - * Renders helper - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - * @throws Zend_Loader_PluginLoader_Exception if helper cannot be found - * @throws Zend_View_Exception if helper doesn't implement - * the interface specified in - * {@link findHelper()} - */ - public function render(Zend_Navigation_Container $container = null) - { - $helper = $this->findHelper($this->getDefaultProxy()); - return $helper->render($container); - } -} diff --git a/lib/Zend/View/Helper/Navigation/Breadcrumbs.php b/lib/Zend/View/Helper/Navigation/Breadcrumbs.php deleted file mode 100644 index 34ff118901d..00000000000 --- a/lib/Zend/View/Helper/Navigation/Breadcrumbs.php +++ /dev/null @@ -1,331 +0,0 @@ -setContainer($container); - } - - return $this; - } - - // Accessors: - - /** - * Sets breadcrumb separator - * - * @param string $separator separator string - * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, - * returns self - */ - public function setSeparator($separator) - { - if (is_string($separator)) { - $this->_separator = $separator; - } - - return $this; - } - - /** - * Returns breadcrumb separator - * - * @return string breadcrumb separator - */ - public function getSeparator() - { - return $this->_separator; - } - - /** - * Sets whether last page in breadcrumbs should be hyperlinked - * - * @param bool $linkLast whether last page should - * be hyperlinked - * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, - * returns self - */ - public function setLinkLast($linkLast) - { - $this->_linkLast = (bool) $linkLast; - return $this; - } - - /** - * Returns whether last page in breadcrumbs should be hyperlinked - * - * @return bool whether last page in breadcrumbs should be hyperlinked - */ - public function getLinkLast() - { - return $this->_linkLast; - } - - /** - * Sets which partial view script to use for rendering menu - * - * @param string|array $partial partial view script or - * null. If an array is - * given, it is expected to - * contain two values; - * the partial view script - * to use, and the module - * where the script can be - * found. - * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, - * returns self - */ - public function setPartial($partial) - { - if (null === $partial || is_string($partial) || is_array($partial)) { - $this->_partial = $partial; - } - - return $this; - } - - /** - * Returns partial view script to use for rendering menu - * - * @return string|array|null - */ - public function getPartial() - { - return $this->_partial; - } - - // Render methods: - - /** - * Renders breadcrumbs by chaining 'a' elements with the separator - * registered in the helper - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - */ - public function renderStraight(Zend_Navigation_Container $container = null) - { - if (null === $container) { - $container = $this->getContainer(); - } - - // find deepest active - if (!$active = $this->findActive($container)) { - return ''; - } - - $active = $active['page']; - - // put the deepest active page last in breadcrumbs - if ($this->getLinkLast()) { - $html = $this->htmlify($active); - } else { - $html = $active->getLabel(); - if ($this->getUseTranslator() && $t = $this->getTranslator()) { - $html = $t->translate($html); - } - $html = $this->view->escape($html); - } - - // walk back to root - while ($parent = $active->getParent()) { - if ($parent instanceof Zend_Navigation_Page) { - // prepend crumb to html - $html = $this->htmlify($parent) - . $this->getSeparator() - . $html; - } - - if ($parent === $container) { - // at the root of the given container - break; - } - - $active = $parent; - } - - return strlen($html) ? $this->getIndent() . $html : ''; - } - - /** - * Renders the given $container by invoking the partial view helper - * - * The container will simply be passed on as a model to the view script, - * so in the script it will be available in $this->container. - * - * @param Zend_Navigation_Container $container [optional] container to - * pass to view script. - * Default is to use the - * container registered in the - * helper. - * @param string|array $partial [optional] partial view - * script to use. Default is - * to use the partial - * registered in the helper. - * If an array is given, it is - * expected to contain two - * values; the partial view - * script to use, and the - * module where the script can - * be found. - * @return string helper output - */ - public function renderPartial(Zend_Navigation_Container $container = null, - $partial = null) - { - if (null === $container) { - $container = $this->getContainer(); - } - - if (null === $partial) { - $partial = $this->getPartial(); - } - - if (empty($partial)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception( - 'Unable to render menu: No partial view script provided' - ); - $e->setView($this->view); - throw $e; - } - - // put breadcrumb pages in model - $model = array('pages' => array()); - if ($active = $this->findActive($container)) { - $active = $active['page']; - $model['pages'][] = $active; - while ($parent = $active->getParent()) { - if ($parent instanceof Zend_Navigation_Page) { - $model['pages'][] = $parent; - } else { - break; - } - - if ($parent === $container) { - // break if at the root of the given container - break; - } - - $active = $parent; - } - $model['pages'] = array_reverse($model['pages']); - } - - if (is_array($partial)) { - if (count($partial) != 2) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception( - 'Unable to render menu: A view partial supplied as ' - . 'an array must contain two values: partial view ' - . 'script and module where script can be found' - ); - $e->setView($this->view); - throw $e; - } - - return $this->view->partial($partial[0], $partial[1], $model); - } - - return $this->view->partial($partial, null, $model); - } - - // Zend_View_Helper_Navigation_Helper: - - /** - * Renders helper - * - * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - */ - public function render(Zend_Navigation_Container $container = null) - { - if ($partial = $this->getPartial()) { - return $this->renderPartial($container, $partial); - } else { - return $this->renderStraight($container); - } - } -} diff --git a/lib/Zend/View/Helper/Navigation/Helper.php b/lib/Zend/View/Helper/Navigation/Helper.php deleted file mode 100644 index e7d5878160c..00000000000 --- a/lib/Zend/View/Helper/Navigation/Helper.php +++ /dev/null @@ -1,212 +0,0 @@ -_container = $container; - return $this; - } - - /** - * Returns the navigation container helper operates on by default - * - * Implements {@link Zend_View_Helper_Navigation_Interface::getContainer()}. - * - * If a helper is not explicitly set in this helper instance by calling - * {@link setContainer()} or by passing it through the helper entry point, - * this method will look in {@link Zend_Registry} for a container by using - * the key 'Zend_Navigation'. - * - * If no container is set, and nothing is found in Zend_Registry, a new - * container will be instantiated and stored in the helper. - * - * @return Zend_Navigation_Container navigation container - */ - public function getContainer() - { - if (null === $this->_container) { - // try to fetch from registry first - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Navigation')) { - $nav = Zend_Registry::get('Zend_Navigation'); - if ($nav instanceof Zend_Navigation_Container) { - return $this->_container = $nav; - } - } - - // nothing found in registry, create new container - #require_once 'Zend/Navigation.php'; - $this->_container = new Zend_Navigation(); - } - - return $this->_container; - } - - /** - * Sets the minimum depth a page must have to be included when rendering - * - * @param int $minDepth [optional] minimum - * depth. Default is - * null, which sets - * no minimum depth. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setMinDepth($minDepth = null) - { - if (null === $minDepth || is_int($minDepth)) { - $this->_minDepth = $minDepth; - } else { - $this->_minDepth = (int) $minDepth; - } - return $this; - } - - /** - * Returns minimum depth a page must have to be included when rendering - * - * @return int|null minimum depth or null - */ - public function getMinDepth() - { - if (!is_int($this->_minDepth) || $this->_minDepth < 0) { - return 0; - } - return $this->_minDepth; - } - - /** - * Sets the maximum depth a page can have to be included when rendering - * - * @param int $maxDepth [optional] maximum - * depth. Default is - * null, which sets no - * maximum depth. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setMaxDepth($maxDepth = null) - { - if (null === $maxDepth || is_int($maxDepth)) { - $this->_maxDepth = $maxDepth; - } else { - $this->_maxDepth = (int) $maxDepth; - } - return $this; - } - - /** - * Returns maximum depth a page can have to be included when rendering - * - * @return int|null maximum depth or null - */ - public function getMaxDepth() - { - return $this->_maxDepth; - } - - /** - * Set the indentation string for using in {@link render()}, optionally a - * number of spaces to indent with - * - * @param string|int $indent indentation string or - * number of spaces - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setIndent($indent) - { - $this->_indent = $this->_getWhitespace($indent); - return $this; - } - - /** - * Returns indentation (format output is respected) - * - * @return string indentation string or an empty string - */ - public function getIndent() - { - if (false === $this->getFormatOutput()) { - return ''; - } - - return $this->_indent; - } - - /** - * Returns the EOL character (format output is respected) - * - * @see self::EOL - * @see getFormatOutput() - * - * @return string standard EOL charater or an empty string - */ - public function getEOL() - { - if (false === $this->getFormatOutput()) { - return ''; - } - - return self::EOL; - } - - /** - * Sets whether HTML/XML output should be formatted - * - * @param bool $formatOutput [optional] whether output - * should be formatted. Default - * is true. - * - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function setFormatOutput($formatOutput = true) - { - $this->_formatOutput = (bool)$formatOutput; - - return $this; - } - - /** - * Returns whether HTML/XML output should be formatted - * - * @return bool whether HTML/XML output should be formatted - */ - public function getFormatOutput() - { - return $this->_formatOutput; - } - - /** - * Sets prefix for IDs when they are normalized - * - * @param string $prefix Prefix for IDs - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self - */ - public function setPrefixForId($prefix) - { - if (is_string($prefix)) { - $this->_prefixForId = trim($prefix); - } - - return $this; - } - - /** - * Returns prefix for IDs when they are normalized - * - * @return string Prefix for - */ - public function getPrefixForId() - { - if (null === $this->_prefixForId) { - $prefix = get_class($this); - $this->_prefixForId = strtolower( - trim(substr($prefix, strrpos($prefix, '_')), '_') - ) . '-'; - } - - return $this->_prefixForId; - } - - /** - * Skip the current prefix for IDs when they are normalized - * - * @param bool $flag - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self - */ - public function skipPrefixForId($flag = true) - { - $this->_skipPrefixForId = (bool) $flag; - return $this; - } - - /** - * Sets translator to use in helper - * - * Implements {@link Zend_View_Helper_Navigation_Helper::setTranslator()}. - * - * @param mixed $translator [optional] translator. - * Expects an object of - * type - * {@link Zend_Translate_Adapter} - * or {@link Zend_Translate}, - * or null. Default is - * null, which sets no - * translator. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setTranslator($translator = null) - { - if (null == $translator || - $translator instanceof Zend_Translate_Adapter) { - $this->_translator = $translator; - } elseif ($translator instanceof Zend_Translate) { - $this->_translator = $translator->getAdapter(); - } - - return $this; - } - - /** - * Returns translator used in helper - * - * Implements {@link Zend_View_Helper_Navigation_Helper::getTranslator()}. - * - * @return Zend_Translate_Adapter|null translator or null - */ - public function getTranslator() - { - if (null === $this->_translator) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Translate')) { - $this->setTranslator(Zend_Registry::get('Zend_Translate')); - } - } - - return $this->_translator; - } - - /** - * Sets ACL to use when iterating pages - * - * Implements {@link Zend_View_Helper_Navigation_Helper::setAcl()}. - * - * @param Zend_Acl $acl [optional] ACL object. - * Default is null. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setAcl(Zend_Acl $acl = null) - { - $this->_acl = $acl; - return $this; - } - - /** - * Returns ACL or null if it isn't set using {@link setAcl()} or - * {@link setDefaultAcl()} - * - * Implements {@link Zend_View_Helper_Navigation_Helper::getAcl()}. - * - * @return Zend_Acl|null ACL object or null - */ - public function getAcl() - { - if ($this->_acl === null && self::$_defaultAcl !== null) { - return self::$_defaultAcl; - } - - return $this->_acl; - } - - /** - * Sets ACL role(s) to use when iterating pages - * - * Implements {@link Zend_View_Helper_Navigation_Helper::setRole()}. - * - * @param mixed $role [optional] role to - * set. Expects a string, - * an instance of type - * {@link Zend_Acl_Role_Interface}, - * or null. Default is - * null, which will set - * no role. - * @throws Zend_View_Exception if $role is invalid - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setRole($role = null) - { - if (null === $role || is_string($role) || - $role instanceof Zend_Acl_Role_Interface) { - $this->_role = $role; - } else { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - '$role must be a string, null, or an instance of ' - . 'Zend_Acl_Role_Interface; %s given', - gettype($role) - )); - $e->setView($this->view); - throw $e; - } - - return $this; - } - - /** - * Returns ACL role to use when iterating pages, or null if it isn't set - * using {@link setRole()} or {@link setDefaultRole()} - * - * Implements {@link Zend_View_Helper_Navigation_Helper::getRole()}. - * - * @return string|Zend_Acl_Role_Interface|null role or null - */ - public function getRole() - { - if ($this->_role === null && self::$_defaultRole !== null) { - return self::$_defaultRole; - } - - return $this->_role; - } - - /** - * Sets whether ACL should be used - * - * Implements {@link Zend_View_Helper_Navigation_Helper::setUseAcl()}. - * - * @param bool $useAcl [optional] whether ACL - * should be used. - * Default is true. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setUseAcl($useAcl = true) - { - $this->_useAcl = (bool) $useAcl; - return $this; - } - - /** - * Returns whether ACL should be used - * - * Implements {@link Zend_View_Helper_Navigation_Helper::getUseAcl()}. - * - * @return bool whether ACL should be used - */ - public function getUseAcl() - { - return $this->_useAcl; - } - - /** - * Return renderInvisible flag - * - * @return bool - */ - public function getRenderInvisible() - { - return $this->_renderInvisible; - } - - /** - * Render invisible items? - * - * @param bool $renderInvisible [optional] boolean flag - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface - * returns self - */ - public function setRenderInvisible($renderInvisible = true) - { - $this->_renderInvisible = (bool) $renderInvisible; - return $this; - } - - /** - * Sets whether translator should be used - * - * Implements {@link Zend_View_Helper_Navigation_Helper::setUseTranslator()}. - * - * @param bool $useTranslator [optional] whether - * translator should be - * used. Default is true. - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setUseTranslator($useTranslator = true) - { - $this->_useTranslator = (bool) $useTranslator; - return $this; - } - - /** - * Returns whether translator should be used - * - * Implements {@link Zend_View_Helper_Navigation_Helper::getUseTranslator()}. - * - * @return bool whether translator should be used - */ - public function getUseTranslator() - { - return $this->_useTranslator; - } - - // Magic overloads: - - /** - * Magic overload: Proxy calls to the navigation container - * - * @param string $method method name in container - * @param array $arguments [optional] arguments to pass - * @return mixed returns what the container returns - * @throws Zend_Navigation_Exception if method does not exist in container - */ - public function __call($method, array $arguments = array()) - { - return call_user_func_array( - array($this->getContainer(), $method), - $arguments); - } - - /** - * Magic overload: Proxy to {@link render()}. - * - * This method will trigger an E_USER_ERROR if rendering the helper causes - * an exception to be thrown. - * - * Implements {@link Zend_View_Helper_Navigation_Helper::__toString()}. - * - * @return string - */ - public function __toString() - { - try { - return $this->render(); - } catch (Exception $e) { - $msg = get_class($e) . ': ' . $e->getMessage(); - trigger_error($msg, E_USER_ERROR); - return ''; - } - } - - // Public methods: - - /** - * Finds the deepest active page in the given container - * - * @param Zend_Navigation_Container $container container to search - * @param int|null $minDepth [optional] minimum depth - * required for page to be - * valid. Default is to use - * {@link getMinDepth()}. A - * null value means no minimum - * depth required. - * @param int|null $minDepth [optional] maximum depth - * a page can have to be - * valid. Default is to use - * {@link getMaxDepth()}. A - * null value means no maximum - * depth required. - * @return array an associative array with - * the values 'depth' and - * 'page', or an empty array - * if not found - */ - public function findActive(Zend_Navigation_Container $container, - $minDepth = null, - $maxDepth = -1) - { - if (!is_int($minDepth)) { - $minDepth = $this->getMinDepth(); - } - if ((!is_int($maxDepth) || $maxDepth < 0) && null !== $maxDepth) { - $maxDepth = $this->getMaxDepth(); - } - - $found = null; - $foundDepth = -1; - $iterator = new RecursiveIteratorIterator($container, - RecursiveIteratorIterator::CHILD_FIRST); - - foreach ($iterator as $page) { - $currDepth = $iterator->getDepth(); - if ($currDepth < $minDepth || !$this->accept($page)) { - // page is not accepted - continue; - } - - if ($page->isActive(false) && $currDepth > $foundDepth) { - // found an active page at a deeper level than before - $found = $page; - $foundDepth = $currDepth; - } - } - - if (is_int($maxDepth) && $foundDepth > $maxDepth) { - while ($foundDepth > $maxDepth) { - if (--$foundDepth < $minDepth) { - $found = null; - break; - } - - $found = $found->getParent(); - if (!$found instanceof Zend_Navigation_Page) { - $found = null; - break; - } - } - } - - if ($found) { - return array('page' => $found, 'depth' => $foundDepth); - } else { - return array(); - } - } - - /** - * Checks if the helper has a container - * - * Implements {@link Zend_View_Helper_Navigation_Helper::hasContainer()}. - * - * @return bool whether the helper has a container or not - */ - public function hasContainer() - { - return null !== $this->_container; - } - - /** - * Checks if the helper has an ACL instance - * - * Implements {@link Zend_View_Helper_Navigation_Helper::hasAcl()}. - * - * @return bool whether the helper has a an ACL instance or not - */ - public function hasAcl() - { - return null !== $this->_acl; - } - - /** - * Checks if the helper has an ACL role - * - * Implements {@link Zend_View_Helper_Navigation_Helper::hasRole()}. - * - * @return bool whether the helper has a an ACL role or not - */ - public function hasRole() - { - return null !== $this->_role; - } - - /** - * Checks if the helper has a translator - * - * Implements {@link Zend_View_Helper_Navigation_Helper::hasTranslator()}. - * - * @return bool whether the helper has a translator or not - */ - public function hasTranslator() - { - return null !== $this->_translator; - } - - /** - * Returns an HTML string containing an 'a' element for the given page - * - * @param Zend_Navigation_Page $page page to generate HTML for - * @return string HTML string for the given page - */ - public function htmlify(Zend_Navigation_Page $page) - { - // get label and title for translating - $label = $page->getLabel(); - $title = $page->getTitle(); - - if ($this->getUseTranslator() && $t = $this->getTranslator()) { - if (is_string($label) && !empty($label)) { - $label = $t->translate($label); - } - if (is_string($title) && !empty($title)) { - $title = $t->translate($title); - } - } - - // get attribs for anchor element - $attribs = array_merge( - array( - 'id' => $page->getId(), - 'title' => $title, - 'class' => $page->getClass(), - 'href' => $page->getHref(), - 'target' => $page->getTarget() - ), - $page->getCustomHtmlAttribs() - ); - - return '_htmlAttribs($attribs) . '>' - . $this->view->escape($label) - . ''; - } - - // Iterator filter methods: - - /** - * Determines whether a page should be accepted when iterating - * - * Rules: - * - If a page is not visible it is not accepted, unless RenderInvisible has - * been set to true. - * - If helper has no ACL, page is accepted - * - If helper has ACL, but no role, page is not accepted - * - If helper has ACL and role: - * - Page is accepted if it has no resource or privilege - * - Page is accepted if ACL allows page's resource or privilege - * - If page is accepted by the rules above and $recursive is true, the page - * will not be accepted if it is the descendant of a non-accepted page. - * - * @param Zend_Navigation_Page $page page to check - * @param bool $recursive [optional] if true, page will not - * be accepted if it is the - * descendant of a page that is not - * accepted. Default is true. - * @return bool whether page should be accepted - */ - public function accept(Zend_Navigation_Page $page, $recursive = true) - { - // accept by default - $accept = true; - - if (!$page->isVisible(false) && !$this->getRenderInvisible()) { - // don't accept invisible pages - $accept = false; - } elseif ($this->getUseAcl() && !$this->_acceptAcl($page)) { - // acl is not amused - $accept = false; - } - - if ($accept && $recursive) { - $parent = $page->getParent(); - if ($parent instanceof Zend_Navigation_Page) { - $accept = $this->accept($parent, true); - } - } - - return $accept; - } - - /** - * Determines whether a page should be accepted by ACL when iterating - * - * Rules: - * - If helper has no ACL, page is accepted - * - If page has a resource or privilege defined, page is accepted - * if the ACL allows access to it using the helper's role - * - If page has no resource or privilege, page is accepted - * - * @param Zend_Navigation_Page $page page to check - * @return bool whether page is accepted by ACL - */ - protected function _acceptAcl(Zend_Navigation_Page $page) - { - if (!$acl = $this->getAcl()) { - // no acl registered means don't use acl - return true; - } - - $role = $this->getRole(); - $resource = $page->getResource(); - $privilege = $page->getPrivilege(); - - if ($resource || $privilege) { - // determine using helper role and page resource/privilege - return $acl->isAllowed($role, $resource, $privilege); - } - - return true; - } - - // Util methods: - - /** - * Retrieve whitespace representation of $indent - * - * @param int|string $indent - * @return string - */ - protected function _getWhitespace($indent) - { - if (is_int($indent)) { - $indent = str_repeat(' ', $indent); - } - - return (string) $indent; - } - - /** - * Converts an associative array to a string of tag attributes. - * - * Overloads {@link Zend_View_Helper_HtmlElement::_htmlAttribs()}. - * - * @param array $attribs an array where each key-value pair is converted - * to an attribute name and value - * @return string an attribute string - */ - protected function _htmlAttribs($attribs) - { - // filter out null values and empty string values - foreach ($attribs as $key => $value) { - if ($value === null || (is_string($value) && !strlen($value))) { - unset($attribs[$key]); - } - } - - return parent::_htmlAttribs($attribs); - } - - /** - * Normalize an ID - * - * Extends {@link Zend_View_Helper_HtmlElement::_normalizeId()}. - * - * @param string $value ID - * @return string Normalized ID - */ - protected function _normalizeId($value) - { - if (false === $this->_skipPrefixForId) { - $prefix = $this->getPrefixForId(); - - if (strlen($prefix)) { - return $prefix . $value; - } - } - - return parent::_normalizeId($value); - } - - // Static methods: - - /** - * Sets default ACL to use if another ACL is not explicitly set - * - * @param Zend_Acl $acl [optional] ACL object. Default is null, which - * sets no ACL object. - * @return void - */ - public static function setDefaultAcl(Zend_Acl $acl = null) - { - self::$_defaultAcl = $acl; - } - - /** - * Sets default ACL role(s) to use when iterating pages if not explicitly - * set later with {@link setRole()} - * - * @param mixed $role [optional] role to set. Expects null, - * string, or an instance of - * {@link Zend_Acl_Role_Interface}. - * Default is null, which sets no default - * role. - * @throws Zend_View_Exception if role is invalid - * @return void - */ - public static function setDefaultRole($role = null) - { - if (null === $role || - is_string($role) || - $role instanceof Zend_Acl_Role_Interface) { - self::$_defaultRole = $role; - } else { - #require_once 'Zend/View/Exception.php'; - throw new Zend_View_Exception( - '$role must be null|string|Zend_Acl_Role_Interface' - ); - } - } -} diff --git a/lib/Zend/View/Helper/Navigation/Links.php b/lib/Zend/View/Helper/Navigation/Links.php deleted file mode 100644 index f3356692f45..00000000000 --- a/lib/Zend/View/Helper/Navigation/Links.php +++ /dev/null @@ -1,783 +0,0 @@ - elements - * - * @category Zend - * @package Zend_View - * @subpackage Helper - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_View_Helper_Navigation_Links - extends Zend_View_Helper_Navigation_HelperAbstract -{ - /**#@+ - * Constants used for specifying which link types to find and render - * - * @var int - */ - const RENDER_ALTERNATE = 0x0001; - const RENDER_STYLESHEET = 0x0002; - const RENDER_START = 0x0004; - const RENDER_NEXT = 0x0008; - const RENDER_PREV = 0x0010; - const RENDER_CONTENTS = 0x0020; - const RENDER_INDEX = 0x0040; - const RENDER_GLOSSARY = 0x0080; - const RENDER_COPYRIGHT = 0x0100; - const RENDER_CHAPTER = 0x0200; - const RENDER_SECTION = 0x0400; - const RENDER_SUBSECTION = 0x0800; - const RENDER_APPENDIX = 0x1000; - const RENDER_HELP = 0x2000; - const RENDER_BOOKMARK = 0x4000; - const RENDER_CUSTOM = 0x8000; - const RENDER_ALL = 0xffff; - /**#@+**/ - - /** - * Maps render constants to W3C link types - * - * @var array - */ - protected static $_RELATIONS = array( - self::RENDER_ALTERNATE => 'alternate', - self::RENDER_STYLESHEET => 'stylesheet', - self::RENDER_START => 'start', - self::RENDER_NEXT => 'next', - self::RENDER_PREV => 'prev', - self::RENDER_CONTENTS => 'contents', - self::RENDER_INDEX => 'index', - self::RENDER_GLOSSARY => 'glossary', - self::RENDER_COPYRIGHT => 'copyright', - self::RENDER_CHAPTER => 'chapter', - self::RENDER_SECTION => 'section', - self::RENDER_SUBSECTION => 'subsection', - self::RENDER_APPENDIX => 'appendix', - self::RENDER_HELP => 'help', - self::RENDER_BOOKMARK => 'bookmark' - ); - - /** - * The helper's render flag - * - * @see render() - * @see setRenderFlag() - * @var int - */ - protected $_renderFlag = self::RENDER_ALL; - - /** - * Root container - * - * Used for preventing methods to traverse above the container given to - * the {@link render()} method. - * - * @see _findRoot() - * - * @var Zend_Navigation_Container - */ - protected $_root; - - /** - * View helper entry point: - * Retrieves helper and optionally sets container to operate on - * - * @param Zend_Navigation_Container $container [optional] container to - * operate on - * @return Zend_View_Helper_Navigation_Links fluent interface, returns - * self - */ - public function links(Zend_Navigation_Container $container = null) - { - if (null !== $container) { - $this->setContainer($container); - } - - return $this; - } - - /** - * Magic overload: Proxy calls to {@link findRelation()} or container - * - * Examples of finder calls: - * - * // METHOD // SAME AS - * $h->findRelNext($page); // $h->findRelation($page, 'rel', 'next') - * $h->findRevSection($page); // $h->findRelation($page, 'rev', 'section'); - * $h->findRelFoo($page); // $h->findRelation($page, 'rel', 'foo'); - * - * - * @param string $method method name - * @param array $arguments method arguments - * @throws Zend_Navigation_Exception if method does not exist in container - */ - public function __call($method, array $arguments = array()) - { - if (@preg_match('/find(Rel|Rev)(.+)/', $method, $match)) { - return $this->findRelation($arguments[0], - strtolower($match[1]), - strtolower($match[2])); - } - - return parent::__call($method, $arguments); - } - - // Accessors: - - /** - * Sets the helper's render flag - * - * The helper uses the bitwise '&' operator against the hex values of the - * render constants. This means that the flag can is "bitwised" value of - * the render constants. Examples: - * - * // render all links except glossary - * $flag = Zend_View_Helper_Navigation_Links:RENDER_ALL ^ - * Zend_View_Helper_Navigation_Links:RENDER_GLOSSARY; - * $helper->setRenderFlag($flag); - * - * // render only chapters and sections - * $flag = Zend_View_Helper_Navigation_Links:RENDER_CHAPTER | - * Zend_View_Helper_Navigation_Links:RENDER_SECTION; - * $helper->setRenderFlag($flag); - * - * // render only relations that are not native W3C relations - * $helper->setRenderFlag(Zend_View_Helper_Navigation_Links:RENDER_CUSTOM); - * - * // render all relations (default) - * $helper->setRenderFlag(Zend_View_Helper_Navigation_Links:RENDER_ALL); - * - * - * Note that custom relations can also be rendered directly using the - * {@link renderLink()} method. - * - * @param int $renderFlag render flag - * @return Zend_View_Helper_Navigation_Links fluent interface, returns self - */ - public function setRenderFlag($renderFlag) - { - $this->_renderFlag = (int) $renderFlag; - return $this; - } - - /** - * Returns the helper's render flag - * - * @return int render flag - */ - public function getRenderFlag() - { - return $this->_renderFlag; - } - - // Finder methods: - - /** - * Finds all relations (forward and reverse) for the given $page - * - * The form of the returned array: - * - * // $page denotes an instance of Zend_Navigation_Page - * $returned = array( - * 'rel' => array( - * 'alternate' => array($page, $page, $page), - * 'start' => array($page), - * 'next' => array($page), - * 'prev' => array($page), - * 'canonical' => array($page) - * ), - * 'rev' => array( - * 'section' => array($page) - * ) - * ); - * - * - * @param Zend_Navigation_Page $page page to find links for - * @return array related pages - */ - public function findAllRelations(Zend_Navigation_Page $page, - $flag = null) - { - if (!is_int($flag)) { - $flag = self::RENDER_ALL; - } - - $result = array('rel' => array(), 'rev' => array()); - $native = array_values(self::$_RELATIONS); - - foreach (array_keys($result) as $rel) { - $meth = 'getDefined' . ucfirst($rel); - $types = array_merge($native, array_diff($page->$meth(), $native)); - - foreach ($types as $type) { - if (!$relFlag = array_search($type, self::$_RELATIONS)) { - $relFlag = self::RENDER_CUSTOM; - } - if (!($flag & $relFlag)) { - continue; - } - if ($found = $this->findRelation($page, $rel, $type)) { - if (!is_array($found)) { - $found = array($found); - } - $result[$rel][$type] = $found; - } - } - } - - return $result; - } - - /** - * Finds relations of the given $rel=$type from $page - * - * This method will first look for relations in the page instance, then - * by searching the root container if nothing was found in the page. - * - * @param Zend_Navigation_Page $page page to find relations for - * @param string $rel relation, "rel" or "rev" - * @param string $type link type, e.g. 'start', 'next' - * @return Zend_Navigaiton_Page|array|null page(s), or null if not found - * @throws Zend_View_Exception if $rel is not "rel" or "rev" - */ - public function findRelation(Zend_Navigation_Page $page, $rel, $type) - { - if (!in_array($rel, array('rel', 'rev'))) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - 'Invalid argument: $rel must be "rel" or "rev"; "%s" given', - $rel)); - $e->setView($this->view); - throw $e; - } - - if (!$result = $this->_findFromProperty($page, $rel, $type)) { - $result = $this->_findFromSearch($page, $rel, $type); - } - - return $result; - } - - /** - * Finds relations of given $type for $page by checking if the - * relation is specified as a property of $page - * - * @param Zend_Navigation_Page $page page to find relations for - * @param string $rel relation, 'rel' or 'rev' - * @param string $type link type, e.g. 'start', 'next' - * @return Zend_Navigation_Page|array|null page(s), or null if not found - */ - protected function _findFromProperty(Zend_Navigation_Page $page, $rel, $type) - { - $method = 'get' . ucfirst($rel); - if ($result = $page->$method($type)) { - if ($result = $this->_convertToPages($result)) { - if (!is_array($result)) { - $result = array($result); - } - - foreach ($result as $key => $page) { - if (!$this->accept($page)) { - unset($result[$key]); - } - } - - return count($result) == 1 ? $result[0] : $result; - } - } - - return null; - } - - /** - * Finds relations of given $rel=$type for $page by using the helper to - * search for the relation in the root container - * - * @param Zend_Navigation_Page $page page to find relations for - * @param string $rel relation, 'rel' or 'rev' - * @param string $type link type, e.g. 'start', 'next', etc - * @return array|null array of pages, or null if not found - */ - protected function _findFromSearch(Zend_Navigation_Page $page, $rel, $type) - { - $found = null; - - $method = 'search' . ucfirst($rel) . ucfirst($type); - if (method_exists($this, $method)) { - $found = $this->$method($page); - } - - return $found; - } - - // Search methods: - - /** - * Searches the root container for the forward 'start' relation of the given - * $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to the first document in a collection of documents. This link type - * tells search engines which document is considered by the author to be the - * starting point of the collection. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|null page or null - */ - public function searchRelStart(Zend_Navigation_Page $page) - { - $found = $this->_findRoot($page); - if (!$found instanceof Zend_Navigation_Page) { - $found->rewind(); - $found = $found->current(); - } - - if ($found === $page || !$this->accept($found)) { - $found = null; - } - - return $found; - } - - /** - * Searches the root container for the forward 'next' relation of the given - * $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to the next document in a linear sequence of documents. User - * agents may choose to preload the "next" document, to reduce the perceived - * load time. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|null page(s) or null - */ - public function searchRelNext(Zend_Navigation_Page $page) - { - $found = null; - $break = false; - $iterator = new RecursiveIteratorIterator($this->_findRoot($page), - RecursiveIteratorIterator::SELF_FIRST); - foreach ($iterator as $intermediate) { - if ($intermediate === $page) { - // current page; break at next accepted page - $break = true; - continue; - } - - if ($break && $this->accept($intermediate)) { - $found = $intermediate; - break; - } - } - - return $found; - } - - /** - * Searches the root container for the forward 'prev' relation of the given - * $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to the previous document in an ordered series of documents. Some - * user agents also support the synonym "Previous". - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|null page or null - */ - public function searchRelPrev(Zend_Navigation_Page $page) - { - $found = null; - $prev = null; - $iterator = new RecursiveIteratorIterator( - $this->_findRoot($page), - RecursiveIteratorIterator::SELF_FIRST); - foreach ($iterator as $intermediate) { - if (!$this->accept($intermediate)) { - continue; - } - if ($intermediate === $page) { - $found = $prev; - break; - } - - $prev = $intermediate; - } - - return $found; - } - - /** - * Searches the root container for forward 'chapter' relations of the given - * $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to a document serving as a chapter in a collection of documents. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|array|null page(s) or null - */ - public function searchRelChapter(Zend_Navigation_Page $page) - { - $found = array(); - - // find first level of pages - $root = $this->_findRoot($page); - - // find start page(s) - $start = $this->findRelation($page, 'rel', 'start'); - if (!is_array($start)) { - $start = array($start); - } - - foreach ($root as $chapter) { - // exclude self and start page from chapters - if ($chapter !== $page && - !in_array($chapter, $start) && - $this->accept($chapter)) { - $found[] = $chapter; - } - } - - switch (count($found)) { - case 0: - return null; - case 1: - return $found[0]; - default: - return $found; - } - } - - /** - * Searches the root container for forward 'section' relations of the given - * $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to a document serving as a section in a collection of documents. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|array|null page(s) or null - */ - public function searchRelSection(Zend_Navigation_Page $page) - { - $found = array(); - - // check if given page has pages and is a chapter page - if ($page->hasPages() && $this->_findRoot($page)->hasPage($page)) { - foreach ($page as $section) { - if ($this->accept($section)) { - $found[] = $section; - } - } - } - - switch (count($found)) { - case 0: - return null; - case 1: - return $found[0]; - default: - return $found; - } - } - - /** - * Searches the root container for forward 'subsection' relations of the - * given $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to a document serving as a subsection in a collection of - * documents. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|array|null page(s) or null - */ - public function searchRelSubsection(Zend_Navigation_Page $page) - { - $found = array(); - - if ($page->hasPages()) { - // given page has child pages, loop chapters - foreach ($this->_findRoot($page) as $chapter) { - // is page a section? - if ($chapter->hasPage($page)) { - foreach ($page as $subsection) { - if ($this->accept($subsection)) { - $found[] = $subsection; - } - } - } - } - } - - switch (count($found)) { - case 0: - return null; - case 1: - return $found[0]; - default: - return $found; - } - } - - /** - * Searches the root container for the reverse 'section' relation of the - * given $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to a document serving as a section in a collection of documents. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|null page(s) or null - */ - public function searchRevSection(Zend_Navigation_Page $page) - { - $found = null; - - if ($parent = $page->getParent()) { - if ($parent instanceof Zend_Navigation_Page && - $this->_findRoot($page)->hasPage($parent)) { - $found = $parent; - } - } - - return $found; - } - - /** - * Searches the root container for the reverse 'section' relation of the - * given $page - * - * From {@link http://www.w3.org/TR/html4/types.html#type-links}: - * Refers to a document serving as a subsection in a collection of - * documents. - * - * @param Zend_Navigation_Page $page page to find relation for - * @return Zend_Navigation_Page|null page(s) or null - */ - public function searchRevSubsection(Zend_Navigation_Page $page) - { - $found = null; - - if ($parent = $page->getParent()) { - if ($parent instanceof Zend_Navigation_Page) { - $root = $this->_findRoot($page); - foreach ($root as $chapter) { - if ($chapter->hasPage($parent)) { - $found = $parent; - break; - } - } - } - } - - return $found; - } - - // Util methods: - - /** - * Returns the root container of the given page - * - * When rendering a container, the render method still store the given - * container as the root container, and unset it when done rendering. This - * makes sure finder methods will not traverse above the container given - * to the render method. - * - * @param Zend_Navigaiton_Page $page page to find root for - * @return Zend_Navigation_Container the root container of the given page - */ - protected function _findRoot(Zend_Navigation_Page $page) - { - if ($this->_root) { - return $this->_root; - } - - $root = $page; - - while ($parent = $page->getParent()) { - $root = $parent; - if ($parent instanceof Zend_Navigation_Page) { - $page = $parent; - } else { - break; - } - } - - return $root; - } - - /** - * Converts a $mixed value to an array of pages - * - * @param mixed $mixed mixed value to get page(s) from - * @param bool $recursive whether $value should be looped - * if it is an array or a config - * @return Zend_Navigation_Page|array|null empty if unable to convert - */ - protected function _convertToPages($mixed, $recursive = true) - { - if (is_object($mixed)) { - if ($mixed instanceof Zend_Navigation_Page) { - // value is a page instance; return directly - return $mixed; - } elseif ($mixed instanceof Zend_Navigation_Container) { - // value is a container; return pages in it - $pages = array(); - foreach ($mixed as $page) { - $pages[] = $page; - } - return $pages; - } elseif ($mixed instanceof Zend_Config) { - // convert config object to array and extract - return $this->_convertToPages($mixed->toArray(), $recursive); - } - } elseif (is_string($mixed)) { - // value is a string; make an URI page - return Zend_Navigation_Page::factory(array( - 'type' => 'uri', - 'uri' => $mixed - )); - } elseif (is_array($mixed) && !empty($mixed)) { - if ($recursive && is_numeric(key($mixed))) { - // first key is numeric; assume several pages - $pages = array(); - foreach ($mixed as $value) { - if ($value = $this->_convertToPages($value, false)) { - $pages[] = $value; - } - } - return $pages; - } else { - // pass array to factory directly - try { - $page = Zend_Navigation_Page::factory($mixed); - return $page; - } catch (Exception $e) { - } - } - } - - // nothing found - return null; - } - - // Render methods: - - /** - * Renders the given $page as a link element, with $attrib = $relation - * - * @param Zend_Navigation_Page $page the page to render the link for - * @param string $attrib the attribute to use for $type, - * either 'rel' or 'rev' - * @param string $relation relation type, muse be one of; - * alternate, appendix, bookmark, - * chapter, contents, copyright, - * glossary, help, home, index, next, - * prev, section, start, stylesheet, - * subsection - * @return string rendered link element - * @throws Zend_View_Exception if $attrib is invalid - */ - public function renderLink(Zend_Navigation_Page $page, $attrib, $relation) - { - if (!in_array($attrib, array('rel', 'rev'))) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - 'Invalid relation attribute "%s", must be "rel" or "rev"', - $attrib)); - $e->setView($this->view); - throw $e; - } - - if (!$href = $page->getHref()) { - return ''; - } - - // TODO: add more attribs - // http://www.w3.org/TR/html401/struct/links.html#h-12.2 - $attribs = array( - $attrib => $relation, - 'href' => $href, - 'title' => $page->getLabel() - ); - - return '_htmlAttribs($attribs) . - $this->getClosingBracket(); - } - - // Zend_View_Helper_Navigation_Helper: - - /** - * Renders helper - * - * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - */ - public function render(Zend_Navigation_Container $container = null) - { - if (null === $container) { - $container = $this->getContainer(); - } - - if ($active = $this->findActive($container)) { - $active = $active['page']; - } else { - // no active page - return ''; - } - - $output = ''; - $indent = $this->getIndent(); - $this->_root = $container; - - $result = $this->findAllRelations($active, $this->getRenderFlag()); - foreach ($result as $attrib => $types) { - foreach ($types as $relation => $pages) { - foreach ($pages as $page) { - if ($r = $this->renderLink($page, $attrib, $relation)) { - $output .= $indent . $r . $this->getEOL(); - } - } - } - } - - $this->_root = null; - - // return output (trim last newline by spec) - return strlen($output) ? rtrim($output, self::EOL) : ''; - } -} diff --git a/lib/Zend/View/Helper/Navigation/Menu.php b/lib/Zend/View/Helper/Navigation/Menu.php deleted file mode 100644 index 325dfc56047..00000000000 --- a/lib/Zend/View/Helper/Navigation/Menu.php +++ /dev/null @@ -1,1099 +0,0 @@ -setContainer($container); - } - - return $this; - } - - // Accessors: - - /** - * Sets CSS class to use for the first 'ul' element when rendering - * - * @param string $ulClass CSS class to set - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setUlClass($ulClass) - { - if (is_string($ulClass)) { - $this->_ulClass = $ulClass; - } - - return $this; - } - - /** - * Returns CSS class to use for the first 'ul' element when rendering - * - * @return string CSS class - */ - public function getUlClass() - { - return $this->_ulClass; - } - - /** - * Sets unique identifier (id) to use for the first 'ul' element when - * rendering - * - * @param string|null $ulId Unique identifier (id) to set - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setUlId($ulId) - { - if (is_string($ulId)) { - $this->_ulId = $ulId; - } - - return $this; - } - - /** - * Returns unique identifier (id) to use for the first 'ul' element when - * rendering - * - * @return string|null Unique identifier (id); Default is 'null' - */ - public function getUlId() - { - return $this->_ulId; - } - - /** - * Sets CSS class to use for the active elements when rendering - * - * @param string $activeClass CSS class to set - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setActiveClass($activeClass) - { - if (is_string($activeClass)) { - $this->_activeClass = $activeClass; - } - - return $this; - } - - /** - * Returns CSS class to use for the active elements when rendering - * - * @return string CSS class - */ - public function getActiveClass() - { - return $this->_activeClass; - } - - /** - * Sets CSS class to use for the parent li elements when rendering - * - * @param string $parentClass CSS class to set to parents - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setParentClass($parentClass) - { - if (is_string($parentClass)) { - $this->_parentClass = $parentClass; - } - - return $this; - } - - /** - * Returns CSS class to use for the parent lie elements when rendering - * - * @return string CSS class - */ - public function getParentClass() - { - return $this->_parentClass; - } - - /** - * Enables/disables rendering of parent class to the li element - * - * @param bool $flag [optional] render with parent - * class. Default is true. - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setRenderParentClass($flag = true) - { - $this->_renderParentClass = (bool) $flag; - return $this; - } - - /** - * Returns flag indicating whether parent class should be rendered to the li - * element - * - * @return bool whether parent class should be rendered - */ - public function getRenderParentClass() - { - return $this->_renderParentClass; - } - - /** - * Sets a flag indicating whether only active branch should be rendered - * - * @param bool $flag [optional] render only active - * branch. Default is true. - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setOnlyActiveBranch($flag = true) - { - $this->_onlyActiveBranch = (bool) $flag; - return $this; - } - - /** - * Returns a flag indicating whether only active branch should be rendered - * - * By default, this value is false, meaning the entire menu will be - * be rendered. - * - * @return bool whether only active branch should be rendered - */ - public function getOnlyActiveBranch() - { - return $this->_onlyActiveBranch; - } - - /** - * Sets a flag indicating whether to expand all sibling nodes of the active branch - * - * @param bool $flag [optional] expand all siblings of - * nodes in the active branch. Default is true. - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setExpandSiblingNodesOfActiveBranch($flag = true) - { - $this->_expandSiblingNodesOfActiveBranch = (bool) $flag; - return $this; - } - - /** - * Returns a flag indicating whether to expand all sibling nodes of the active branch - * - * By default, this value is false, meaning the entire menu will be - * be rendered. - * - * @return bool whether siblings of nodes in the active branch should be expanded - */ - public function getExpandSiblingNodesOfActiveBranch() - { - return $this->_expandSiblingNodesOfActiveBranch; - } - - /** - * Enables/disables rendering of parents when only rendering active branch - * - * See {@link setOnlyActiveBranch()} for more information. - * - * @param bool $flag [optional] render parents when - * rendering active branch. - * Default is true. - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setRenderParents($flag = true) - { - $this->_renderParents = (bool) $flag; - return $this; - } - - /** - * Returns flag indicating whether parents should be rendered when rendering - * only the active branch - * - * By default, this value is true. - * - * @return bool whether parents should be rendered - */ - public function getRenderParents() - { - return $this->_renderParents; - } - - /** - * Sets which partial view script to use for rendering menu - * - * @param string|array $partial partial view script or null. If - * an array is given, it is - * expected to contain two values; - * the partial view script to use, - * and the module where the script - * can be found. - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function setPartial($partial) - { - if (null === $partial || is_string($partial) || is_array($partial)) { - $this->_partial = $partial; - } - - return $this; - } - - /** - * Returns partial view script to use for rendering menu - * - * @return string|array|null - */ - public function getPartial() - { - return $this->_partial; - } - - /** - * Adds CSS class from page to li element - * - * Before: - * - *
  • - * Bar - *
  • - *
    - * - * After: - * - *
  • - * Bar - *
  • - *
    - * - * @param bool $flag [optional] adds CSS class from - * page to li element - * - * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self - */ - public function addPageClassToLi($flag = true) - { - $this->_addPageClassToLi = (bool) $flag; - - return $this; - } - - /** - * Returns a flag indicating whether the CSS class from page to be added to - * li element - * - * @return bool - */ - public function getAddPageClassToLi() - { - return $this->_addPageClassToLi; - } - - /** - * Set the inner indentation string for using in {@link render()}, optionally - * a number of spaces to indent with - * - * @param string|int $indent indentation string or - * number of spaces - * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, - * returns self - */ - public function setInnerIndent($indent) - { - $this->_innerIndent = $this->_getWhitespace($indent); - - return $this; - } - - /** - * Returns inner indentation (format output is respected) - * - * @see getFormatOutput() - * - * @return string indentation string or an empty string - */ - public function getInnerIndent() - { - if (false === $this->getFormatOutput()) { - return ''; - } - - return $this->_innerIndent; - } - - // Public methods: - - /** - * Returns an HTML string containing an 'a' element for the given page if - * the page's href is not empty, and a 'span' element if it is empty - * - * Overrides {@link Zend_View_Helper_Navigation_Abstract::htmlify()}. - * - * @param Zend_Navigation_Page $page page to generate HTML for - * @return string HTML string for the given page - */ - public function htmlify(Zend_Navigation_Page $page) - { - // get label and title for translating - $label = $page->getLabel(); - $title = $page->getTitle(); - - // translate label and title? - if ($this->getUseTranslator() && $t = $this->getTranslator()) { - if (is_string($label) && !empty($label)) { - $label = $t->translate($label); - } - if (is_string($title) && !empty($title)) { - $title = $t->translate($title); - } - } - - // get attribs for element - $attribs = array( - 'id' => $page->getId(), - 'title' => $title, - ); - - if (false === $this->getAddPageClassToLi()) { - $attribs['class'] = $page->getClass(); - } - - // does page have a href? - if ($href = $page->getHref()) { - $element = 'a'; - $attribs['href'] = $href; - $attribs['target'] = $page->getTarget(); - $attribs['accesskey'] = $page->getAccessKey(); - } else { - $element = 'span'; - } - - // Add custom HTML attributes - $attribs = array_merge($attribs, $page->getCustomHtmlAttribs()); - - return '<' . $element . $this->_htmlAttribs($attribs) . '>' - . $this->view->escape($label) - . ''; - } - - /** - * Normalizes given render options - * - * @param array $options [optional] options to normalize - * @return array normalized options - */ - protected function _normalizeOptions(array $options = array()) - { - // Ident - if (isset($options['indent'])) { - $options['indent'] = $this->_getWhitespace($options['indent']); - } else { - $options['indent'] = $this->getIndent(); - } - - // Inner ident - if (isset($options['innerIndent'])) { - $options['innerIndent'] = - $this->_getWhitespace($options['innerIndent']); - } else { - $options['innerIndent'] = $this->getInnerIndent(); - } - - // UL class - if (isset($options['ulClass']) && $options['ulClass'] !== null) { - $options['ulClass'] = (string) $options['ulClass']; - } else { - $options['ulClass'] = $this->getUlClass(); - } - - // UL id - if (isset($options['ulId']) && $options['ulId'] !== null) { - $options['ulId'] = (string) $options['ulId']; - } else { - $options['ulId'] = $this->getUlId(); - } - - // Active class - if (isset($options['activeClass']) && $options['activeClass'] !== null - ) { - $options['activeClass'] = (string) $options['activeClass']; - } else { - $options['activeClass'] = $this->getActiveClass(); - } - - // Parent class - if (isset($options['parentClass']) && $options['parentClass'] !== null) { - $options['parentClass'] = (string) $options['parentClass']; - } else { - $options['parentClass'] = $this->getParentClass(); - } - - // Minimum depth - if (array_key_exists('minDepth', $options)) { - if (null !== $options['minDepth']) { - $options['minDepth'] = (int) $options['minDepth']; - } - } else { - $options['minDepth'] = $this->getMinDepth(); - } - - if ($options['minDepth'] < 0 || $options['minDepth'] === null) { - $options['minDepth'] = 0; - } - - // Maximum depth - if (array_key_exists('maxDepth', $options)) { - if (null !== $options['maxDepth']) { - $options['maxDepth'] = (int) $options['maxDepth']; - } - } else { - $options['maxDepth'] = $this->getMaxDepth(); - } - - // Only active branch - if (!isset($options['onlyActiveBranch'])) { - $options['onlyActiveBranch'] = $this->getOnlyActiveBranch(); - } - - // Expand sibling nodes of active branch - if (!isset($options['expandSiblingNodesOfActiveBranch'])) { - $options['expandSiblingNodesOfActiveBranch'] = $this->getExpandSiblingNodesOfActiveBranch(); - } - - // Render parents? - if (!isset($options['renderParents'])) { - $options['renderParents'] = $this->getRenderParents(); - } - - // Render parent class? - if (!isset($options['renderParentClass'])) { - $options['renderParentClass'] = $this->getRenderParentClass(); - } - - // Add page CSS class to LI element - if (!isset($options['addPageClassToLi'])) { - $options['addPageClassToLi'] = $this->getAddPageClassToLi(); - } - - return $options; - } - - // Render methods: - - /** - * Renders the deepest active menu within [$minDepth, $maxDeth], (called - * from {@link renderMenu()}) - * - * @param Zend_Navigation_Container $container container to render - * @param string $ulClass CSS class for first UL - * @param string $indent initial indentation - * @param string $innerIndent inner indentation - * @param int|null $minDepth minimum depth - * @param int|null $maxDepth maximum depth - * @param string|null $ulId unique identifier (id) - * for first UL - * @param bool $addPageClassToLi adds CSS class from - * page to li element - * @param string|null $activeClass CSS class for active - * element - * @param string $parentClass CSS class for parent - * li's - * @param bool $renderParentClass Render parent class? - * @return string rendered menu (HTML) - */ - protected function _renderDeepestMenu(Zend_Navigation_Container $container, - $ulClass, - $indent, - $innerIndent, - $minDepth, - $maxDepth, - $ulId, - $addPageClassToLi, - $activeClass, - $parentClass, - $renderParentClass) - { - if (!$active = $this->findActive($container, $minDepth - 1, $maxDepth)) { - return ''; - } - - // special case if active page is one below minDepth - if ($active['depth'] < $minDepth) { - if (!$active['page']->hasPages()) { - return ''; - } - } else if (!$active['page']->hasPages()) { - // found pages has no children; render siblings - $active['page'] = $active['page']->getParent(); - } else if (is_int($maxDepth) && $active['depth'] + 1 > $maxDepth) { - // children are below max depth; render siblings - $active['page'] = $active['page']->getParent(); - } - - $attribs = array( - 'class' => $ulClass, - 'id' => $ulId, - ); - - // We don't need a prefix for the menu ID (backup) - $skipValue = $this->_skipPrefixForId; - $this->skipPrefixForId(); - - $html = $indent . '_htmlAttribs($attribs) - . '>' - . $this->getEOL(); - - // Reset prefix for IDs - $this->_skipPrefixForId = $skipValue; - - foreach ($active['page'] as $subPage) { - if (!$this->accept($subPage)) { - continue; - } - - $liClass = ''; - if ($subPage->isActive(true) && $addPageClassToLi) { - $liClass = $this->_htmlAttribs( - array('class' => $activeClass . ' ' . $subPage->getClass()) - ); - } else if ($subPage->isActive(true)) { - $liClass = $this->_htmlAttribs(array('class' => $activeClass)); - } else if ($addPageClassToLi) { - $liClass = $this->_htmlAttribs( - array('class' => $subPage->getClass()) - ); - } - $html .= $indent . $innerIndent . '' . $this->getEOL(); - $html .= $indent . str_repeat($innerIndent, 2) . $this->htmlify($subPage) - . $this->getEOL(); - $html .= $indent . $innerIndent . '' . $this->getEOL(); - } - - $html .= $indent . ''; - - return $html; - } - - /** - * Renders a normal menu (called from {@link renderMenu()}) - * - * @param Zend_Navigation_Container $container container to render - * @param string $ulClass CSS class for first UL - * @param string $indent initial indentation - * @param string $innerIndent inner indentation - * @param int|null $minDepth minimum depth - * @param int|null $maxDepth maximum depth - * @param bool $onlyActive render only active branch? - * @param bool $expandSibs render siblings of active - * branch nodes? - * @param string|null $ulId unique identifier (id) - * for first UL - * @param bool $addPageClassToLi adds CSS class from - * page to li element - * @param string|null $activeClass CSS class for active - * element - * @param string $parentClass CSS class for parent - * li's - * @param bool $renderParentClass Render parent class? - * @return string rendered menu (HTML) - */ - protected function _renderMenu(Zend_Navigation_Container $container, - $ulClass, - $indent, - $innerIndent, - $minDepth, - $maxDepth, - $onlyActive, - $expandSibs, - $ulId, - $addPageClassToLi, - $activeClass, - $parentClass, - $renderParentClass) - { - $html = ''; - - // find deepest active - if ($found = $this->findActive($container, $minDepth, $maxDepth)) { - $foundPage = $found['page']; - $foundDepth = $found['depth']; - } else { - $foundPage = null; - } - - // create iterator - $iterator = new RecursiveIteratorIterator($container, - RecursiveIteratorIterator::SELF_FIRST); - if (is_int($maxDepth)) { - $iterator->setMaxDepth($maxDepth); - } - - // iterate container - $prevDepth = -1; - foreach ($iterator as $page) { - $depth = $iterator->getDepth(); - $isActive = $page->isActive(true); - if ($depth < $minDepth || !$this->accept($page)) { - // page is below minDepth or not accepted by acl/visibilty - continue; - } else if ($expandSibs && $depth > $minDepth) { - // page is not active itself, but might be in the active branch - $accept = false; - if ($foundPage) { - if ($foundPage->hasPage($page)) { - // accept if page is a direct child of the active page - $accept = true; - } else if ($page->getParent()->isActive(true)) { - // page is a sibling of the active branch... - $accept = true; - } - } - if (!$isActive && !$accept) { - continue; - } - } else if ($onlyActive && !$isActive) { - // page is not active itself, but might be in the active branch - $accept = false; - if ($foundPage) { - if ($foundPage->hasPage($page)) { - // accept if page is a direct child of the active page - $accept = true; - } else if ($foundPage->getParent()->hasPage($page)) { - // page is a sibling of the active page... - if (!$foundPage->hasPages() || - is_int($maxDepth) && $foundDepth + 1 > $maxDepth) { - // accept if active page has no children, or the - // children are too deep to be rendered - $accept = true; - } - } - } - - if (!$accept) { - continue; - } - } - - // make sure indentation is correct - $depth -= $minDepth; - $myIndent = $indent . str_repeat($innerIndent, $depth * 2); - - if ($depth > $prevDepth) { - $attribs = array(); - - // start new ul tag - if (0 == $depth) { - $attribs = array( - 'class' => $ulClass, - 'id' => $ulId, - ); - } - - // We don't need a prefix for the menu ID (backup) - $skipValue = $this->_skipPrefixForId; - $this->skipPrefixForId(); - - $html .= $myIndent . '_htmlAttribs($attribs) - . '>' - . $this->getEOL(); - - // Reset prefix for IDs - $this->_skipPrefixForId = $skipValue; - } else if ($prevDepth > $depth) { - // close li/ul tags until we're at current depth - for ($i = $prevDepth; $i > $depth; $i--) { - $ind = $indent . str_repeat($innerIndent, $i * 2); - $html .= $ind . $innerIndent . '' . $this->getEOL(); - $html .= $ind . '' . $this->getEOL(); - } - // close previous li tag - $html .= $myIndent . $innerIndent . '' . $this->getEOL(); - } else { - // close previous li tag - $html .= $myIndent . $innerIndent . '' . $this->getEOL(); - } - - // render li tag and page - $liClasses = array(); - // Is page active? - if ($isActive) { - $liClasses[] = $activeClass; - } - // Add CSS class from page to LI? - if ($addPageClassToLi) { - $liClasses[] = $page->getClass(); - } - // Add CSS class for parents to LI? - if ($renderParentClass && $page->hasChildren()) { - // Check max depth - if ((is_int($maxDepth) && ($depth + 1 < $maxDepth)) - || !is_int($maxDepth) - ) { - $liClasses[] = $parentClass; - } - } - - $html .= $myIndent . $innerIndent . '_htmlAttribs(array('class' => implode(' ', $liClasses))) - . '>' . $this->getEOL() - . $myIndent . str_repeat($innerIndent, 2) - . $this->htmlify($page) - . $this->getEOL(); - - // store as previous depth for next iteration - $prevDepth = $depth; - } - - if ($html) { - // done iterating container; close open ul/li tags - for ($i = $prevDepth+1; $i > 0; $i--) { - $myIndent = $indent . str_repeat($innerIndent . $innerIndent, $i - 1); - $html .= $myIndent . $innerIndent . '' . $this->getEOL() - . $myIndent . '' . $this->getEOL(); - } - $html = rtrim($html, $this->getEOL()); - } - - return $html; - } - - /** - * Renders helper - * - * Renders a HTML 'ul' for the given $container. If $container is not given, - * the container registered in the helper will be used. - * - * Available $options: - * - * - * @param Zend_Navigation_Container $container [optional] container to - * create menu from. Default - * is to use the container - * retrieved from - * {@link getContainer()}. - * @param array $options [optional] options for - * controlling rendering - * @return string rendered menu - */ - public function renderMenu(Zend_Navigation_Container $container = null, - array $options = array()) - { - if (null === $container) { - $container = $this->getContainer(); - } - - $options = $this->_normalizeOptions($options); - - if ($options['onlyActiveBranch'] && !$options['renderParents']) { - $html = $this->_renderDeepestMenu( - $container, - $options['ulClass'], - $options['indent'], - $options['innerIndent'], - $options['minDepth'], - $options['maxDepth'], - $options['ulId'], - $options['addPageClassToLi'], - $options['activeClass'], - $options['parentClass'], - $options['renderParentClass'] - ); - } else { - $html = $this->_renderMenu( - $container, - $options['ulClass'], - $options['indent'], - $options['innerIndent'], - $options['minDepth'], - $options['maxDepth'], - $options['onlyActiveBranch'], - $options['expandSiblingNodesOfActiveBranch'], - $options['ulId'], - $options['addPageClassToLi'], - $options['activeClass'], - $options['parentClass'], - $options['renderParentClass'] - ); - } - - return $html; - } - - /** - * Renders the inner-most sub menu for the active page in the $container - * - * This is a convenience method which is equivalent to the following call: - * - * renderMenu($container, array( - * 'indent' => $indent, - * 'ulClass' => $ulClass, - * 'minDepth' => null, - * 'maxDepth' => null, - * 'onlyActiveBranch' => true, - * 'renderParents' => false - * )); - * - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to render - * the container registered in - * the helper. - * @param string|null $ulClass [optional] CSS class to - * use for UL element. Default - * is to use the value from - * {@link getUlClass()}. - * @param string|int $indent [optional] indentation as - * a string or number of - * spaces. Default is to use - * the value retrieved from - * {@link getIndent()}. - * @param string|null $ulId [optional] Unique identifier - * (id) use for UL element - * @param bool $addPageClassToLi adds CSS class from - * page to li element - * @param string|int $innerIndent [optional] inner - * indentation as a string - * or number of spaces. - * Default is to use the - * {@link getInnerIndent()}. - * @return string rendered content - */ - public function renderSubMenu(Zend_Navigation_Container $container = null, - $ulClass = null, - $indent = null, - $ulId = null, - $addPageClassToLi = false, - $innerIndent = null) - { - return $this->renderMenu($container, array( - 'indent' => $indent, - 'innerIndent' => $innerIndent, - 'ulClass' => $ulClass, - 'minDepth' => null, - 'maxDepth' => null, - 'onlyActiveBranch' => true, - 'renderParents' => false, - 'ulId' => $ulId, - 'addPageClassToLi' => $addPageClassToLi, - )); - } - - /** - * Renders the given $container by invoking the partial view helper - * - * The container will simply be passed on as a model to the view script - * as-is, and will be available in the partial script as 'container', e.g. - * echo 'Number of pages: ', count($this->container);. - * - * @param Zend_Navigation_Container $container [optional] container to - * pass to view script. Default - * is to use the container - * registered in the helper. - * @param string|array $partial [optional] partial view - * script to use. Default is to - * use the partial registered - * in the helper. If an array - * is given, it is expected to - * contain two values; the - * partial view script to use, - * and the module where the - * script can be found. - * @return string helper output - * - * @throws Zend_View_Exception When no partial script is set - */ - public function renderPartial(Zend_Navigation_Container $container = null, - $partial = null) - { - if (null === $container) { - $container = $this->getContainer(); - } - - if (null === $partial) { - $partial = $this->getPartial(); - } - - if (empty($partial)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception( - 'Unable to render menu: No partial view script provided' - ); - $e->setView($this->view); - throw $e; - } - - $model = array( - 'container' => $container - ); - - if (is_array($partial)) { - if (count($partial) != 2) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception( - 'Unable to render menu: A view partial supplied as ' - . 'an array must contain two values: partial view ' - . 'script and module where script can be found' - ); - $e->setView($this->view); - throw $e; - } - - return $this->view->partial($partial[0], $partial[1], $model); - } - - return $this->view->partial($partial, null, $model); - } - - // Zend_View_Helper_Navigation_Helper: - - /** - * Renders menu - * - * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. - * - * If a partial view is registered in the helper, the menu will be rendered - * using the given partial script. If no partial is registered, the menu - * will be rendered as an 'ul' element by the helper's internal method. - * - * @see renderPartial() - * @see renderMenu() - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - */ - public function render(Zend_Navigation_Container $container = null) - { - if ($partial = $this->getPartial()) { - return $this->renderPartial($container, $partial); - } else { - return $this->renderMenu($container); - } - } -} diff --git a/lib/Zend/View/Helper/Navigation/Sitemap.php b/lib/Zend/View/Helper/Navigation/Sitemap.php deleted file mode 100644 index d3ced3aaeee..00000000000 --- a/lib/Zend/View/Helper/Navigation/Sitemap.php +++ /dev/null @@ -1,444 +0,0 @@ - tag - * - * @var string - */ - const SITEMAP_NS = 'http://www.sitemaps.org/schemas/sitemap/0.9'; - - /** - * Schema URL - * - * @var string - */ - const SITEMAP_XSD = 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd'; - - /** - * Whether the XML declaration should be included in XML output - * - * @var bool - */ - protected $_useXmlDeclaration = true; - - /** - * Whether sitemap should be validated using Zend_Validate_Sitemap_* - * - * @var bool - */ - protected $_useSitemapValidators = true; - - /** - * Whether sitemap should be schema validated when generated - * - * @var bool - */ - protected $_useSchemaValidation = false; - - /** - * Server url - * - * @var string - */ - protected $_serverUrl; - - /** - * View helper entry point: - * Retrieves helper and optionally sets container to operate on - * - * @param Zend_Navigation_Container $container [optional] container to - * operate on - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function sitemap(Zend_Navigation_Container $container = null) - { - if (null !== $container) { - $this->setContainer($container); - } - - return $this; - } - - // Accessors: - - /** - * Sets whether the XML declaration should be used in output - * - * @param bool $useXmlDecl whether XML delcaration - * should be rendered - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function setUseXmlDeclaration($useXmlDecl) - { - $this->_useXmlDeclaration = (bool) $useXmlDecl; - return $this; - } - - /** - * Returns whether the XML declaration should be used in output - * - * @return bool whether the XML declaration should be used in output - */ - public function getUseXmlDeclaration() - { - return $this->_useXmlDeclaration; - } - - /** - * Sets whether sitemap should be validated using Zend_Validate_Sitemap_* - * - * @param bool $useSitemapValidators whether sitemap validators - * should be used - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function setUseSitemapValidators($useSitemapValidators) - { - $this->_useSitemapValidators = (bool) $useSitemapValidators; - return $this; - } - - /** - * Returns whether sitemap should be validated using Zend_Validate_Sitemap_* - * - * @return bool whether sitemap should be validated using validators - */ - public function getUseSitemapValidators() - { - return $this->_useSitemapValidators; - } - - /** - * Sets whether sitemap should be schema validated when generated - * - * @param bool $schemaValidation whether sitemap should - * validated using XSD Schema - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function setUseSchemaValidation($schemaValidation) - { - $this->_useSchemaValidation = (bool) $schemaValidation; - return $this; - } - - /** - * Returns true if sitemap should be schema validated when generated - * - * @return bool - */ - public function getUseSchemaValidation() - { - return $this->_useSchemaValidation; - } - - /** - * Sets server url (scheme and host-related stuff without request URI) - * - * E.g. http://www.example.com - * - * @param string $serverUrl server URL to set (only - * scheme and host) - * @throws Zend_Uri_Exception if invalid server URL - * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns - * self - */ - public function setServerUrl($serverUrl) - { - #require_once 'Zend/Uri.php'; - $uri = Zend_Uri::factory($serverUrl); - $uri->setFragment(''); - $uri->setPath(''); - $uri->setQuery(''); - - if ($uri->valid()) { - $this->_serverUrl = $uri->getUri(); - } else { - #require_once 'Zend/Uri/Exception.php'; - $e = new Zend_Uri_Exception(sprintf( - 'Invalid server URL: "%s"', - $serverUrl)); - $e->setView($this->view); - throw $e; - } - - return $this; - } - - /** - * Returns server URL - * - * @return string server URL - */ - public function getServerUrl() - { - if (!isset($this->_serverUrl)) { - $this->_serverUrl = $this->view->serverUrl(); - } - - return $this->_serverUrl; - } - - // Helper methods: - - /** - * Escapes string for XML usage - * - * @param string $string string to escape - * @return string escaped string - */ - protected function _xmlEscape($string) - { - $enc = 'UTF-8'; - if ($this->view instanceof Zend_View_Interface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - - // do not encode existing HTML entities - return htmlspecialchars($string, ENT_QUOTES, $enc, false); - } - - // Public methods: - - /** - * Returns an escaped absolute URL for the given page - * - * @param Zend_Navigation_Page $page page to get URL from - * @return string - */ - public function url(Zend_Navigation_Page $page) - { - $href = $page->getHref(); - - if (!isset($href[0])) { - // no href - return ''; - } elseif ($href[0] == '/') { - // href is relative to root; use serverUrl helper - $url = $this->getServerUrl() . $href; - } elseif (preg_match('/^[a-z]+:/im', (string) $href)) { - // scheme is given in href; assume absolute URL already - $url = (string) $href; - } else { - // href is relative to current document; use url helpers - $url = $this->getServerUrl() - . rtrim($this->view->url(), '/') . '/' - . $href; - } - - return $this->_xmlEscape($url); - } - - /** - * Returns a DOMDocument containing the Sitemap XML for the given container - * - * @param Zend_Navigation_Container $container [optional] container to get - * breadcrumbs from, defaults - * to what is registered in the - * helper - * @return DOMDocument DOM representation of the - * container - * @throws Zend_View_Exception if schema validation is on - * and the sitemap is invalid - * according to the sitemap - * schema, or if sitemap - * validators are used and the - * loc element fails validation - */ - public function getDomSitemap(Zend_Navigation_Container $container = null) - { - if (null === $container) { - $container = $this->getContainer(); - } - - // check if we should validate using our own validators - if ($this->getUseSitemapValidators()) { - #require_once 'Zend/Validate/Sitemap/Changefreq.php'; - #require_once 'Zend/Validate/Sitemap/Lastmod.php'; - #require_once 'Zend/Validate/Sitemap/Loc.php'; - #require_once 'Zend/Validate/Sitemap/Priority.php'; - - // create validators - $locValidator = new Zend_Validate_Sitemap_Loc(); - $lastmodValidator = new Zend_Validate_Sitemap_Lastmod(); - $changefreqValidator = new Zend_Validate_Sitemap_Changefreq(); - $priorityValidator = new Zend_Validate_Sitemap_Priority(); - } - - // create document - $dom = new DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = $this->getFormatOutput(); - - // ...and urlset (root) element - $urlSet = $dom->createElementNS(self::SITEMAP_NS, 'urlset'); - $dom->appendChild($urlSet); - - // create iterator - $iterator = new RecursiveIteratorIterator($container, - RecursiveIteratorIterator::SELF_FIRST); - - $maxDepth = $this->getMaxDepth(); - if (is_int($maxDepth)) { - $iterator->setMaxDepth($maxDepth); - } - $minDepth = $this->getMinDepth(); - if (!is_int($minDepth) || $minDepth < 0) { - $minDepth = 0; - } - - // iterate container - foreach ($iterator as $page) { - if ($iterator->getDepth() < $minDepth || !$this->accept($page)) { - // page should not be included - continue; - } - - // get absolute url from page - if (!$url = $this->url($page)) { - // skip page if it has no url (rare case) - continue; - } - - // create url node for this page - $urlNode = $dom->createElementNS(self::SITEMAP_NS, 'url'); - $urlSet->appendChild($urlNode); - - if ($this->getUseSitemapValidators() && - !$locValidator->isValid($url)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - 'Encountered an invalid URL for Sitemap XML: "%s"', - $url)); - $e->setView($this->view); - throw $e; - } - - // put url in 'loc' element - $urlNode->appendChild($dom->createElementNS(self::SITEMAP_NS, - 'loc', $url)); - - // add 'lastmod' element if a valid lastmod is set in page - if (isset($page->lastmod)) { - $lastmod = strtotime((string) $page->lastmod); - - // prevent 1970-01-01... - if ($lastmod !== false) { - $lastmod = date('c', $lastmod); - } - - if (!$this->getUseSitemapValidators() || - $lastmodValidator->isValid($lastmod)) { - $urlNode->appendChild( - $dom->createElementNS(self::SITEMAP_NS, 'lastmod', - $lastmod) - ); - } - } - - // add 'changefreq' element if a valid changefreq is set in page - if (isset($page->changefreq)) { - $changefreq = $page->changefreq; - if (!$this->getUseSitemapValidators() || - $changefreqValidator->isValid($changefreq)) { - $urlNode->appendChild( - $dom->createElementNS(self::SITEMAP_NS, 'changefreq', - $changefreq) - ); - } - } - - // add 'priority' element if a valid priority is set in page - if (isset($page->priority)) { - $priority = $page->priority; - if (!$this->getUseSitemapValidators() || - $priorityValidator->isValid($priority)) { - $urlNode->appendChild( - $dom->createElementNS(self::SITEMAP_NS, 'priority', - $priority) - ); - } - } - } - - // validate using schema if specified - if ($this->getUseSchemaValidation()) { - if (!@$dom->schemaValidate(self::SITEMAP_XSD)) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception(sprintf( - 'Sitemap is invalid according to XML Schema at "%s"', - self::SITEMAP_XSD)); - $e->setView($this->view); - throw $e; - } - } - - return $dom; - } - - // Zend_View_Helper_Navigation_Helper: - - /** - * Renders helper - * - * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. - * - * @param Zend_Navigation_Container $container [optional] container to - * render. Default is to - * render the container - * registered in the helper. - * @return string helper output - */ - public function render(Zend_Navigation_Container $container = null) - { - $dom = $this->getDomSitemap($container); - - $xml = $this->getUseXmlDeclaration() ? - $dom->saveXML() : - $dom->saveXML($dom->documentElement); - - return rtrim($xml, self::EOL); - } -} diff --git a/lib/Zend/View/Helper/PaginationControl.php b/lib/Zend/View/Helper/PaginationControl.php deleted file mode 100644 index 728559622d1..00000000000 --- a/lib/Zend/View/Helper/PaginationControl.php +++ /dev/null @@ -1,145 +0,0 @@ -view = $view; - return $this; - } - - /** - * Sets the default view partial. - * - * @param string|array $partial View partial - */ - public static function setDefaultViewPartial($partial) - { - self::$_defaultViewPartial = $partial; - } - - /** - * Gets the default view partial - * - * @return string|array - */ - public static function getDefaultViewPartial() - { - return self::$_defaultViewPartial; - } - - /** - * Render the provided pages. This checks if $view->paginator is set and, - * if so, uses that. Also, if no scrolling style or partial are specified, - * the defaults will be used (if set). - * - * @param Zend_Paginator (Optional) $paginator - * @param string $scrollingStyle (Optional) Scrolling style - * @param string $partial (Optional) View partial - * @param array|string $params (Optional) params to pass to the partial - * @return string - * @throws Zend_View_Exception - */ - public function paginationControl(Zend_Paginator $paginator = null, $scrollingStyle = null, $partial = null, $params = null) - { - if ($paginator === null) { - if (isset($this->view->paginator) and $this->view->paginator !== null and $this->view->paginator instanceof Zend_Paginator) { - $paginator = $this->view->paginator; - } else { - /** - * @see Zend_View_Exception - */ - #require_once 'Zend/View/Exception.php'; - - $e = new Zend_View_Exception('No paginator instance provided or incorrect type'); - $e->setView($this->view); - throw $e; - } - } - - if ($partial === null) { - if (self::$_defaultViewPartial === null) { - /** - * @see Zend_View_Exception - */ - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('No view partial provided and no default set'); - $e->setView($this->view); - throw $e; - } - - $partial = self::$_defaultViewPartial; - } - - $pages = get_object_vars($paginator->getPages($scrollingStyle)); - - if ($params !== null) { - $pages = array_merge($pages, (array) $params); - } - - if (is_array($partial)) { - if (count($partial) != 2) { - /** - * @see Zend_View_Exception - */ - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('A view partial supplied as an array must contain two values: the filename and its module'); - $e->setView($this->view); - throw $e; - } - - if ($partial[1] !== null) { - return $this->view->partial($partial[0], $partial[1], $pages); - } - - $partial = $partial[0]; - } - - return $this->view->partial($partial, $pages); - } -} diff --git a/lib/Zend/View/Helper/Partial.php b/lib/Zend/View/Helper/Partial.php deleted file mode 100644 index 263c2a5ba38..00000000000 --- a/lib/Zend/View/Helper/Partial.php +++ /dev/null @@ -1,153 +0,0 @@ -cloneView(); - if (isset($this->partialCounter)) { - $view->partialCounter = $this->partialCounter; - } - if (isset($this->partialTotalCount)) { - $view->partialTotalCount = $this->partialTotalCount; - } - - if ((null !== $module) && is_string($module)) { - #require_once 'Zend/Controller/Front.php'; - $moduleDir = Zend_Controller_Front::getInstance()->getControllerDirectory($module); - if (null === $moduleDir) { - #require_once 'Zend/View/Helper/Partial/Exception.php'; - $e = new Zend_View_Helper_Partial_Exception('Cannot render partial; module does not exist'); - $e->setView($this->view); - throw $e; - } - $viewsDir = dirname($moduleDir) . '/views'; - $view->addBasePath($viewsDir); - } elseif ((null == $model) && (null !== $module) - && (is_array($module) || is_object($module))) - { - $model = $module; - } - - if (!empty($model)) { - if (is_array($model)) { - $view->assign($model); - } elseif (is_object($model)) { - if (null !== ($objectKey = $this->getObjectKey())) { - $view->assign($objectKey, $model); - } elseif (method_exists($model, 'toArray')) { - $view->assign($model->toArray()); - } else { - $view->assign(get_object_vars($model)); - } - } - } - - return $view->render($name); - } - - /** - * Clone the current View - * - * @return Zend_View_Interface - */ - public function cloneView() - { - $view = clone $this->view; - $view->clearVars(); - return $view; - } - - /** - * Set object key - * - * @param string $key - * @return Zend_View_Helper_Partial - */ - public function setObjectKey($key) - { - if (null === $key) { - $this->_objectKey = null; - } else { - $this->_objectKey = (string) $key; - } - - return $this; - } - - /** - * Retrieve object key - * - * The objectKey is the variable to which an object in the iterator will be - * assigned. - * - * @return null|string - */ - public function getObjectKey() - { - return $this->_objectKey; - } -} diff --git a/lib/Zend/View/Helper/Partial/Exception.php b/lib/Zend/View/Helper/Partial/Exception.php deleted file mode 100644 index 3dc59ffe107..00000000000 --- a/lib/Zend/View/Helper/Partial/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ -setView($this->view); - throw $e; - } - - if (is_object($model) - && (!$model instanceof Traversable) - && method_exists($model, 'toArray') - ) { - $model = $model->toArray(); - } - - $content = ''; - // reset the counter if it's call again - $this->partialCounter = 0; - $this->partialTotalCount = count($model); - - foreach ($model as $item) { - // increment the counter variable - $this->partialCounter++; - - $content .= $this->partial($name, $module, $item); - } - - return $content; - } -} diff --git a/lib/Zend/View/Helper/Placeholder.php b/lib/Zend/View/Helper/Placeholder.php deleted file mode 100644 index c1ea21cd00a..00000000000 --- a/lib/Zend/View/Helper/Placeholder.php +++ /dev/null @@ -1,87 +0,0 @@ -_registry = Zend_View_Helper_Placeholder_Registry::getRegistry(); - } - - - /** - * Placeholder helper - * - * @param string $name - * @return Zend_View_Helper_Placeholder_Container_Abstract - */ - public function placeholder($name) - { - $name = (string) $name; - return $this->_registry->getContainer($name); - } - - /** - * Retrieve the registry - * - * @return Zend_View_Helper_Placeholder_Registry - */ - public function getRegistry() - { - return $this->_registry; - } -} diff --git a/lib/Zend/View/Helper/Placeholder/Container.php b/lib/Zend/View/Helper/Placeholder/Container.php deleted file mode 100644 index b5670538651..00000000000 --- a/lib/Zend/View/Helper/Placeholder/Container.php +++ /dev/null @@ -1,36 +0,0 @@ -exchangeArray(array($value)); - } - - /** - * Prepend a value to the top of the container - * - * @param mixed $value - * @return void - */ - public function prepend($value) - { - $values = $this->getArrayCopy(); - array_unshift($values, $value); - $this->exchangeArray($values); - } - - /** - * Retrieve container value - * - * If single element registered, returns that element; otherwise, - * serializes to array. - * - * @return mixed - */ - public function getValue() - { - if (1 == count($this)) { - $keys = $this->getKeys(); - $key = array_shift($keys); - return $this[$key]; - } - - return $this->getArrayCopy(); - } - - /** - * Set prefix for __toString() serialization - * - * @param string $prefix - * @return Zend_View_Helper_Placeholder_Container - */ - public function setPrefix($prefix) - { - $this->_prefix = (string) $prefix; - return $this; - } - - /** - * Retrieve prefix - * - * @return string - */ - public function getPrefix() - { - return $this->_prefix; - } - - /** - * Set postfix for __toString() serialization - * - * @param string $postfix - * @return Zend_View_Helper_Placeholder_Container - */ - public function setPostfix($postfix) - { - $this->_postfix = (string) $postfix; - return $this; - } - - /** - * Retrieve postfix - * - * @return string - */ - public function getPostfix() - { - return $this->_postfix; - } - - /** - * Set separator for __toString() serialization - * - * Used to implode elements in container - * - * @param string $separator - * @return Zend_View_Helper_Placeholder_Container - */ - public function setSeparator($separator) - { - $this->_separator = (string) $separator; - return $this; - } - - /** - * Retrieve separator - * - * @return string - */ - public function getSeparator() - { - return $this->_separator; - } - - /** - * Set the indentation string for __toString() serialization, - * optionally, if a number is passed, it will be the number of spaces - * - * @param string|int $indent - * @return Zend_View_Helper_Placeholder_Container_Abstract - */ - public function setIndent($indent) - { - $this->_indent = $this->getWhitespace($indent); - return $this; - } - - /** - * Retrieve indentation - * - * @return string - */ - public function getIndent() - { - return $this->_indent; - } - - /** - * Retrieve whitespace representation of $indent - * - * @param int|string $indent - * @return string - */ - public function getWhitespace($indent) - { - if (is_int($indent)) { - $indent = str_repeat(' ', $indent); - } - - return (string) $indent; - } - - /** - * Start capturing content to push into placeholder - * - * @param int|string $type How to capture content into placeholder; append, prepend, or set - * @param null $key - * @throws Zend_View_Helper_Placeholder_Container_Exception - * @return void - */ - public function captureStart($type = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $key = null) - { - if ($this->_captureLock) { - #require_once 'Zend/View/Helper/Placeholder/Container/Exception.php'; - $e = new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest placeholder captures for the same placeholder'); - $e->setView($this->view); - throw $e; - } - - $this->_captureLock = true; - $this->_captureType = $type; - if ((null !== $key) && is_scalar($key)) { - $this->_captureKey = (string) $key; - } - ob_start(); - } - - /** - * End content capture - * - * @return void - */ - public function captureEnd() - { - $data = ob_get_clean(); - $key = null; - $this->_captureLock = false; - if (null !== $this->_captureKey) { - $key = $this->_captureKey; - } - switch ($this->_captureType) { - case self::SET: - if (null !== $key) { - $this[$key] = $data; - } else { - $this->exchangeArray(array($data)); - } - break; - case self::PREPEND: - if (null !== $key) { - $array = array($key => $data); - $values = $this->getArrayCopy(); - $final = $array + $values; - $this->exchangeArray($final); - } else { - $this->prepend($data); - } - break; - case self::APPEND: - default: - if (null !== $key) { - if (empty($this[$key])) { - $this[$key] = $data; - } else { - $this[$key] .= $data; - } - } else { - $this[$this->nextIndex()] = $data; - } - break; - } - } - - /** - * Get keys - * - * @return array - */ - public function getKeys() - { - $array = $this->getArrayCopy(); - return array_keys($array); - } - - /** - * Next Index - * - * as defined by the PHP manual - * @return int - */ - public function nextIndex() - { - $keys = $this->getKeys(); - if (0 == count($keys)) { - return 0; - } - - return $nextIndex = max($keys) + 1; - } - - /** - * Render the placeholder - * - * @param null $indent - * @return string - */ - public function toString($indent = null) - { - // Check items - if (0 === $this->count()) { - return ''; - } - - $indent = ($indent !== null) - ? $this->getWhitespace($indent) - : $this->getIndent(); - - $items = $this->getArrayCopy(); - $return = $indent - . $this->getPrefix() - . implode($this->getSeparator(), $items) - . $this->getPostfix(); - $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return); - return $return; - } - - /** - * Serialize object to string - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } -} diff --git a/lib/Zend/View/Helper/Placeholder/Container/Exception.php b/lib/Zend/View/Helper/Placeholder/Container/Exception.php deleted file mode 100644 index 9435f95c1c0..00000000000 --- a/lib/Zend/View/Helper/Placeholder/Container/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ -setRegistry(Zend_View_Helper_Placeholder_Registry::getRegistry()); - $this->setContainer($this->getRegistry()->getContainer($this->_regKey)); - } - - /** - * Retrieve registry - * - * @return Zend_View_Helper_Placeholder_Registry - */ - public function getRegistry() - { - return $this->_registry; - } - - /** - * Set registry object - * - * @param Zend_View_Helper_Placeholder_Registry $registry - * @return Zend_View_Helper_Placeholder_Container_Standalone - */ - public function setRegistry(Zend_View_Helper_Placeholder_Registry $registry) - { - $this->_registry = $registry; - return $this; - } - - /** - * Set whether or not auto escaping should be used - * - * @param bool $autoEscape whether or not to auto escape output - * @return Zend_View_Helper_Placeholder_Container_Standalone - */ - public function setAutoEscape($autoEscape = true) - { - $this->_autoEscape = ($autoEscape) ? true : false; - return $this; - } - - /** - * Return whether autoEscaping is enabled or disabled - * - * return bool - */ - public function getAutoEscape() - { - return $this->_autoEscape; - } - - /** - * Escape a string - * - * @param string $string - * @return string - */ - protected function _escape($string) - { - $enc = 'UTF-8'; - if ($this->view instanceof Zend_View_Interface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - - return htmlspecialchars((string) $string, ENT_COMPAT, $enc); - } - - /** - * Set container on which to operate - * - * @param Zend_View_Helper_Placeholder_Container_Abstract $container - * @return Zend_View_Helper_Placeholder_Container_Standalone - */ - public function setContainer(Zend_View_Helper_Placeholder_Container_Abstract $container) - { - $this->_container = $container; - return $this; - } - - /** - * Retrieve placeholder container - * - * @return Zend_View_Helper_Placeholder_Container_Abstract - */ - public function getContainer() - { - return $this->_container; - } - - /** - * Overloading: set property value - * - * @param string $key - * @param mixed $value - * @return void - */ - public function __set($key, $value) - { - $container = $this->getContainer(); - $container[$key] = $value; - } - - /** - * Overloading: retrieve property - * - * @param string $key - * @return mixed - */ - public function __get($key) - { - $container = $this->getContainer(); - if (isset($container[$key])) { - return $container[$key]; - } - - return null; - } - - /** - * Overloading: check if property is set - * - * @param string $key - * @return bool - */ - public function __isset($key) - { - $container = $this->getContainer(); - return isset($container[$key]); - } - - /** - * Overloading: unset property - * - * @param string $key - * @return void - */ - public function __unset($key) - { - $container = $this->getContainer(); - if (isset($container[$key])) { - unset($container[$key]); - } - } - - /** - * Overload - * - * Proxy to container methods - * - * @param string $method - * @param array $args - * @return mixed - */ - public function __call($method, $args) - { - $container = $this->getContainer(); - if (method_exists($container, $method)) { - $return = call_user_func_array(array($container, $method), $args); - if ($return === $container) { - // If the container is returned, we really want the current object - return $this; - } - return $return; - } - - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('Method "' . $method . '" does not exist'); - $e->setView($this->view); - throw $e; - } - - /** - * String representation - * - * @return string - */ - public function toString() - { - return $this->getContainer()->toString(); - } - - /** - * Cast to string representation - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Countable - * - * @return int - */ - public function count() - { - $container = $this->getContainer(); - return count($container); - } - - /** - * ArrayAccess: offsetExists - * - * @param string|int $offset - * @return bool - */ - public function offsetExists($offset) - { - return $this->getContainer()->offsetExists($offset); - } - - /** - * ArrayAccess: offsetGet - * - * @param string|int $offset - * @return mixed - */ - public function offsetGet($offset) - { - return $this->getContainer()->offsetGet($offset); - } - - /** - * ArrayAccess: offsetSet - * - * @param string|int $offset - * @param mixed $value - * @return void - */ - public function offsetSet($offset, $value) - { - return $this->getContainer()->offsetSet($offset, $value); - } - - /** - * ArrayAccess: offsetUnset - * - * @param string|int $offset - * @return void - */ - public function offsetUnset($offset) - { - return $this->getContainer()->offsetUnset($offset); - } - - /** - * IteratorAggregate: get Iterator - * - * @return Iterator - */ - public function getIterator() - { - return $this->getContainer()->getIterator(); - } -} diff --git a/lib/Zend/View/Helper/Placeholder/Registry.php b/lib/Zend/View/Helper/Placeholder/Registry.php deleted file mode 100644 index 6aab493d8d1..00000000000 --- a/lib/Zend/View/Helper/Placeholder/Registry.php +++ /dev/null @@ -1,188 +0,0 @@ -_items[$key] = new $this->_containerClass($value); - return $this->_items[$key]; - } - - /** - * Retrieve a placeholder container - * - * @param string $key - * @return Zend_View_Helper_Placeholder_Container_Abstract - */ - public function getContainer($key) - { - $key = (string) $key; - if (isset($this->_items[$key])) { - return $this->_items[$key]; - } - - $container = $this->createContainer($key); - - return $container; - } - - /** - * Does a particular container exist? - * - * @param string $key - * @return bool - */ - public function containerExists($key) - { - $key = (string) $key; - $return = array_key_exists($key, $this->_items); - return $return; - } - - /** - * Set the container for an item in the registry - * - * @param string $key - * @param Zend_View_Placeholder_Container_Abstract $container - * @return Zend_View_Placeholder_Registry - */ - public function setContainer($key, Zend_View_Helper_Placeholder_Container_Abstract $container) - { - $key = (string) $key; - $this->_items[$key] = $container; - return $this; - } - - /** - * Delete a container - * - * @param string $key - * @return bool - */ - public function deleteContainer($key) - { - $key = (string) $key; - if (isset($this->_items[$key])) { - unset($this->_items[$key]); - return true; - } - - return false; - } - - /** - * Set the container class to use - * - * @param string $name - * @return Zend_View_Helper_Placeholder_Registry - */ - public function setContainerClass($name) - { - if (!class_exists($name)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($name); - } - - $reflection = new ReflectionClass($name); - if (!$reflection->isSubclassOf(new ReflectionClass('Zend_View_Helper_Placeholder_Container_Abstract'))) { - #require_once 'Zend/View/Helper/Placeholder/Registry/Exception.php'; - $e = new Zend_View_Helper_Placeholder_Registry_Exception('Invalid Container class specified'); - $e->setView($this->view); - throw $e; - } - - $this->_containerClass = $name; - return $this; - } - - /** - * Retrieve the container class - * - * @return string - */ - public function getContainerClass() - { - return $this->_containerClass; - } -} diff --git a/lib/Zend/View/Helper/Placeholder/Registry/Exception.php b/lib/Zend/View/Helper/Placeholder/Registry/Exception.php deleted file mode 100644 index ed3f1422a00..00000000000 --- a/lib/Zend/View/Helper/Placeholder/Registry/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ -view->placeholder($placeholder)->captureStart(); - echo $this->view->render($script); - $this->view->placeholder($placeholder)->captureEnd(); - } -} diff --git a/lib/Zend/View/Helper/ServerUrl.php b/lib/Zend/View/Helper/ServerUrl.php deleted file mode 100644 index c38ec8bc86a..00000000000 --- a/lib/Zend/View/Helper/ServerUrl.php +++ /dev/null @@ -1,148 +0,0 @@ -setScheme($scheme); - - if (isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])) { - $this->setHost($_SERVER['HTTP_HOST']); - } else if (isset($_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'])) { - $name = $_SERVER['SERVER_NAME']; - $port = $_SERVER['SERVER_PORT']; - - if (($scheme == 'http' && $port == 80) || - ($scheme == 'https' && $port == 443)) { - $this->setHost($name); - } else { - $this->setHost($name . ':' . $port); - } - } - } - - /** - * View helper entry point: - * Returns the current host's URL like http://site.com - * - * @param string|boolean $requestUri [optional] if true, the request URI - * found in $_SERVER will be appended - * as a path. If a string is given, it - * will be appended as a path. Default - * is to not append any path. - * @return string server url - */ - public function serverUrl($requestUri = null) - { - if ($requestUri === true) { - $path = $_SERVER['REQUEST_URI']; - } else if (is_string($requestUri)) { - $path = $requestUri; - } else { - $path = ''; - } - - return $this->getScheme() . '://' . $this->getHost() . $path; - } - - /** - * Returns host - * - * @return string host - */ - public function getHost() - { - return $this->_host; - } - - /** - * Sets host - * - * @param string $host new host - * @return Zend_View_Helper_ServerUrl fluent interface, returns self - */ - public function setHost($host) - { - $this->_host = $host; - return $this; - } - - /** - * Returns scheme (typically http or https) - * - * @return string scheme (typically http or https) - */ - public function getScheme() - { - return $this->_scheme; - } - - /** - * Sets scheme (typically http or https) - * - * @param string $scheme new scheme (typically http or https) - * @return Zend_View_Helper_ServerUrl fluent interface, returns self - */ - public function setScheme($scheme) - { - $this->_scheme = $scheme; - return $this; - } -} diff --git a/lib/Zend/View/Helper/Translate.php b/lib/Zend/View/Helper/Translate.php deleted file mode 100644 index e107e55f6a2..00000000000 --- a/lib/Zend/View/Helper/Translate.php +++ /dev/null @@ -1,180 +0,0 @@ -setTranslator($translate); - } - } - - /** - * Translate a message - * You can give multiple params or an array of params. - * If you want to output another locale just set it as last single parameter - * Example 1: translate('%1\$s + %2\$s', $value1, $value2, $locale); - * Example 2: translate('%1\$s + %2\$s', array($value1, $value2), $locale); - * - * @param string $messageid Id of the message to be translated - * @return string|Zend_View_Helper_Translate Translated message - */ - public function translate($messageid = null) - { - if ($messageid === null) { - return $this; - } - - $translate = $this->getTranslator(); - $options = func_get_args(); - - array_shift($options); - $count = count($options); - $locale = null; - if ($count > 0) { - if (Zend_Locale::isLocale($options[($count - 1)], null, false) !== false) { - $locale = array_pop($options); - } - } - - if ((count($options) === 1) and (is_array($options[0]) === true)) { - $options = $options[0]; - } - - if ($translate !== null) { - $messageid = $translate->translate($messageid, $locale); - } - - if (count($options) === 0) { - return $messageid; - } - - return vsprintf($messageid, $options); - } - - /** - * Sets a translation Adapter for translation - * - * @param Zend_Translate|Zend_Translate_Adapter $translate Instance of Zend_Translate - * @throws Zend_View_Exception When no or a false instance was set - * @return Zend_View_Helper_Translate - */ - public function setTranslator($translate) - { - if ($translate instanceof Zend_Translate_Adapter) { - $this->_translator = $translate; - } else if ($translate instanceof Zend_Translate) { - $this->_translator = $translate->getAdapter(); - } else { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('You must set an instance of Zend_Translate or Zend_Translate_Adapter'); - $e->setView($this->view); - throw $e; - } - - return $this; - } - - /** - * Retrieve translation object - * - * @return Zend_Translate_Adapter|null - */ - public function getTranslator() - { - if ($this->_translator === null) { - #require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Translate')) { - $this->setTranslator(Zend_Registry::get('Zend_Translate')); - } - } - - return $this->_translator; - } - - /** - * Set's an new locale for all further translations - * - * @param string|Zend_Locale $locale New locale to set - * @throws Zend_View_Exception When no Zend_Translate instance was set - * @return Zend_View_Helper_Translate - */ - public function setLocale($locale = null) - { - $translate = $this->getTranslator(); - if ($translate === null) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('You must set an instance of Zend_Translate or Zend_Translate_Adapter'); - $e->setView($this->view); - throw $e; - } - - $translate->setLocale($locale); - return $this; - } - - /** - * Returns the set locale for translations - * - * @throws Zend_View_Exception When no Zend_Translate instance was set - * @return string|Zend_Locale - */ - public function getLocale() - { - $translate = $this->getTranslator(); - if ($translate === null) { - #require_once 'Zend/View/Exception.php'; - $e = new Zend_View_Exception('You must set an instance of Zend_Translate or Zend_Translate_Adapter'); - $e->setView($this->view); - throw $e; - } - - return $translate->getLocale(); - } -} diff --git a/lib/Zend/View/Helper/Url.php b/lib/Zend/View/Helper/Url.php deleted file mode 100644 index f2e28f7de0f..00000000000 --- a/lib/Zend/View/Helper/Url.php +++ /dev/null @@ -1,51 +0,0 @@ -getRouter(); - return $router->assemble($urlOptions, $name, $reset, $encode); - } -} diff --git a/lib/Zend/View/Helper/UserAgent.php b/lib/Zend/View/Helper/UserAgent.php deleted file mode 100644 index ef454198438..00000000000 --- a/lib/Zend/View/Helper/UserAgent.php +++ /dev/null @@ -1,83 +0,0 @@ -setUserAgent($userAgent); - } - return $this->getUserAgent(); - } - - /** - * Set UserAgent instance - * - * @param Zend_Http_UserAgent $userAgent - * @return Zend_View_Helper_UserAgent - */ - public function setUserAgent(Zend_Http_UserAgent $userAgent) - { - $this->_userAgent = $userAgent; - return $this; - } - - /** - * Retrieve UserAgent instance - * - * If none set, instantiates one using no configuration - * - * @return Zend_Http_UserAgent - */ - public function getUserAgent() - { - if (null === $this->_userAgent) { - #require_once 'Zend/Http/UserAgent.php'; - $this->setUserAgent(new Zend_Http_UserAgent()); - } - return $this->_userAgent; - } -} diff --git a/lib/Zend/View/Interface.php b/lib/Zend/View/Interface.php deleted file mode 100644 index 496ec7108ec..00000000000 --- a/lib/Zend/View/Interface.php +++ /dev/null @@ -1,137 +0,0 @@ - value pairs to set en - * masse. - * - * @see __set() - * @param string|array $spec The assignment strategy to use (key or array of key - * => value pairs) - * @param mixed $value (Optional) If assigning a named variable, use this - * as the value. - * @return void - */ - public function assign($spec, $value = null); - - /** - * Clear all assigned variables - * - * Clears all variables assigned to Zend_View either via {@link assign()} or - * property overloading ({@link __get()}/{@link __set()}). - * - * @return void - */ - public function clearVars(); - - /** - * Processes a view script and returns the output. - * - * @param string $name The script name to process. - * @return string The script output. - */ - public function render($name); -} diff --git a/lib/Zend/View/Stream.php b/lib/Zend/View/Stream.php deleted file mode 100644 index ae8d52419e4..00000000000 --- a/lib/Zend/View/Stream.php +++ /dev/null @@ -1,183 +0,0 @@ -_data = file_get_contents($path); - - /** - * If reading the file failed, update our local stat store - * to reflect the real stat of the file, then return on failure - */ - if ($this->_data === false) { - $this->_stat = stat($path); - return false; - } - - /** - * Convert to long-form and to - * - */ - $this->_data = preg_replace('/\<\?\=/', "_data); - $this->_data = preg_replace('/<\?(?!xml|php)/s', '_data); - - /** - * file_get_contents() won't update PHP's stat cache, so we grab a stat - * of the file to prevent additional reads should the script be - * requested again, which will make include() happy. - */ - $this->_stat = stat($path); - - return true; - } - - /** - * Included so that __FILE__ returns the appropriate info - * - * @return array - */ - public function url_stat() - { - return $this->_stat; - } - - /** - * Reads from the stream. - */ - public function stream_read($count) - { - $ret = substr($this->_data, $this->_pos, $count); - $this->_pos += strlen($ret); - return $ret; - } - - - /** - * Tells the current position in the stream. - */ - public function stream_tell() - { - return $this->_pos; - } - - - /** - * Tells if we are at the end of the stream. - */ - public function stream_eof() - { - return $this->_pos >= strlen($this->_data); - } - - - /** - * Stream statistics. - */ - public function stream_stat() - { - return $this->_stat; - } - - - /** - * Seek to a specific point in the stream. - */ - public function stream_seek($offset, $whence) - { - switch ($whence) { - case SEEK_SET: - if ($offset < strlen($this->_data) && $offset >= 0) { - $this->_pos = $offset; - return true; - } else { - return false; - } - break; - - case SEEK_CUR: - if ($offset >= 0) { - $this->_pos += $offset; - return true; - } else { - return false; - } - break; - - case SEEK_END: - if (strlen($this->_data) + $offset >= 0) { - $this->_pos = strlen($this->_data) + $offset; - return true; - } else { - return false; - } - break; - - default: - return false; - } - } -} diff --git a/lib/Zend/Wildfire/Channel/HttpHeaders.php b/lib/Zend/Wildfire/Channel/HttpHeaders.php deleted file mode 100644 index 17cd60e7a3e..00000000000 --- a/lib/Zend/Wildfire/Channel/HttpHeaders.php +++ /dev/null @@ -1,343 +0,0 @@ -_protocols[$uri])) { - $this->_protocols[$uri] = $this->_initProtocol($uri); - } - - $this->_registerControllerPlugin(); - - return $this->_protocols[$uri]; - } - - /** - * Initialize a new protocol - * - * @param string $uri The URI for the protocol to be initialized - * @return object Returns the new initialized protocol instance - * @throws Zend_Wildfire_Exception - */ - protected function _initProtocol($uri) - { - switch ($uri) { - case Zend_Wildfire_Protocol_JsonStream::PROTOCOL_URI; - return new Zend_Wildfire_Protocol_JsonStream(); - } - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Tyring to initialize unknown protocol for URI "'.$uri.'".'); - } - - - /** - * Flush all data from all protocols and send all data to response headers. - * - * @return boolean Returns TRUE if data was flushed - */ - public function flush() - { - if (!$this->_protocols || !$this->isReady()) { - return false; - } - - foreach ( $this->_protocols as $protocol ) { - - $payload = $protocol->getPayload($this); - - if ($payload) { - foreach( $payload as $message ) { - - $this->getResponse()->setHeader(self::$_headerPrefix.$message[0], - $message[1], true); - } - } - } - return true; - } - - /** - * Set the index of the plugin in the controller dispatch loop plugin stack - * - * @param integer $index The index of the plugin in the stack - * @return integer The previous index. - */ - public static function setControllerPluginStackIndex($index) - { - $previous = self::$_controllerPluginStackIndex; - self::$_controllerPluginStackIndex = $index; - return $previous; - } - - /** - * Register this object as a controller plugin. - * - * @return void - */ - protected function _registerControllerPlugin() - { - $controller = Zend_Controller_Front::getInstance(); - if (!$controller->hasPlugin(get_class($this))) { - $controller->registerPlugin($this, self::$_controllerPluginStackIndex); - } - } - - - /* - * Zend_Wildfire_Channel_Interface - */ - - /** - * Determine if channel is ready. - * - * The channel is ready as long as the request and response objects are initialized, - * can send headers and the FirePHP header exists in the User-Agent. - * - * If the header does not exist in the User-Agent, no appropriate client - * is making this request and the messages should not be sent. - * - * A timing issue arises when messages are logged before the request/response - * objects are initialized. In this case we do not yet know if the client - * will be able to accept the messages. If we consequently indicate that - * the channel is not ready, these messages will be dropped which is in - * most cases not the intended behaviour. The intent is to send them at the - * end of the request when the request/response objects will be available - * for sure. - * - * If the request/response objects are not yet initialized we assume if messages are - * logged, the client will be able to receive them. As soon as the request/response - * objects are availoable and a message is logged this assumption is challenged. - * If the client cannot accept the messages any further messages are dropped - * and messages sent prior are kept but discarded when the channel is finally - * flushed at the end of the request. - * - * When the channel is flushed the $forceCheckRequest option is used to force - * a check of the request/response objects. This is the last verification to ensure - * messages are only sent when the client can accept them. - * - * @param boolean $forceCheckRequest OPTIONAL Set to TRUE if the request must be checked - * @return boolean Returns TRUE if channel is ready. - */ - public function isReady($forceCheckRequest=false) - { - if (!$forceCheckRequest - && !$this->_request - && !$this->_response - ) { - return true; - } - - if (!($this->getRequest() instanceof Zend_Controller_Request_Http)) { - return false; - } - - return ($this->getResponse()->canSendHeaders() - && (preg_match_all( - '/\s?FirePHP\/([\.\d]*)\s?/si', - $this->getRequest()->getHeader('User-Agent'), - $m - ) || - (($header = $this->getRequest()->getHeader('X-FirePHP-Version')) - && preg_match_all('/^([\.\d]*)$/si', $header, $m) - )) - ); - } - - - /* - * Zend_Controller_Plugin_Abstract - */ - - /** - * Flush messages to headers as late as possible but before headers have been sent. - * - * @return void - */ - public function dispatchLoopShutdown() - { - $this->flush(); - } - - /** - * Get the request object - * - * @return Zend_Controller_Request_Abstract - * @throws Zend_Wildfire_Exception - */ - public function getRequest() - { - if (!$this->_request) { - $controller = Zend_Controller_Front::getInstance(); - $this->setRequest($controller->getRequest()); - } - if (!$this->_request) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Request objects not initialized.'); - } - return $this->_request; - } - - /** - * Get the response object - * - * @return Zend_Controller_Response_Abstract - * @throws Zend_Wildfire_Exception - */ - public function getResponse() - { - if (!$this->_response) { - $response = Zend_Controller_Front::getInstance()->getResponse(); - if ($response) { - $this->setResponse($response); - } - } - if (!$this->_response) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Response objects not initialized.'); - } - return $this->_response; - } -} diff --git a/lib/Zend/Wildfire/Channel/Interface.php b/lib/Zend/Wildfire/Channel/Interface.php deleted file mode 100644 index fccec351c9e..00000000000 --- a/lib/Zend/Wildfire/Channel/Interface.php +++ /dev/null @@ -1,38 +0,0 @@ - 1, /* The offset in the trace which identifies the source of the message */ - 'maxTraceDepth' => 99, /* Maximum depth for stack traces */ - 'maxObjectDepth' => 10, /* The maximum depth to traverse objects when encoding */ - 'maxArrayDepth' => 20, /* The maximum depth to traverse nested arrays when encoding */ - 'includeLineNumbers' => true /* Whether to include line and file info for each message */ - ); - - /** - * Filters used to exclude object members when encoding - * @var array - */ - protected $_objectFilters = array(); - - /** - * A stack of objects used during encoding to detect recursion - * @var array - */ - protected $_objectStack = array(); - - /** - * Create singleton instance. - * - * @param string $class OPTIONAL Subclass of Zend_Wildfire_Plugin_FirePhp - * @return Zend_Wildfire_Plugin_FirePhp Returns the singleton Zend_Wildfire_Plugin_FirePhp instance - * @throws Zend_Wildfire_Exception - */ - public static function init($class = null) - { - if (self::$_instance !== null) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Singleton instance of Zend_Wildfire_Plugin_FirePhp already exists!'); - } - if ($class !== null) { - if (!is_string($class)) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Third argument is not a class string'); - } - - if (!class_exists($class)) { - #require_once 'Zend/Loader.php'; - Zend_Loader::loadClass($class); - } - self::$_instance = new $class(); - if (!self::$_instance instanceof Zend_Wildfire_Plugin_FirePhp) { - self::$_instance = null; - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Invalid class to third argument. Must be subclass of Zend_Wildfire_Plugin_FirePhp.'); - } - } else { - self::$_instance = new self(); - } - - return self::$_instance; - } - - /** - * Constructor - * @return void - */ - protected function __construct() - { - $this->_channel = Zend_Wildfire_Channel_HttpHeaders::getInstance(); - $this->_channel->getProtocol(self::PROTOCOL_URI)->registerPlugin($this); - } - - /** - * Get or create singleton instance - * - * @param bool $skipCreate True if an instance should not be created - * @return Zend_Wildfire_Plugin_FirePhp - */ - public static function getInstance($skipCreate=false) - { - if (self::$_instance===null && $skipCreate!==true) { - return self::init(); - } - return self::$_instance; - } - - /** - * Destroys the singleton instance - * - * Primarily used for testing. - * - * @return void - */ - public static function destroyInstance() - { - self::$_instance = null; - } - - /** - * Enable or disable sending of messages to user-agent. - * If disabled all headers to be sent will be removed. - * - * @param boolean $enabled Set to TRUE to enable sending of messages. - * @return boolean The previous value. - */ - public function setEnabled($enabled) - { - $previous = $this->_enabled; - $this->_enabled = $enabled; - if (!$this->_enabled) { - $this->_messages = array(); - $this->_channel->getProtocol(self::PROTOCOL_URI)->clearMessages($this); - } - return $previous; - } - - /** - * Determine if logging to user-agent is enabled. - * - * @return boolean Returns TRUE if logging is enabled. - */ - public function getEnabled() - { - return $this->_enabled; - } - - /** - * Set a single option - * - * @param string $key The name of the option - * @param mixed $value The value of the option - * @return mixed The previous value of the option - */ - public function setOption($key, $value) - { - if (!array_key_exists($key,$this->_options)) { - throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!'); - } - $previous = $this->_options[$key]; - $this->_options[$key] = $value; - return $previous; - } - - /** - * Retrieve a single option - * - * @param string $key The name of the option - * @return mixed The value of the option - */ - public function getOption($key) - { - if (!array_key_exists($key,$this->_options)) { - throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!'); - } - return $this->_options[$key]; - } - - /** - * Retrieve all options - * - * @return array All options - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @param string $Class The class name of the object - * @param array $Filter An array of members to exclude - * @return void - */ - public function setObjectFilter($class, $filter) { - $this->_objectFilters[$class] = $filter; - } - - /** - * Starts a group in the Firebug Console - * - * @param string $title The title of the group - * @param array $options OPTIONAL Setting 'Collapsed' to true will initialize group collapsed instead of expanded - * @return TRUE if the group instruction was added to the response headers or buffered. - */ - public static function group($title, $options=array()) - { - return self::send(null, $title, self::GROUP_START, $options); - } - - /** - * Ends a group in the Firebug Console - * - * @return TRUE if the group instruction was added to the response headers or buffered. - */ - public static function groupEnd() - { - return self::send(null, null, self::GROUP_END); - } - - /** - * Logs variables to the Firebug Console - * via HTTP response headers and the FirePHP Firefox Extension. - * - * @param mixed $var The variable to log. - * @param string $label OPTIONAL Label to prepend to the log event. - * @param string $style OPTIONAL Style of the log event. - * @param array $options OPTIONAL Options to change how messages are processed and sent - * @return boolean Returns TRUE if the variable was added to the response headers or buffered. - * @throws Zend_Wildfire_Exception - */ - public static function send($var, $label=null, $style=null, $options=array()) - { - $firephp = self::getInstance(); - - if (!$firephp->getEnabled()) { - return false; - } - - if ($var instanceof Zend_Wildfire_Plugin_FirePhp_Message) { - - if ($var->getBuffered()) { - if (!in_array($var, self::$_instance->_messages)) { - self::$_instance->_messages[] = $var; - } - return true; - } - - if ($var->getDestroy()) { - return false; - } - - $style = $var->getStyle(); - $label = $var->getLabel(); - $options = $var->getOptions(); - $var = $var->getMessage(); - } - - if (!self::$_instance->_channel->isReady()) { - return false; - } - - foreach ($options as $name => $value) { - if ($value===null) { - unset($options[$name]); - } - } - $options = array_merge($firephp->getOptions(), $options); - - $trace = null; - - $skipFinalEncode = false; - - $meta = array(); - $meta['Type'] = $style; - - if ($var instanceof Exception) { - - $eTrace = $var->getTrace(); - $eTrace = array_splice($eTrace, 0, $options['maxTraceDepth']); - - $var = array('Class'=>get_class($var), - 'Message'=>$var->getMessage(), - 'File'=>$var->getFile(), - 'Line'=>$var->getLine(), - 'Type'=>'throw', - 'Trace'=>$firephp->_encodeTrace($eTrace)); - - $meta['Type'] = self::EXCEPTION; - - $skipFinalEncode = true; - - } else - if ($meta['Type']==self::TRACE) { - - if (!$label && $var) { - $label = $var; - $var = null; - } - - if (!$trace) { - $trace = $firephp->_getStackTrace(array_merge($options, - array('maxTraceDepth'=>$options['maxTraceDepth']+1))); - } - - $var = array('Class'=>$trace[0]['class'], - 'Type'=>$trace[0]['type'], - 'Function'=>$trace[0]['function'], - 'Message'=>$label, - 'File'=>isset($trace[0]['file'])?$trace[0]['file']:'', - 'Line'=>isset($trace[0]['line'])?$trace[0]['line']:'', - 'Args'=>isset($trace[0]['args'])?$firephp->_encodeObject($trace[0]['args']):'', - 'Trace'=>$firephp->_encodeTrace(array_splice($trace,1))); - - $skipFinalEncode = true; - - } else - if ($meta['Type']==self::TABLE) { - - $var = $firephp->_encodeTable($var); - - $skipFinalEncode = true; - - } else { - if ($meta['Type']===null) { - $meta['Type'] = self::LOG; - } - } - - if ($label!=null) { - $meta['Label'] = $label; - } - - switch ($meta['Type']) { - case self::LOG: - case self::INFO: - case self::WARN: - case self::ERROR: - case self::EXCEPTION: - case self::TRACE: - case self::TABLE: - case self::DUMP: - case self::GROUP_START: - case self::GROUP_END: - break; - default: - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Log style "'.$meta['Type'].'" not recognized!'); - break; - } - - if ($meta['Type'] != self::DUMP && $options['includeLineNumbers']) { - if (!isset($meta['File']) || !isset($meta['Line'])) { - - if (!$trace) { - $trace = $firephp->_getStackTrace(array_merge($options, - array('maxTraceDepth'=>$options['maxTraceDepth']+1))); - } - - $meta['File'] = isset($trace[0]['file'])?$trace[0]['file']:''; - $meta['Line'] = isset($trace[0]['line'])?$trace[0]['line']:''; - - } - } else { - unset($meta['File']); - unset($meta['Line']); - } - - if ($meta['Type'] == self::GROUP_START) { - if (isset($options['Collapsed'])) { - $meta['Collapsed'] = ($options['Collapsed'])?'true':'false'; - } - } - - if ($meta['Type'] == self::DUMP) { - - return $firephp->_recordMessage(self::STRUCTURE_URI_DUMP, - array('key'=>$meta['Label'], - 'data'=>$var), - $skipFinalEncode); - - } else { - - return $firephp->_recordMessage(self::STRUCTURE_URI_FIREBUGCONSOLE, - array('data'=>$var, - 'meta'=>$meta), - $skipFinalEncode); - } - } - - /** - * Gets a stack trace - * - * @param array $options Options to change how the stack trace is returned - * @return array The stack trace - */ - protected function _getStackTrace($options) - { - $trace = debug_backtrace(); - - $trace = array_splice($trace, $options['traceOffset']); - - if (!count($trace)) { - return $trace; - } - - if (isset($options['fixZendLogOffsetIfApplicable']) && $options['fixZendLogOffsetIfApplicable']) { - if (count($trace) >=3 && - isset($trace[0]['file']) && substr($trace[0]['file'], -7, 7)=='Log.php' && - isset($trace[1]['function']) && $trace[1]['function']=='__call') { - - $trace = array_splice($trace, 2); - } - } - - return array_splice($trace, 0, $options['maxTraceDepth']); - } - - /** - * Record a message with the given data in the given structure - * - * @param string $structure The structure to be used for the data - * @param array $data The data to be recorded - * @param boolean $skipEncode TRUE if variable encoding should be skipped - * @return boolean Returns TRUE if message was recorded - * @throws Zend_Wildfire_Exception - */ - protected function _recordMessage($structure, $data, $skipEncode=false) - { - switch($structure) { - - case self::STRUCTURE_URI_DUMP: - - if (!isset($data['key'])) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('You must supply a key.'); - } - if (!array_key_exists('data',$data)) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('You must supply data.'); - } - - $value = $data['data']; - if (!$skipEncode) { - $value = $this->_encodeObject($data['data']); - } - - return $this->_channel->getProtocol(self::PROTOCOL_URI)-> - recordMessage($this, - $structure, - array($data['key']=>$value)); - - case self::STRUCTURE_URI_FIREBUGCONSOLE: - - if (!isset($data['meta']) || - !is_array($data['meta']) || - !array_key_exists('Type',$data['meta'])) { - - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('You must supply a "Type" in the meta information.'); - } - if (!array_key_exists('data',$data)) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('You must supply data.'); - } - - $value = $data['data']; - if (!$skipEncode) { - $value = $this->_encodeObject($data['data']); - } - - return $this->_channel->getProtocol(self::PROTOCOL_URI)-> - recordMessage($this, - $structure, - array($data['meta'], - $value)); - - default: - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Structure of name "'.$structure.'" is not recognized.'); - break; - } - return false; - } - - /** - * Encodes a table by encoding each row and column with _encodeObject() - * - * @param array $Table The table to be encoded - * @return array - */ - protected function _encodeTable($table) - { - if (!$table) { - return $table; - } - for ($i=0 ; $i_encodeObject($table[$i][$j]); - } - } - } - return $table; - } - - /** - * Encodes a trace by encoding all "args" with _encodeObject() - * - * @param array $Trace The trace to be encoded - * @return array The encoded trace - */ - protected function _encodeTrace($trace) - { - if (!$trace) { - return $trace; - } - for ($i=0 ; $i_encodeObject($trace[$i]['args']); - } - } - return $trace; - } - - /** - * Encode an object by generating an array containing all object members. - * - * All private and protected members are included. Some meta info about - * the object class is added. - * - * @param mixed $object The object/array/value to be encoded - * @return array The encoded object - */ - protected function _encodeObject($object, $objectDepth = 1, $arrayDepth = 1) - { - $return = array(); - - if (is_resource($object)) { - - return '** '.(string)$object.' **'; - - } else - if (is_object($object)) { - - if ($objectDepth > $this->_options['maxObjectDepth']) { - return '** Max Object Depth ('.$this->_options['maxObjectDepth'].') **'; - } - - foreach ($this->_objectStack as $refVal) { - if ($refVal === $object) { - return '** Recursion ('.get_class($object).') **'; - } - } - array_push($this->_objectStack, $object); - - $return['__className'] = $class = get_class($object); - - $reflectionClass = new ReflectionClass($class); - $properties = array(); - foreach ( $reflectionClass->getProperties() as $property) { - $properties[$property->getName()] = $property; - } - - $members = (array)$object; - - foreach ($properties as $just_name => $property) { - - $name = $raw_name = $just_name; - - if ($property->isStatic()) { - $name = 'static:'.$name; - } - if ($property->isPublic()) { - $name = 'public:'.$name; - } else - if ($property->isPrivate()) { - $name = 'private:'.$name; - $raw_name = "\0".$class."\0".$raw_name; - } else - if ($property->isProtected()) { - $name = 'protected:'.$name; - $raw_name = "\0".'*'."\0".$raw_name; - } - - if (!(isset($this->_objectFilters[$class]) - && is_array($this->_objectFilters[$class]) - && in_array($just_name,$this->_objectFilters[$class]))) { - - if (array_key_exists($raw_name,$members) - && !$property->isStatic()) { - - $return[$name] = $this->_encodeObject($members[$raw_name], $objectDepth + 1, 1); - - } else { - if (method_exists($property,'setAccessible')) { - $property->setAccessible(true); - $return[$name] = $this->_encodeObject($property->getValue($object), $objectDepth + 1, 1); - } else - if ($property->isPublic()) { - $return[$name] = $this->_encodeObject($property->getValue($object), $objectDepth + 1, 1); - } else { - $return[$name] = '** Need PHP 5.3 to get value **'; - } - } - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - - // Include all members that are not defined in the class - // but exist in the object - foreach($members as $just_name => $value) { - - $name = $raw_name = $just_name; - - if ($name[0] == "\0") { - $parts = explode("\0", $name); - $name = $parts[2]; - } - if (!isset($properties[$name])) { - $name = 'undeclared:'.$name; - - if (!(isset($this->objectFilters[$class]) - && is_array($this->objectFilters[$class]) - && in_array($just_name,$this->objectFilters[$class]))) { - - $return[$name] = $this->_encodeObject($value, $objectDepth + 1, 1); - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - } - - array_pop($this->_objectStack); - - } elseif (is_array($object)) { - - if ($arrayDepth > $this->_options['maxArrayDepth']) { - return '** Max Array Depth ('.$this->_options['maxArrayDepth'].') **'; - } - - foreach ($object as $key => $val) { - - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if ($key=='GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS',$val)) { - - $val['GLOBALS'] = '** Recursion (GLOBALS) **'; - } - $return[$key] = $this->_encodeObject($val, 1, $arrayDepth + 1); - } - } else { - return $object; - } - return $return; - } - - /* - * Zend_Wildfire_Plugin_Interface - */ - - /** - * Get the unique indentifier for this plugin. - * - * @return string Returns the URI of the plugin. - */ - public function getUri() - { - return self::PLUGIN_URI; - } - - /** - * Flush any buffered data. - * - * @param string $protocolUri The URI of the protocol that should be flushed to - * @return void - */ - public function flushMessages($protocolUri) - { - if (!$this->_messages || $protocolUri!=self::PROTOCOL_URI) { - return; - } - - foreach( $this->_messages as $message ) { - if (!$message->getDestroy()) { - $this->send($message->getMessage(), - $message->getLabel(), - $message->getStyle(), - $message->getOptions()); - } - } - - $this->_messages = array(); - } -} diff --git a/lib/Zend/Wildfire/Plugin/FirePhp/Message.php b/lib/Zend/Wildfire/Plugin/FirePhp/Message.php deleted file mode 100644 index 78e98005a2d..00000000000 --- a/lib/Zend/Wildfire/Plugin/FirePhp/Message.php +++ /dev/null @@ -1,246 +0,0 @@ - null, /* The offset in the trace which identifies the source of the message */ - 'includeLineNumbers' => null /* Whether to include line and file info for this message */ - ); - - /** - * Creates a new message with the given style and message - * - * @param string $style Style of the message. - * @param mixed $message The message - * @return void - */ - function __construct($style, $message) - { - $this->_style = $style; - $this->_message = $message; - $this->_ruid = md5(microtime().mt_rand()); - } - - /** - * Set the label of the message - * - * @param string $label The label to be set - * @return void - */ - public function setLabel($label) - { - $this->_label = $label; - } - - /** - * Get the label of the message - * - * @return string The label of the message - */ - public function getLabel() - { - return $this->_label; - } - - /** - * Enable or disable message buffering - * - * If a message is buffered it can be updated for the duration of the - * request and is only flushed at the end of the request. - * - * @param boolean $buffered TRUE to enable buffering FALSE otherwise - * @return boolean Returns previous buffering value - */ - public function setBuffered($buffered) - { - $previous = $this->_buffered; - $this->_buffered = $buffered; - return $previous; - } - - /** - * Determine if buffering is enabled or disabled - * - * @return boolean Returns TRUE if buffering is enabled, FALSE otherwise. - */ - public function getBuffered() - { - return $this->_buffered; - } - - /** - * Destroy the message to prevent delivery - * - * @param boolean $destroy TRUE to destroy FALSE otherwise - * @return boolean Returns previous destroy value - */ - public function setDestroy($destroy) - { - $previous = $this->_destroy; - $this->_destroy = $destroy; - return $previous; - } - - /** - * Determine if message should be destroyed - * - * @return boolean Returns TRUE if message should be destroyed, FALSE otherwise. - */ - public function getDestroy() - { - return $this->_destroy; - } - - /** - * Set the style of the message - * - * @return void - */ - public function setStyle($style) - { - $this->_style = $style; - } - - /** - * Get the style of the message - * - * @return string The style of the message - */ - public function getStyle() - { - return $this->_style; - } - - /** - * Set the actual message to be sent in its final format. - * - * @return void - */ - public function setMessage($message) - { - $this->_message = $message; - } - - /** - * Get the actual message to be sent in its final format. - * - * @return mixed Returns the message to be sent. - */ - public function getMessage() - { - return $this->_message; - } - - /** - * Set a single option - * - * @param string $key The name of the option - * @param mixed $value The value of the option - * @return mixed The previous value of the option - */ - public function setOption($key, $value) - { - if(!array_key_exists($key,$this->_options)) { - throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!'); - } - $previous = $this->_options[$key]; - $this->_options[$key] = $value; - return $previous; - } - - /** - * Retrieve a single option - * - * @param string $key The name of the option - * @return mixed The value of the option - */ - public function getOption($key) - { - if(!array_key_exists($key,$this->_options)) { - throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!'); - } - return $this->_options[$key]; - } - - /** - * Retrieve all options - * - * @return array All options - */ - public function getOptions() - { - return $this->_options; - } -} - diff --git a/lib/Zend/Wildfire/Plugin/FirePhp/TableMessage.php b/lib/Zend/Wildfire/Plugin/FirePhp/TableMessage.php deleted file mode 100644 index eff631eb4c8..00000000000 --- a/lib/Zend/Wildfire/Plugin/FirePhp/TableMessage.php +++ /dev/null @@ -1,165 +0,0 @@ -setLabel($label); - } - - /** - * Set the table header - * - * @param array $header The header columns - * @return void - */ - public function setHeader($header) - { - $this->_header = $header; - } - - /** - * Append a row to the end of the table. - * - * @param array $row An array of column values representing a row. - * @return void - */ - public function addRow($row) - { - $this->_rows[] = $row; - } - - /** - * Get the actual message to be sent in its final format. - * - * @return mixed Returns the message to be sent. - */ - public function getMessage() - { - $table = $this->_rows; - if($this->_header) { - array_unshift($table,$this->_header); - } - return $table; - } - - /** - * Returns the row at the given index - * - * @param integer $index The index of the row - * @return array Returns the row - * @throws Zend_Wildfire_Exception - */ - public function getRowAt($index) - { - $count = $this->getRowCount(); - - if($index < 0 || $index > $count-1) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Row index('.$index.') out of bounds('.$count.')!'); - } - - return $this->_rows[$index]; - } - - /** - * Sets the row on the given index to a new row - * - * @param integer $index The index of the row - * @param array $row The new data for the row - * @throws Zend_Wildfire_Exception - */ - public function setRowAt($index, $row) - { - $count = $this->getRowCount(); - - if($index < 0 || $index > $count-1) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Row index('.$index.') out of bounds('.$count.')!'); - } - - $this->_rows[$index] = $row; - } - - /** - * Returns the number of rows - * - * @return integer - */ - public function getRowCount() - { - return count($this->_rows); - } - - /** - * Returns the last row of the table - * - * @return array Returns the last row - * @throws Zend_Wildfire_Exception - */ - public function getLastRow() - { - $count = $this->getRowCount(); - - if($count==0) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Cannot get last row as no rows exist!'); - } - - return $this->_rows[$count-1]; - } -} diff --git a/lib/Zend/Wildfire/Plugin/Interface.php b/lib/Zend/Wildfire/Plugin/Interface.php deleted file mode 100644 index 2943ca8e8a5..00000000000 --- a/lib/Zend/Wildfire/Plugin/Interface.php +++ /dev/null @@ -1,48 +0,0 @@ -_plugins)) { - return false; - } - $this->_plugins[] = $plugin; - return true; - } - - /** - * Record a message with the given data in the given structure - * - * @param Zend_Wildfire_Plugin_Interface $plugin The plugin recording the message - * @param string $structure The structure to be used for the data - * @param array $data The data to be recorded - * @return boolean Returns TRUE if message was recorded - */ - public function recordMessage(Zend_Wildfire_Plugin_Interface $plugin, $structure, $data) - { - if(!isset($this->_messages[$structure])) { - $this->_messages[$structure] = array(); - } - - $uri = $plugin->getUri(); - - if(!isset($this->_messages[$structure][$uri])) { - $this->_messages[$structure][$uri] = array(); - } - - $this->_messages[$structure][$uri][] = $this->_encode($data); - return true; - } - - /** - * Remove all qued messages - * - * @param Zend_Wildfire_Plugin_Interface $plugin The plugin for which to clear messages - * @return boolean Returns TRUE if messages were present - */ - public function clearMessages(Zend_Wildfire_Plugin_Interface $plugin) - { - $uri = $plugin->getUri(); - - $present = false; - foreach ($this->_messages as $structure => $messages) { - - if(!isset($this->_messages[$structure][$uri])) { - continue; - } - - $present = true; - - unset($this->_messages[$structure][$uri]); - - if (!$this->_messages[$structure]) { - unset($this->_messages[$structure]); - } - } - return $present; - } - - /** - * Get all qued messages - * - * @return mixed Returns qued messages or FALSE if no messages are qued - */ - public function getMessages() - { - if (!$this->_messages) { - return false; - } - return $this->_messages; - } - - /** - * Use the JSON encoding scheme for the value specified - * - * @param mixed $value The value to be encoded - * @return string The encoded value - */ - protected function _encode($value) - { - return Zend_Json::encode($value, true, array('silenceCyclicalExceptions'=>true)); - } - - /** - * Retrieves all formatted data ready to be sent by the channel. - * - * @param Zend_Wildfire_Channel_Interface $channel The instance of the channel that will be transmitting the data - * @return mixed Returns the data to be sent by the channel. - * @throws Zend_Wildfire_Exception - */ - public function getPayload(Zend_Wildfire_Channel_Interface $channel) - { - if (!$channel instanceof Zend_Wildfire_Channel_HttpHeaders) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('The '.get_class($channel).' channel is not supported by the '.get_class($this).' protocol.'); - } - - if ($this->_plugins) { - foreach ($this->_plugins as $plugin) { - $plugin->flushMessages(self::PROTOCOL_URI); - } - } - - if (!$this->_messages) { - return false; - } - - $protocol_index = 1; - $structure_index = 1; - $plugin_index = 1; - $message_index = 1; - - $payload = array(); - - $payload[] = array('Protocol-'.$protocol_index, self::PROTOCOL_URI); - - foreach ($this->_messages as $structure_uri => $plugin_messages ) { - - $payload[] = array($protocol_index.'-Structure-'.$structure_index, $structure_uri); - - foreach ($plugin_messages as $plugin_uri => $messages ) { - - $payload[] = array($protocol_index.'-Plugin-'.$plugin_index, $plugin_uri); - - foreach ($messages as $message) { - - $parts = explode("\n",chunk_split($message, 5000, "\n")); - - for ($i=0 ; $i2) { - $msg = (($i==0)?strlen($message):'') - . '|' . $part . '|' - . (($i 99999) { - #require_once 'Zend/Wildfire/Exception.php'; - throw new Zend_Wildfire_Exception('Maximum number (99,999) of messages reached!'); - } - } - } - } - $plugin_index++; - } - $structure_index++; - } - - return $payload; - } - -} - diff --git a/lib/Zend/Xml/Exception.php b/lib/Zend/Xml/Exception.php deleted file mode 100644 index e46648c3b04..00000000000 --- a/lib/Zend/Xml/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ - 0) { - return true; - } - return false; - } - - /** - * Scan XML string for potential XXE and XEE attacks - * - * @param string $xml - * @param DomDocument $dom - * @throws Zend_Xml_Exception - * @return SimpleXMLElement|DomDocument|boolean - */ - public static function scan($xml, DOMDocument $dom = null) - { - // If running with PHP-FPM we perform an heuristic scan - // We cannot use libxml_disable_entity_loader because of this bug - // @see https://bugs.php.net/bug.php?id=64938 - if (self::isPhpFpm()) { - self::heuristicScan($xml); - } - - if (null === $dom) { - $simpleXml = true; - $dom = new DOMDocument(); - } - - if (!self::isPhpFpm()) { - $loadEntities = libxml_disable_entity_loader(true); - $useInternalXmlErrors = libxml_use_internal_errors(true); - } - - // Load XML with network access disabled (LIBXML_NONET) - // error disabled with @ for PHP-FPM scenario - set_error_handler(array('Zend_Xml_Security', 'loadXmlErrorHandler'), E_WARNING); - - $result = $dom->loadXml($xml, LIBXML_NONET); - restore_error_handler(); - - if (!$result) { - // Entity load to previous setting - if (!self::isPhpFpm()) { - libxml_disable_entity_loader($loadEntities); - libxml_use_internal_errors($useInternalXmlErrors); - } - return false; - } - - // Scan for potential XEE attacks using ENTITY, if not PHP-FPM - if (!self::isPhpFpm()) { - foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - if ($child->entities->length > 0) { - #require_once 'Exception.php'; - throw new Zend_Xml_Exception(self::ENTITY_DETECT); - } - } - } - } - - // Entity load to previous setting - if (!self::isPhpFpm()) { - libxml_disable_entity_loader($loadEntities); - libxml_use_internal_errors($useInternalXmlErrors); - } - - if (isset($simpleXml)) { - $result = simplexml_import_dom($dom); - if (!$result instanceof SimpleXMLElement) { - return false; - } - return $result; - } - return $dom; - } - - /** - * Scan XML file for potential XXE/XEE attacks - * - * @param string $file - * @param DOMDocument $dom - * @throws Zend_Xml_Exception - * @return SimpleXMLElement|DomDocument - */ - public static function scanFile($file, DOMDocument $dom = null) - { - if (!file_exists($file)) { - #require_once 'Exception.php'; - throw new Zend_Xml_Exception( - "The file $file specified doesn't exist" - ); - } - return self::scan(file_get_contents($file), $dom); - } - - /** - * Return true if PHP is running with PHP-FPM - * - * This method is mainly used to determine whether or not heuristic checks - * (vs libxml checks) should be made, due to threading issues in libxml; - * under php-fpm, threading becomes a concern. - * - * However, PHP versions 5.5.22+ and 5.6.6+ contain a patch to the - * libxml support in PHP that makes the libxml checks viable; in such - * versions, this method will return false to enforce those checks, which - * are more strict and accurate than the heuristic checks. - * - * @return boolean - */ - public static function isPhpFpm() - { - $isVulnerableVersion = ( - version_compare(PHP_VERSION, '5.5.22', '<') - || ( - version_compare(PHP_VERSION, '5.6', '>=') - && version_compare(PHP_VERSION, '5.6.6', '<') - ) - ); - - if (substr(php_sapi_name(), 0, 3) === 'fpm' && $isVulnerableVersion) { - return true; - } - return false; - } - - /** - * Determine and return the string(s) to use for the $generator) { - $prefix = call_user_func($generator, '<' . '?xml'); - if (0 === strncmp($xml, $prefix, strlen($prefix))) { - return $encoding; - } - } - - // Fallback - return 'UTF-8'; - } - - /** - * Attempt to detect the specified XML encoding. - * - * Using the file's encoding, determines if an "encoding" attribute is - * present and well-formed in the XML declaration; if so, it returns a - * list with both the ASCII representation of that declaration and the - * original file encoding. - * - * If not, a list containing only the provided file encoding is returned. - * - * @param string $xml - * @param string $fileEncoding - * @return string[] Potential XML encodings - */ - protected static function detectXmlEncoding($xml, $fileEncoding) - { - $encodingMap = self::getAsciiEncodingMap(); - $generator = $encodingMap[$fileEncoding]; - $encAttr = call_user_func($generator, 'encoding="'); - $quote = call_user_func($generator, '"'); - $close = call_user_func($generator, '>'); - - $closePos = strpos($xml, $close); - if (false === $closePos) { - return array($fileEncoding); - } - - $encPos = strpos($xml, $encAttr); - if (false === $encPos - || $encPos > $closePos - ) { - return array($fileEncoding); - } - - $encPos += strlen($encAttr); - $quotePos = strpos($xml, $quote, $encPos); - if (false === $quotePos) { - return array($fileEncoding); - } - - $encoding = self::substr($xml, $encPos, $quotePos); - return array( - // Following line works because we're only supporting 8-bit safe encodings at this time. - str_replace('\0', '', $encoding), // detected encoding - $fileEncoding, // file encoding - ); - } - - /** - * Return a list of BOM maps. - * - * Returns a list of common encoding -> BOM maps, along with the character - * length to compare against. - * - * @link https://en.wikipedia.org/wiki/Byte_order_mark - * @return array - */ - protected static function getBomMap() - { - return array( - array( - 'encoding' => 'UTF-32BE', - 'bom' => pack('CCCC', 0x00, 0x00, 0xfe, 0xff), - 'length' => 4, - ), - array( - 'encoding' => 'UTF-32LE', - 'bom' => pack('CCCC', 0xff, 0xfe, 0x00, 0x00), - 'length' => 4, - ), - array( - 'encoding' => 'GB-18030', - 'bom' => pack('CCCC', 0x84, 0x31, 0x95, 0x33), - 'length' => 4, - ), - array( - 'encoding' => 'UTF-16BE', - 'bom' => pack('CC', 0xfe, 0xff), - 'length' => 2, - ), - array( - 'encoding' => 'UTF-16LE', - 'bom' => pack('CC', 0xff, 0xfe), - 'length' => 2, - ), - array( - 'encoding' => 'UTF-8', - 'bom' => pack('CCC', 0xef, 0xbb, 0xbf), - 'length' => 3, - ), - ); - } - - /** - * Return a map of encoding => generator pairs. - * - * Returns a map of encoding => generator pairs, where the generator is a - * callable that accepts a string and returns the appropriate byte order - * sequence of that string for the encoding. - * - * @return array - */ - protected static function getAsciiEncodingMap() - { - return array( - 'UTF-32BE' => array(__CLASS__, 'encodeToUTF32BE'), - 'UTF-32LE' => array(__CLASS__, 'encodeToUTF32LE'), - 'UTF-32odd1' => array(__CLASS__, 'encodeToUTF32odd1'), - 'UTF-32odd2' => array(__CLASS__, 'encodeToUTF32odd2'), - 'UTF-16BE' => array(__CLASS__, 'encodeToUTF16BE'), - 'UTF-16LE' => array(__CLASS__, 'encodeToUTF16LE'), - 'UTF-8' => array(__CLASS__, 'encodeToUTF8'), - 'GB-18030' => array(__CLASS__, 'encodeToUTF8'), - ); - } - - /** - * Binary-safe substr. - * - * substr() is not binary-safe; this method loops by character to ensure - * multi-byte characters are aggregated correctly. - * - * @param string $string - * @param int $start - * @param int $end - * @return string - */ - protected static function substr($string, $start, $end) - { - $substr = ''; - for ($i = $start; $i < $end; $i += 1) { - $substr .= $string[$i]; - } - return $substr; - } - - /** - * Generate an entity comparison based on the given encoding. - * - * This patch is internal only, and public only so it can be used as a - * callable to pass to array_map. - * - * @internal - * @param string $encoding - * @return string - */ - public static function generateEntityComparison($encoding) - { - $encodingMap = self::getAsciiEncodingMap(); - $generator = isset($encodingMap[$encoding]) ? $encodingMap[$encoding] : $encodingMap['UTF-8']; - return call_user_func($generator, '_httpClient = new Zend_Http_Client(); - } else { - $this->_httpClient = $httpClient; - } - - $this->_introspector = new Zend_XmlRpc_Client_ServerIntrospection($this); - $this->_serverAddress = $server; - } - - - /** - * Sets the HTTP client object to use for connecting the XML-RPC server. - * - * @param Zend_Http_Client $httpClient - * @return Zend_Http_Client - */ - public function setHttpClient(Zend_Http_Client $httpClient) - { - return $this->_httpClient = $httpClient; - } - - - /** - * Gets the HTTP client object. - * - * @return Zend_Http_Client - */ - public function getHttpClient() - { - return $this->_httpClient; - } - - - /** - * Sets the object used to introspect remote servers - * - * @param Zend_XmlRpc_Client_ServerIntrospection - * @return Zend_XmlRpc_Client_ServerIntrospection - */ - public function setIntrospector(Zend_XmlRpc_Client_ServerIntrospection $introspector) - { - return $this->_introspector = $introspector; - } - - - /** - * Gets the introspection object. - * - * @return Zend_XmlRpc_Client_ServerIntrospection - */ - public function getIntrospector() - { - return $this->_introspector; - } - - - /** - * The request of the last method call - * - * @return Zend_XmlRpc_Request - */ - public function getLastRequest() - { - return $this->_lastRequest; - } - - - /** - * The response received from the last method call - * - * @return Zend_XmlRpc_Response - */ - public function getLastResponse() - { - return $this->_lastResponse; - } - - - /** - * Returns a proxy object for more convenient method calls - * - * @param string $namespace Namespace to proxy or empty string for none - * @return Zend_XmlRpc_Client_ServerProxy - */ - public function getProxy($namespace = '') - { - if (empty($this->_proxyCache[$namespace])) { - $proxy = new Zend_XmlRpc_Client_ServerProxy($this, $namespace); - $this->_proxyCache[$namespace] = $proxy; - } - return $this->_proxyCache[$namespace]; - } - - /** - * Set skip system lookup flag - * - * @param bool $flag - * @return Zend_XmlRpc_Client - */ - public function setSkipSystemLookup($flag = true) - { - $this->_skipSystemLookup = (bool) $flag; - return $this; - } - - /** - * Skip system lookup when determining if parameter should be array or struct? - * - * @return bool - */ - public function skipSystemLookup() - { - return $this->_skipSystemLookup; - } - - /** - * Perform an XML-RPC request and return a response. - * - * @param Zend_XmlRpc_Request $request - * @param null|Zend_XmlRpc_Response $response - * @return void - * @throws Zend_XmlRpc_Client_HttpException - */ - public function doRequest($request, $response = null) - { - $this->_lastRequest = $request; - - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('input_encoding', 'UTF-8'); - iconv_set_encoding('output_encoding', 'UTF-8'); - iconv_set_encoding('internal_encoding', 'UTF-8'); - } else { - ini_set('input_encoding', 'UTF-8'); - ini_set('output_encoding', 'UTF-8'); - ini_set('default_charset', 'UTF-8'); - } - - $http = $this->getHttpClient(); - if($http->getUri() === null) { - $http->setUri($this->_serverAddress); - } - - $http->setHeaders(array( - 'Content-Type: text/xml; charset=utf-8', - 'Accept: text/xml', - )); - - if ($http->getHeader('user-agent') === null) { - $http->setHeaders(array('User-Agent: Zend_XmlRpc_Client')); - } - - $xml = $this->_lastRequest->__toString(); - $http->setRawData($xml); - $httpResponse = $http->request(Zend_Http_Client::POST); - - if (! $httpResponse->isSuccessful()) { - /** - * Exception thrown when an HTTP error occurs - * @see Zend_XmlRpc_Client_HttpException - */ - #require_once 'Zend/XmlRpc/Client/HttpException.php'; - throw new Zend_XmlRpc_Client_HttpException( - $httpResponse->getMessage(), - $httpResponse->getStatus()); - } - - if ($response === null) { - $response = new Zend_XmlRpc_Response(); - } - $this->_lastResponse = $response; - $this->_lastResponse->loadXml(trim($httpResponse->getBody())); - } - - /** - * Send an XML-RPC request to the service (for a specific method) - * - * @param string $method Name of the method we want to call - * @param array $params Array of parameters for the method - * @return mixed - * @throws Zend_XmlRpc_Client_FaultException - */ - public function call($method, $params=array()) - { - if (!$this->skipSystemLookup() && ('system.' != substr($method, 0, 7))) { - // Ensure empty array/struct params are cast correctly - // If system.* methods are not available, bypass. (ZF-2978) - $success = true; - try { - $signatures = $this->getIntrospector()->getMethodSignature($method); - } catch (Zend_XmlRpc_Exception $e) { - $success = false; - } - if ($success) { - $validTypes = array( - Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY, - Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64, - Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN, - Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME, - Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE, - Zend_XmlRpc_Value::XMLRPC_TYPE_I4, - Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER, - Zend_XmlRpc_Value::XMLRPC_TYPE_NIL, - Zend_XmlRpc_Value::XMLRPC_TYPE_STRING, - Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT, - ); - - if (!is_array($params)) { - $params = array($params); - } - - foreach ($params as $key => $param) - { - if ($param instanceof Zend_XmlRpc_Value) { - continue; - } - - if (count($signatures) > 1) { - $type = Zend_XmlRpc_Value::getXmlRpcTypeByValue($param); - foreach ($signatures as $signature) { - if (!is_array($signature)) { - continue; - } - if (isset($signature['parameters'][$key])) { - if ($signature['parameters'][$key] == $type) { - break; - } - } - } - } elseif (isset($signatures[0]['parameters'][$key])) { - $type = $signatures[0]['parameters'][$key]; - } else { - $type = null; - } - - if (empty($type) || !in_array($type, $validTypes)) { - $type = Zend_XmlRpc_Value::AUTO_DETECT_TYPE; - } - - $params[$key] = Zend_XmlRpc_Value::getXmlRpcValue($param, $type); - } - } - } - - $request = $this->_createRequest($method, $params); - - $this->doRequest($request); - - if ($this->_lastResponse->isFault()) { - $fault = $this->_lastResponse->getFault(); - /** - * Exception thrown when an XML-RPC fault is returned - * @see Zend_XmlRpc_Client_FaultException - */ - #require_once 'Zend/XmlRpc/Client/FaultException.php'; - throw new Zend_XmlRpc_Client_FaultException($fault->getMessage(), - $fault->getCode()); - } - - return $this->_lastResponse->getReturnValue(); - } - - /** - * Create request object - * - * @return Zend_XmlRpc_Request - */ - protected function _createRequest($method, $params) - { - return new Zend_XmlRpc_Request($method, $params); - } -} diff --git a/lib/Zend/XmlRpc/Client/Exception.php b/lib/Zend/XmlRpc/Client/Exception.php deleted file mode 100644 index 000b993f3e1..00000000000 --- a/lib/Zend/XmlRpc/Client/Exception.php +++ /dev/null @@ -1,40 +0,0 @@ -_system = $client->getProxy('system'); - } - - /** - * Returns the signature for each method on the server, - * autodetecting whether system.multicall() is supported and - * using it if so. - * - * @return array - */ - public function getSignatureForEachMethod() - { - $methods = $this->listMethods(); - - #require_once 'Zend/XmlRpc/Client/FaultException.php'; - try { - $signatures = $this->getSignatureForEachMethodByMulticall($methods); - } catch (Zend_XmlRpc_Client_FaultException $e) { - // degrade to looping - } - - if (empty($signatures)) { - $signatures = $this->getSignatureForEachMethodByLooping($methods); - } - - return $signatures; - } - - /** - * Attempt to get the method signatures in one request via system.multicall(). - * This is a boxcar feature of XML-RPC and is found on fewer servers. However, - * can significantly improve performance if present. - * - * @param array $methods - * @return array array(array(return, param, param, param...)) - */ - public function getSignatureForEachMethodByMulticall($methods = null) - { - if ($methods === null) { - $methods = $this->listMethods(); - } - - $multicallParams = array(); - foreach ($methods as $method) { - $multicallParams[] = array('methodName' => 'system.methodSignature', - 'params' => array($method)); - } - - $serverSignatures = $this->_system->multicall($multicallParams); - - if (! is_array($serverSignatures)) { - $type = gettype($serverSignatures); - $error = "Multicall return is malformed. Expected array, got $type"; - #require_once 'Zend/XmlRpc/Client/IntrospectException.php'; - throw new Zend_XmlRpc_Client_IntrospectException($error); - } - - if (count($serverSignatures) != count($methods)) { - $error = 'Bad number of signatures received from multicall'; - #require_once 'Zend/XmlRpc/Client/IntrospectException.php'; - throw new Zend_XmlRpc_Client_IntrospectException($error); - } - - // Create a new signatures array with the methods name as keys and the signature as value - $signatures = array(); - foreach ($serverSignatures as $i => $signature) { - $signatures[$methods[$i]] = $signature; - } - - return $signatures; - } - - /** - * Get the method signatures for every method by - * successively calling system.methodSignature - * - * @param array $methods - * @return array - */ - public function getSignatureForEachMethodByLooping($methods = null) - { - if ($methods === null) { - $methods = $this->listMethods(); - } - - $signatures = array(); - foreach ($methods as $method) { - $signatures[$method] = $this->getMethodSignature($method); - } - - return $signatures; - } - - /** - * Call system.methodSignature() for the given method - * - * @param array $method - * @return array array(array(return, param, param, param...)) - */ - public function getMethodSignature($method) - { - $signature = $this->_system->methodSignature($method); - if (!is_array($signature)) { - $error = 'Invalid signature for method "' . $method . '"'; - #require_once 'Zend/XmlRpc/Client/IntrospectException.php'; - throw new Zend_XmlRpc_Client_IntrospectException($error); - } - return $signature; - } - - /** - * Call system.listMethods() - * - * @param array $method - * @return array array(method, method, method...) - */ - public function listMethods() - { - return $this->_system->listMethods(); - } - -} diff --git a/lib/Zend/XmlRpc/Client/ServerProxy.php b/lib/Zend/XmlRpc/Client/ServerProxy.php deleted file mode 100644 index 516619773b9..00000000000 --- a/lib/Zend/XmlRpc/Client/ServerProxy.php +++ /dev/null @@ -1,95 +0,0 @@ -foo->bar->baz()". - * - * @category Zend - * @package Zend_XmlRpc - * @subpackage Client - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_XmlRpc_Client_ServerProxy -{ - /** - * @var Zend_XmlRpc_Client - */ - private $_client = null; - - /** - * @var string - */ - private $_namespace = ''; - - - /** - * @var array of Zend_XmlRpc_Client_ServerProxy - */ - private $_cache = array(); - - - /** - * Class constructor - * - * @param string $namespace - * @param Zend_XmlRpc_Client $client - */ - public function __construct($client, $namespace = '') - { - $this->_namespace = $namespace; - $this->_client = $client; - } - - - /** - * Get the next successive namespace - * - * @param string $name - * @return Zend_XmlRpc_Client_ServerProxy - */ - public function __get($namespace) - { - $namespace = ltrim("$this->_namespace.$namespace", '.'); - if (!isset($this->_cache[$namespace])) { - $this->_cache[$namespace] = new $this($this->_client, $namespace); - } - return $this->_cache[$namespace]; - } - - - /** - * Call a method in this namespace. - * - * @param string $methodN - * @param array $args - * @return mixed - */ - public function __call($method, $args) - { - $method = ltrim("$this->_namespace.$method", '.'); - return $this->_client->call($method, $args); - } -} diff --git a/lib/Zend/XmlRpc/Exception.php b/lib/Zend/XmlRpc/Exception.php deleted file mode 100644 index 8b079192354..00000000000 --- a/lib/Zend/XmlRpc/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ - messages - * @var array - */ - protected $_internal = array( - 404 => 'Unknown Error', - - // 610 - 619 reflection errors - 610 => 'Invalid method class', - 611 => 'Unable to attach function or callback; not callable', - 612 => 'Unable to load array; not an array', - 613 => 'One or more method records are corrupt or otherwise unusable', - - // 620 - 629 dispatch errors - 620 => 'Method does not exist', - 621 => 'Error instantiating class to invoke method', - 622 => 'Method missing implementation', - 623 => 'Calling parameters do not match signature', - - // 630 - 639 request errors - 630 => 'Unable to read request', - 631 => 'Failed to parse request', - 632 => 'Invalid request, no method passed; request must contain a \'methodName\' tag', - 633 => 'Param must contain a value', - 634 => 'Invalid method name', - 635 => 'Invalid XML provided to request', - 636 => 'Error creating xmlrpc value', - - // 640 - 649 system.* errors - 640 => 'Method does not exist', - - // 650 - 659 response errors - 650 => 'Invalid XML provided for response', - 651 => 'Failed to parse response', - 652 => 'Invalid response', - 653 => 'Invalid XMLRPC value in response', - ); - - /** - * Constructor - * - * @return Zend_XmlRpc_Fault - */ - public function __construct($code = 404, $message = '') - { - $this->setCode($code); - $code = $this->getCode(); - - if (empty($message) && isset($this->_internal[$code])) { - $message = $this->_internal[$code]; - } elseif (empty($message)) { - $message = 'Unknown error'; - } - $this->setMessage($message); - } - - /** - * Set the fault code - * - * @param int $code - * @return Zend_XmlRpc_Fault - */ - public function setCode($code) - { - $this->_code = (int) $code; - return $this; - } - - /** - * Return fault code - * - * @return int - */ - public function getCode() - { - return $this->_code; - } - - /** - * Retrieve fault message - * - * @param string - * @return Zend_XmlRpc_Fault - */ - public function setMessage($message) - { - $this->_message = (string) $message; - return $this; - } - - /** - * Retrieve fault message - * - * @return string - */ - public function getMessage() - { - return $this->_message; - } - - /** - * Set encoding to use in fault response - * - * @param string $encoding - * @return Zend_XmlRpc_Fault - */ - public function setEncoding($encoding) - { - $this->_encoding = $encoding; - Zend_XmlRpc_Value::setEncoding($encoding); - return $this; - } - - /** - * Retrieve current fault encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Load an XMLRPC fault from XML - * - * @param string $fault - * @return boolean Returns true if successfully loaded fault response, false - * if response was not a fault response - * @throws Zend_XmlRpc_Exception if no or faulty XML provided, or if fault - * response does not contain either code or message - */ - public function loadXml($fault) - { - if (!is_string($fault)) { - #require_once 'Zend/XmlRpc/Exception.php'; - throw new Zend_XmlRpc_Exception('Invalid XML provided to fault'); - } - - try { - $xml = @new SimpleXMLElement($fault); - } catch (Exception $e) { - // Not valid XML - #require_once 'Zend/XmlRpc/Exception.php'; - throw new Zend_XmlRpc_Exception('Failed to parse XML fault: ' . $e->getMessage(), 500, $e); - } - - // Check for fault - if (!$xml->fault) { - // Not a fault - return false; - } - - if (!$xml->fault->value->struct) { - // not a proper fault - #require_once 'Zend/XmlRpc/Exception.php'; - throw new Zend_XmlRpc_Exception('Invalid fault structure', 500); - } - - $structXml = $xml->fault->value->asXML(); - $struct = Zend_XmlRpc_Value::getXmlRpcValue($structXml, Zend_XmlRpc_Value::XML_STRING); - $struct = $struct->getValue(); - - if (isset($struct['faultCode'])) { - $code = $struct['faultCode']; - } - if (isset($struct['faultString'])) { - $message = $struct['faultString']; - } - - if (empty($code) && empty($message)) { - #require_once 'Zend/XmlRpc/Exception.php'; - throw new Zend_XmlRpc_Exception('Fault code and string required'); - } - - if (empty($code)) { - $code = '404'; - } - - if (empty($message)) { - if (isset($this->_internal[$code])) { - $message = $this->_internal[$code]; - } else { - $message = 'Unknown Error'; - } - } - - $this->setCode($code); - $this->setMessage($message); - - return true; - } - - /** - * Determine if an XML response is an XMLRPC fault - * - * @param string $xml - * @return boolean - */ - public static function isFault($xml) - { - $fault = new self(); - #require_once 'Zend/XmlRpc/Exception.php'; - try { - $isFault = $fault->loadXml($xml); - } catch (Zend_XmlRpc_Exception $e) { - $isFault = false; - } - - return $isFault; - } - - /** - * Serialize fault to XML - * - * @return string - */ - public function saveXml() - { - // Create fault value - $faultStruct = array( - 'faultCode' => $this->getCode(), - 'faultString' => $this->getMessage() - ); - $value = Zend_XmlRpc_Value::getXmlRpcValue($faultStruct); - - $generator = Zend_XmlRpc_Value::getGenerator(); - $generator->openElement('methodResponse') - ->openElement('fault'); - $value->generateXml(); - $generator->closeElement('fault') - ->closeElement('methodResponse'); - - return $generator->flush(); - } - - /** - * Return XML fault response - * - * @return string - */ - public function __toString() - { - return $this->saveXML(); - } -} diff --git a/lib/Zend/XmlRpc/Generator/DomDocument.php b/lib/Zend/XmlRpc/Generator/DomDocument.php deleted file mode 100644 index 99138427a3f..00000000000 --- a/lib/Zend/XmlRpc/Generator/DomDocument.php +++ /dev/null @@ -1,101 +0,0 @@ -_dom->createElement($name); - - $this->_currentElement = $this->_currentElement->appendChild($newElement); - } - - /** - * Write XML text data into the currently opened XML element - * - * @param string $text - */ - protected function _writeTextData($text) - { - $this->_currentElement->appendChild($this->_dom->createTextNode($text)); - } - - /** - * Close an previously opened XML element - * - * Resets $_currentElement to the next parent node in the hierarchy - * - * @param string $name - * @return void - */ - protected function _closeElement($name) - { - if (isset($this->_currentElement->parentNode)) { - $this->_currentElement = $this->_currentElement->parentNode; - } - } - - /** - * Save XML as a string - * - * @return string - */ - public function saveXml() - { - return $this->_dom->saveXml(); - } - - /** - * Initializes internal objects - * - * @return void - */ - protected function _init() - { - $this->_dom = new DOMDocument('1.0', $this->_encoding); - $this->_currentElement = $this->_dom; - } -} diff --git a/lib/Zend/XmlRpc/Generator/GeneratorAbstract.php b/lib/Zend/XmlRpc/Generator/GeneratorAbstract.php deleted file mode 100644 index 03afcd696f4..00000000000 --- a/lib/Zend/XmlRpc/Generator/GeneratorAbstract.php +++ /dev/null @@ -1,150 +0,0 @@ -_encoding = $encoding; - $this->_init(); - } - - /** - * Start XML element - * - * Method opens a new XML element with an element name and an optional value - * - * @param string $name XML tag name - * @param string $value Optional value of the XML tag - * @return Zend_XmlRpc_Generator_Abstract Fluent interface - */ - public function openElement($name, $value = null) - { - $this->_openElement($name); - if ($value !== null) { - $this->_writeTextData($value); - } - - return $this; - } - - /** - * End of an XML element - * - * Method marks the end of an XML element - * - * @param string $name XML tag name - * @return Zend_XmlRpc_Generator_Abstract Fluent interface - */ - public function closeElement($name) - { - $this->_closeElement($name); - - return $this; - } - - /** - * Return XML as a string - * - * @return string - */ - abstract public function saveXml(); - - /** - * Return encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Returns the XML as a string and flushes all internal buffers - * - * @return string - */ - public function flush() - { - $xml = $this->saveXml(); - $this->_init(); - return $xml; - } - - /** - * Returns XML without document declaration - * - * @return string - */ - public function __toString() - { - return $this->stripDeclaration($this->saveXml()); - } - - /** - * Removes XML declaration from a string - * - * @param string $xml - * @return string - */ - public function stripDeclaration($xml) - { - return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $xml); - } - - /** - * Start XML element - * - * @param string $name XML element name - */ - abstract protected function _openElement($name); - - /** - * Write XML text data into the currently opened XML element - * - * @param string $text - */ - abstract protected function _writeTextData($text); - - /** - * End XML element - * - * @param string $name - */ - abstract protected function _closeElement($name); -} diff --git a/lib/Zend/XmlRpc/Generator/XmlWriter.php b/lib/Zend/XmlRpc/Generator/XmlWriter.php deleted file mode 100644 index 62dc84fa331..00000000000 --- a/lib/Zend/XmlRpc/Generator/XmlWriter.php +++ /dev/null @@ -1,93 +0,0 @@ -_xmlWriter = new XMLWriter(); - $this->_xmlWriter->openMemory(); - $this->_xmlWriter->startDocument('1.0', $this->_encoding); - } - - - /** - * Open a new XML element - * - * @param string $name XML element name - * @return void - */ - protected function _openElement($name) - { - $this->_xmlWriter->startElement($name); - } - - /** - * Write XML text data into the currently opened XML element - * - * @param string $text XML text data - * @return void - */ - protected function _writeTextData($text) - { - $this->_xmlWriter->text($text); - } - - /** - * Close an previously opened XML element - * - * @param string $name - * @return void - */ - protected function _closeElement($name) - { - $this->_xmlWriter->endElement(); - - return $this; - } - - public function saveXml() - { - $xml = $this->_xmlWriter->flush(false); - return $xml; - } -} diff --git a/lib/Zend/XmlRpc/Request.php b/lib/Zend/XmlRpc/Request.php deleted file mode 100644 index b796025ab5a..00000000000 --- a/lib/Zend/XmlRpc/Request.php +++ /dev/null @@ -1,445 +0,0 @@ -setMethod($method); - } - - if ($params !== null) { - $this->setParams($params); - } - } - - - /** - * Set encoding to use in request - * - * @param string $encoding - * @return Zend_XmlRpc_Request - */ - public function setEncoding($encoding) - { - $this->_encoding = $encoding; - Zend_XmlRpc_Value::setEncoding($encoding); - return $this; - } - - /** - * Retrieve current request encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Set method to call - * - * @param string $method - * @return boolean Returns true on success, false if method name is invalid - */ - public function setMethod($method) - { - if (!is_string($method) || !preg_match('/^[a-z0-9_.:\/]+$/i', $method)) { - $this->_fault = new Zend_XmlRpc_Fault(634, 'Invalid method name ("' . $method . '")'); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - $this->_method = $method; - return true; - } - - /** - * Retrieve call method - * - * @return string - */ - public function getMethod() - { - return $this->_method; - } - - /** - * Add a parameter to the parameter stack - * - * Adds a parameter to the parameter stack, associating it with the type - * $type if provided - * - * @param mixed $value - * @param string $type Optional; type hinting - * @return void - */ - public function addParam($value, $type = null) - { - $this->_params[] = $value; - if (null === $type) { - // Detect type if not provided explicitly - if ($value instanceof Zend_XmlRpc_Value) { - $type = $value->getType(); - } else { - $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($value); - $type = $xmlRpcValue->getType(); - } - } - $this->_types[] = $type; - $this->_xmlRpcParams[] = array('value' => $value, 'type' => $type); - } - - /** - * Set the parameters array - * - * If called with a single, array value, that array is used to set the - * parameters stack. If called with multiple values or a single non-array - * value, the arguments are used to set the parameters stack. - * - * Best is to call with array of the format, in order to allow type hinting - * when creating the XMLRPC values for each parameter: - * - * $array = array( - * array( - * 'value' => $value, - * 'type' => $type - * )[, ... ] - * ); - * - * - * @access public - * @return void - */ - public function setParams() - { - $argc = func_num_args(); - $argv = func_get_args(); - if (0 == $argc) { - return; - } - - if ((1 == $argc) && is_array($argv[0])) { - $params = array(); - $types = array(); - $wellFormed = true; - foreach ($argv[0] as $arg) { - if (!is_array($arg) || !isset($arg['value'])) { - $wellFormed = false; - break; - } - $params[] = $arg['value']; - - if (!isset($arg['type'])) { - $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg['value']); - $arg['type'] = $xmlRpcValue->getType(); - } - $types[] = $arg['type']; - } - if ($wellFormed) { - $this->_xmlRpcParams = $argv[0]; - $this->_params = $params; - $this->_types = $types; - } else { - $this->_params = $argv[0]; - $this->_types = array(); - $xmlRpcParams = array(); - foreach ($argv[0] as $arg) { - if ($arg instanceof Zend_XmlRpc_Value) { - $type = $arg->getType(); - } else { - $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg); - $type = $xmlRpcValue->getType(); - } - $xmlRpcParams[] = array('value' => $arg, 'type' => $type); - $this->_types[] = $type; - } - $this->_xmlRpcParams = $xmlRpcParams; - } - return; - } - - $this->_params = $argv; - $this->_types = array(); - $xmlRpcParams = array(); - foreach ($argv as $arg) { - if ($arg instanceof Zend_XmlRpc_Value) { - $type = $arg->getType(); - } else { - $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg); - $type = $xmlRpcValue->getType(); - } - $xmlRpcParams[] = array('value' => $arg, 'type' => $type); - $this->_types[] = $type; - } - $this->_xmlRpcParams = $xmlRpcParams; - } - - /** - * Retrieve the array of parameters - * - * @return array - */ - public function getParams() - { - return $this->_params; - } - - /** - * Return parameter types - * - * @return array - */ - public function getTypes() - { - return $this->_types; - } - - /** - * Load XML and parse into request components - * - * @param string $request - * @return boolean True on success, false if an error occurred. - */ - public function loadXml($request) - { - if (!is_string($request)) { - $this->_fault = new Zend_XmlRpc_Fault(635); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - try { - $xml = Zend_Xml_Security::scan($request); - } catch (Zend_Xml_Exception $e) { - // Not valid XML - $this->_fault = new Zend_XmlRpc_Fault(631); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - // Check for method name - if (empty($xml->methodName)) { - // Missing method name - $this->_fault = new Zend_XmlRpc_Fault(632); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - $this->_method = (string) $xml->methodName; - - // Check for parameters - if (!empty($xml->params)) { - $types = array(); - $argv = array(); - foreach ($xml->params->children() as $param) { - if (!isset($param->value)) { - $this->_fault = new Zend_XmlRpc_Fault(633); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - try { - $param = Zend_XmlRpc_Value::getXmlRpcValue($param->value, Zend_XmlRpc_Value::XML_STRING); - $types[] = $param->getType(); - $argv[] = $param->getValue(); - } catch (Exception $e) { - $this->_fault = new Zend_XmlRpc_Fault(636); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - } - - $this->_types = $types; - $this->_params = $argv; - } - - $this->_xml = $request; - - return true; - } - - /** - * Does the current request contain errors and should it return a fault - * response? - * - * @return boolean - */ - public function isFault() - { - return $this->_fault instanceof Zend_XmlRpc_Fault; - } - - /** - * Retrieve the fault response, if any - * - * @return null|Zend_XmlRpc_Fault - */ - public function getFault() - { - return $this->_fault; - } - - /** - * Retrieve method parameters as XMLRPC values - * - * @return array - */ - protected function _getXmlRpcParams() - { - $params = array(); - if (is_array($this->_xmlRpcParams)) { - foreach ($this->_xmlRpcParams as $param) { - $value = $param['value']; - $type = isset($param['type']) ? $param['type'] : Zend_XmlRpc_Value::AUTO_DETECT_TYPE; - - if (!$value instanceof Zend_XmlRpc_Value) { - $value = Zend_XmlRpc_Value::getXmlRpcValue($value, $type); - } - $params[] = $value; - } - } - - return $params; - } - - /** - * Create XML request - * - * @return string - */ - public function saveXml() - { - $args = $this->_getXmlRpcParams(); - $method = $this->getMethod(); - - $generator = Zend_XmlRpc_Value::getGenerator(); - $generator->openElement('methodCall') - ->openElement('methodName', $method) - ->closeElement('methodName'); - - if (is_array($args) && count($args)) { - $generator->openElement('params'); - - foreach ($args as $arg) { - $generator->openElement('param'); - $arg->generateXml(); - $generator->closeElement('param'); - } - $generator->closeElement('params'); - } - $generator->closeElement('methodCall'); - - return $generator->flush(); - } - - /** - * Return XML request - * - * @return string - */ - public function __toString() - { - return $this->saveXML(); - } -} diff --git a/lib/Zend/XmlRpc/Request/Http.php b/lib/Zend/XmlRpc/Request/Http.php deleted file mode 100644 index a116bfd13cb..00000000000 --- a/lib/Zend/XmlRpc/Request/Http.php +++ /dev/null @@ -1,124 +0,0 @@ -_fault = new Zend_XmlRpc_Fault(630); - return; - } - - $this->_xml = $xml; - - $this->loadXml($xml); - } - - /** - * Retrieve the raw XML request - * - * @return string - */ - public function getRawRequest() - { - return $this->_xml; - } - - /** - * Get headers - * - * Gets all headers as key => value pairs and returns them. - * - * @return array - */ - public function getHeaders() - { - if (null === $this->_headers) { - $this->_headers = array(); - foreach ($_SERVER as $key => $value) { - if ('HTTP_' == substr($key, 0, 5)) { - $header = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5))))); - $this->_headers[$header] = $value; - } - } - } - - return $this->_headers; - } - - /** - * Retrieve the full HTTP request, including headers and XML - * - * @return string - */ - public function getFullRequest() - { - $request = ''; - foreach ($this->getHeaders() as $key => $value) { - $request .= $key . ': ' . $value . "\n"; - } - - $request .= $this->_xml; - - return $request; - } -} diff --git a/lib/Zend/XmlRpc/Request/Stdin.php b/lib/Zend/XmlRpc/Request/Stdin.php deleted file mode 100644 index 92e8e736cb8..00000000000 --- a/lib/Zend/XmlRpc/Request/Stdin.php +++ /dev/null @@ -1,84 +0,0 @@ -_fault = new Zend_XmlRpc_Server_Exception(630); - return; - } - - $xml = ''; - while (!feof($fh)) { - $xml .= fgets($fh); - } - fclose($fh); - - $this->_xml = $xml; - - $this->loadXml($xml); - } - - /** - * Retrieve the raw XML request - * - * @return string - */ - public function getRawRequest() - { - return $this->_xml; - } -} diff --git a/lib/Zend/XmlRpc/Response.php b/lib/Zend/XmlRpc/Response.php deleted file mode 100644 index 3cdffb7c158..00000000000 --- a/lib/Zend/XmlRpc/Response.php +++ /dev/null @@ -1,255 +0,0 @@ -setReturnValue($return, $type); - } - - /** - * Set encoding to use in response - * - * @param string $encoding - * @return Zend_XmlRpc_Response - */ - public function setEncoding($encoding) - { - $this->_encoding = $encoding; - Zend_XmlRpc_Value::setEncoding($encoding); - return $this; - } - - /** - * Retrieve current response encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Set the return value - * - * Sets the return value, with optional type hinting if provided. - * - * @param mixed $value - * @param string $type - * @return void - */ - public function setReturnValue($value, $type = null) - { - $this->_return = $value; - $this->_type = (string) $type; - } - - /** - * Retrieve the return value - * - * @return mixed - */ - public function getReturnValue() - { - return $this->_return; - } - - /** - * Retrieve the XMLRPC value for the return value - * - * @return Zend_XmlRpc_Value - */ - protected function _getXmlRpcReturn() - { - return Zend_XmlRpc_Value::getXmlRpcValue($this->_return); - } - - /** - * Is the response a fault response? - * - * @return boolean - */ - public function isFault() - { - return $this->_fault instanceof Zend_XmlRpc_Fault; - } - - /** - * Returns the fault, if any. - * - * @return null|Zend_XmlRpc_Fault - */ - public function getFault() - { - return $this->_fault; - } - - /** - * Load a response from an XML response - * - * Attempts to load a response from an XMLRPC response, autodetecting if it - * is a fault response. - * - * @param string $response - * @return boolean True if a valid XMLRPC response, false if a fault - * response or invalid input - */ - public function loadXml($response) - { - if (!is_string($response)) { - $this->_fault = new Zend_XmlRpc_Fault(650); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - try { - $xml = Zend_Xml_Security::scan($response); - } catch (Zend_Xml_Exception $e) { - // Not valid XML - $this->_fault = new Zend_XmlRpc_Fault(651); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - if (!empty($xml->fault)) { - // fault response - $this->_fault = new Zend_XmlRpc_Fault(); - $this->_fault->setEncoding($this->getEncoding()); - $this->_fault->loadXml($response); - return false; - } - - if (empty($xml->params)) { - // Invalid response - $this->_fault = new Zend_XmlRpc_Fault(652); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - try { - if (!isset($xml->params) || !isset($xml->params->param) || !isset($xml->params->param->value)) { - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Missing XML-RPC value in XML'); - } - $valueXml = $xml->params->param->value->asXML(); - $value = Zend_XmlRpc_Value::getXmlRpcValue($valueXml, Zend_XmlRpc_Value::XML_STRING); - } catch (Zend_XmlRpc_Value_Exception $e) { - $this->_fault = new Zend_XmlRpc_Fault(653); - $this->_fault->setEncoding($this->getEncoding()); - return false; - } - - $this->setReturnValue($value->getValue()); - return true; - } - - /** - * Return response as XML - * - * @return string - */ - public function saveXml() - { - $value = $this->_getXmlRpcReturn(); - $generator = Zend_XmlRpc_Value::getGenerator(); - $generator->openElement('methodResponse') - ->openElement('params') - ->openElement('param'); - $value->generateXml(); - $generator->closeElement('param') - ->closeElement('params') - ->closeElement('methodResponse'); - - return $generator->flush(); - } - - /** - * Return XML response - * - * @return string - */ - public function __toString() - { - return $this->saveXML(); - } -} diff --git a/lib/Zend/XmlRpc/Response/Http.php b/lib/Zend/XmlRpc/Response/Http.php deleted file mode 100644 index e4d8257cfe9..00000000000 --- a/lib/Zend/XmlRpc/Response/Http.php +++ /dev/null @@ -1,51 +0,0 @@ -getEncoding())); - } - - return parent::__toString(); - } -} diff --git a/lib/Zend/XmlRpc/Server.php b/lib/Zend/XmlRpc/Server.php deleted file mode 100644 index 1f79a0cc31d..00000000000 --- a/lib/Zend/XmlRpc/Server.php +++ /dev/null @@ -1,615 +0,0 @@ - - * #require_once 'Zend/XmlRpc/Server.php'; - * #require_once 'Zend/XmlRpc/Server/Cache.php'; - * #require_once 'Zend/XmlRpc/Server/Fault.php'; - * #require_once 'My/Exception.php'; - * #require_once 'My/Fault/Observer.php'; - * - * // Instantiate server - * $server = new Zend_XmlRpc_Server(); - * - * // Allow some exceptions to report as fault responses: - * Zend_XmlRpc_Server_Fault::attachFaultException('My_Exception'); - * Zend_XmlRpc_Server_Fault::attachObserver('My_Fault_Observer'); - * - * // Get or build dispatch table: - * if (!Zend_XmlRpc_Server_Cache::get($filename, $server)) { - * #require_once 'Some/Service/Class.php'; - * #require_once 'Another/Service/Class.php'; - * - * // Attach Some_Service_Class in 'some' namespace - * $server->setClass('Some_Service_Class', 'some'); - * - * // Attach Another_Service_Class in 'another' namespace - * $server->setClass('Another_Service_Class', 'another'); - * - * // Create dispatch table cache file - * Zend_XmlRpc_Server_Cache::save($filename, $server); - * } - * - * $response = $server->handle(); - * echo $response; - * - * - * @category Zend - * @package Zend_XmlRpc - * @subpackage Server - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -class Zend_XmlRpc_Server extends Zend_Server_Abstract -{ - /** - * Character encoding - * @var string - */ - protected $_encoding = 'UTF-8'; - - /** - * Request processed - * @var null|Zend_XmlRpc_Request - */ - protected $_request = null; - - /** - * Class to use for responses; defaults to {@link Zend_XmlRpc_Response_Http} - * @var string - */ - protected $_responseClass = 'Zend_XmlRpc_Response_Http'; - - /** - * Dispatch table of name => method pairs - * @var Zend_Server_Definition - */ - protected $_table; - - /** - * PHP types => XML-RPC types - * @var array - */ - protected $_typeMap = array( - 'i4' => 'i4', - 'int' => 'int', - 'integer' => 'int', - 'Zend_Crypt_Math_BigInteger' => 'i8', - 'i8' => 'i8', - 'ex:i8' => 'i8', - 'double' => 'double', - 'float' => 'double', - 'real' => 'double', - 'boolean' => 'boolean', - 'bool' => 'boolean', - 'true' => 'boolean', - 'false' => 'boolean', - 'string' => 'string', - 'str' => 'string', - 'base64' => 'base64', - 'dateTime.iso8601' => 'dateTime.iso8601', - 'date' => 'dateTime.iso8601', - 'time' => 'dateTime.iso8601', - 'time' => 'dateTime.iso8601', - 'Zend_Date' => 'dateTime.iso8601', - 'DateTime' => 'dateTime.iso8601', - 'array' => 'array', - 'struct' => 'struct', - 'null' => 'nil', - 'nil' => 'nil', - 'ex:nil' => 'nil', - 'void' => 'void', - 'mixed' => 'struct', - ); - - /** - * Send arguments to all methods or just constructor? - * - * @var bool - */ - protected $_sendArgumentsToAllMethods = true; - - /** - * Constructor - * - * Creates system.* methods. - * - * @return void - */ - public function __construct() - { - $this->_table = new Zend_Server_Definition(); - $this->_registerSystemMethods(); - } - - /** - * Proxy calls to system object - * - * @param string $method - * @param array $params - * @return mixed - * @throws Zend_XmlRpc_Server_Exception - */ - public function __call($method, $params) - { - $system = $this->getSystem(); - if (!method_exists($system, $method)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Unknown instance method called on server: ' . $method); - } - return call_user_func_array(array($system, $method), $params); - } - - /** - * Attach a callback as an XMLRPC method - * - * Attaches a callback as an XMLRPC method, prefixing the XMLRPC method name - * with $namespace, if provided. Reflection is done on the callback's - * docblock to create the methodHelp for the XMLRPC method. - * - * Additional arguments to pass to the function at dispatch may be passed; - * any arguments following the namespace will be aggregated and passed at - * dispatch time. - * - * @param string|array $function Valid callback - * @param string $namespace Optional namespace prefix - * @return void - * @throws Zend_XmlRpc_Server_Exception - */ - public function addFunction($function, $namespace = '') - { - if (!is_string($function) && !is_array($function)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); - } - - $argv = null; - if (2 < func_num_args()) { - $argv = func_get_args(); - $argv = array_slice($argv, 2); - } - - $function = (array) $function; - foreach ($function as $func) { - if (!is_string($func) || !function_exists($func)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); - } - $reflection = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace); - $this->_buildSignature($reflection); - } - } - - /** - * Attach class methods as XMLRPC method handlers - * - * $class may be either a class name or an object. Reflection is done on the - * class or object to determine the available public methods, and each is - * attached to the server as an available method; if a $namespace has been - * provided, that namespace is used to prefix the XMLRPC method names. - * - * Any additional arguments beyond $namespace will be passed to a method at - * invocation. - * - * @param string|object $class - * @param string $namespace Optional - * @param mixed $argv Optional arguments to pass to methods - * @return void - * @throws Zend_XmlRpc_Server_Exception on invalid input - */ - public function setClass($class, $namespace = '', $argv = null) - { - if (is_string($class) && !class_exists($class)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Invalid method class', 610); - } - - $args = null; - if (2 < func_num_args()) { - $args = func_get_args(); - $args = array_slice($args, 2); - } - - $dispatchable = Zend_Server_Reflection::reflectClass($class, $args, $namespace); - foreach ($dispatchable->getMethods() as $reflection) { - $this->_buildSignature($reflection, $class); - } - } - - /** - * Raise an xmlrpc server fault - * - * @param string|Exception $fault - * @param int $code - * @return Zend_XmlRpc_Server_Fault - */ - public function fault($fault = null, $code = 404) - { - if (!$fault instanceof Exception) { - $fault = (string) $fault; - if (empty($fault)) { - $fault = 'Unknown Error'; - } - #require_once 'Zend/XmlRpc/Server/Exception.php'; - $fault = new Zend_XmlRpc_Server_Exception($fault, $code); - } - - return Zend_XmlRpc_Server_Fault::getInstance($fault); - } - - /** - * Handle an xmlrpc call - * - * @param Zend_XmlRpc_Request $request Optional - * @return Zend_XmlRpc_Response|Zend_XmlRpc_Fault - */ - public function handle($request = false) - { - // Get request - if ((!$request || !$request instanceof Zend_XmlRpc_Request) - && (null === ($request = $this->getRequest())) - ) { - #require_once 'Zend/XmlRpc/Request/Http.php'; - $request = new Zend_XmlRpc_Request_Http(); - $request->setEncoding($this->getEncoding()); - } - - $this->setRequest($request); - - if ($request->isFault()) { - $response = $request->getFault(); - } else { - try { - $response = $this->_handle($request); - } catch (Exception $e) { - $response = $this->fault($e); - } - } - - // Set output encoding - $response->setEncoding($this->getEncoding()); - - return $response; - } - - /** - * Load methods as returned from {@link getFunctions} - * - * Typically, you will not use this method; it will be called using the - * results pulled from {@link Zend_XmlRpc_Server_Cache::get()}. - * - * @param array|Zend_Server_Definition $definition - * @return void - * @throws Zend_XmlRpc_Server_Exception on invalid input - */ - public function loadFunctions($definition) - { - if (!is_array($definition) && (!$definition instanceof Zend_Server_Definition)) { - if (is_object($definition)) { - $type = get_class($definition); - } else { - $type = gettype($definition); - } - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Unable to load server definition; must be an array or Zend_Server_Definition, received ' . $type, 612); - } - - $this->_table->clearMethods(); - $this->_registerSystemMethods(); - - if ($definition instanceof Zend_Server_Definition) { - $definition = $definition->getMethods(); - } - - foreach ($definition as $key => $method) { - if ('system.' == substr($key, 0, 7)) { - continue; - } - $this->_table->addMethod($method, $key); - } - } - - /** - * Set encoding - * - * @param string $encoding - * @return Zend_XmlRpc_Server - */ - public function setEncoding($encoding) - { - $this->_encoding = $encoding; - Zend_XmlRpc_Value::setEncoding($encoding); - return $this; - } - - /** - * Retrieve current encoding - * - * @return string - */ - public function getEncoding() - { - return $this->_encoding; - } - - /** - * Do nothing; persistence is handled via {@link Zend_XmlRpc_Server_Cache} - * - * @param mixed $mode - * @return void - */ - public function setPersistence($mode) - { - } - - /** - * Set the request object - * - * @param string|Zend_XmlRpc_Request $request - * @return Zend_XmlRpc_Server - * @throws Zend_XmlRpc_Server_Exception on invalid request class or object - */ - public function setRequest($request) - { - if (is_string($request) && class_exists($request)) { - $request = new $request(); - if (!$request instanceof Zend_XmlRpc_Request) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Invalid request class'); - } - $request->setEncoding($this->getEncoding()); - } elseif (!$request instanceof Zend_XmlRpc_Request) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Invalid request object'); - } - - $this->_request = $request; - return $this; - } - - /** - * Return currently registered request object - * - * @return null|Zend_XmlRpc_Request - */ - public function getRequest() - { - return $this->_request; - } - - /** - * Set the class to use for the response - * - * @param string $class - * @return boolean True if class was set, false if not - */ - public function setResponseClass($class) - { - if (!class_exists($class) or - ($c = new ReflectionClass($class) and !$c->isSubclassOf('Zend_XmlRpc_Response'))) { - - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Invalid response class'); - } - $this->_responseClass = $class; - return true; - } - - /** - * Retrieve current response class - * - * @return string - */ - public function getResponseClass() - { - return $this->_responseClass; - } - - /** - * Retrieve dispatch table - * - * @return array - */ - public function getDispatchTable() - { - return $this->_table; - } - - /** - * Returns a list of registered methods - * - * Returns an array of dispatchables (Zend_Server_Reflection_Function, - * _Method, and _Class items). - * - * @return array - */ - public function getFunctions() - { - return $this->_table->toArray(); - } - - /** - * Retrieve system object - * - * @return Zend_XmlRpc_Server_System - */ - public function getSystem() - { - return $this->_system; - } - - /** - * Send arguments to all methods? - * - * If setClass() is used to add classes to the server, this flag defined - * how to handle arguments. If set to true, all methods including constructor - * will receive the arguments. If set to false, only constructor will receive the - * arguments - */ - public function sendArgumentsToAllMethods($flag = null) - { - if ($flag === null) { - return $this->_sendArgumentsToAllMethods; - } - - $this->_sendArgumentsToAllMethods = (bool)$flag; - return $this; - } - - /** - * Map PHP type to XML-RPC type - * - * @param string $type - * @return string - */ - protected function _fixType($type) - { - if (isset($this->_typeMap[$type])) { - return $this->_typeMap[$type]; - } - return 'void'; - } - - /** - * Handle an xmlrpc call (actual work) - * - * @param Zend_XmlRpc_Request $request - * @return Zend_XmlRpc_Response - * @throws Zend_XmlRpcServer_Exception|Exception - * Zend_XmlRpcServer_Exceptions are thrown for internal errors; otherwise, - * any other exception may be thrown by the callback - */ - protected function _handle(Zend_XmlRpc_Request $request) - { - $method = $request->getMethod(); - - // Check for valid method - if (!$this->_table->hasMethod($method)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 620); - } - - $info = $this->_table->getMethod($method); - $params = $request->getParams(); - $argv = $info->getInvokeArguments(); - if (0 < count($argv) and $this->sendArgumentsToAllMethods()) { - $params = array_merge($params, $argv); - } - - // Check calling parameters against signatures - $matched = false; - $sigCalled = $request->getTypes(); - - $sigLength = count($sigCalled); - $paramsLen = count($params); - if ($sigLength < $paramsLen) { - for ($i = $sigLength; $i < $paramsLen; ++$i) { - $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($params[$i]); - $sigCalled[] = $xmlRpcValue->getType(); - } - } - - $signatures = $info->getPrototypes(); - foreach ($signatures as $signature) { - $sigParams = $signature->getParameters(); - if ($sigCalled === $sigParams) { - $matched = true; - break; - } - } - if (!$matched) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Calling parameters do not match signature', 623); - } - - $return = $this->_dispatch($info, $params); - $responseClass = $this->getResponseClass(); - return new $responseClass($return); - } - - /** - * Register system methods with the server - * - * @return void - */ - protected function _registerSystemMethods() - { - $system = new Zend_XmlRpc_Server_System($this); - $this->_system = $system; - $this->setClass($system, 'system'); - } -} diff --git a/lib/Zend/XmlRpc/Server/Cache.php b/lib/Zend/XmlRpc/Server/Cache.php deleted file mode 100644 index c77178d6fbe..00000000000 --- a/lib/Zend/XmlRpc/Server/Cache.php +++ /dev/null @@ -1,46 +0,0 @@ - true); - - /** - * @var array Array of fault observers - */ - protected static $_observers = array(); - - /** - * Constructor - * - * @param Exception $e - * @return Zend_XmlRpc_Server_Fault - */ - public function __construct(Exception $e) - { - $this->_exception = $e; - $code = 404; - $message = 'Unknown error'; - $exceptionClass = get_class($e); - - foreach (array_keys(self::$_faultExceptionClasses) as $class) { - if ($e instanceof $class) { - $code = $e->getCode(); - $message = $e->getMessage(); - break; - } - } - - parent::__construct($code, $message); - - // Notify exception observers, if present - if (!empty(self::$_observers)) { - foreach (array_keys(self::$_observers) as $observer) { - call_user_func(array($observer, 'observe'), $this); - } - } - } - - /** - * Return Zend_XmlRpc_Server_Fault instance - * - * @param Exception $e - * @return Zend_XmlRpc_Server_Fault - */ - public static function getInstance(Exception $e) - { - return new self($e); - } - - /** - * Attach valid exceptions that can be used to define xmlrpc faults - * - * @param string|array $classes Class name or array of class names - * @return void - */ - public static function attachFaultException($classes) - { - if (!is_array($classes)) { - $classes = (array) $classes; - } - - foreach ($classes as $class) { - if (is_string($class) && class_exists($class)) { - self::$_faultExceptionClasses[$class] = true; - } - } - } - - /** - * Detach fault exception classes - * - * @param string|array $classes Class name or array of class names - * @return void - */ - public static function detachFaultException($classes) - { - if (!is_array($classes)) { - $classes = (array) $classes; - } - - foreach ($classes as $class) { - if (is_string($class) && isset(self::$_faultExceptionClasses[$class])) { - unset(self::$_faultExceptionClasses[$class]); - } - } - } - - /** - * Attach an observer class - * - * Allows observation of xmlrpc server faults, thus allowing logging or mail - * notification of fault responses on the xmlrpc server. - * - * Expects a valid class name; that class must have a public static method - * 'observe' that accepts an exception as its sole argument. - * - * @param string $class - * @return boolean - */ - public static function attachObserver($class) - { - if (!is_string($class) - || !class_exists($class) - || !is_callable(array($class, 'observe'))) - { - return false; - } - - if (!isset(self::$_observers[$class])) { - self::$_observers[$class] = true; - } - - return true; - } - - /** - * Detach an observer - * - * @param string $class - * @return boolean - */ - public static function detachObserver($class) - { - if (!isset(self::$_observers[$class])) { - return false; - } - - unset(self::$_observers[$class]); - return true; - } - - /** - * Retrieve the exception - * - * @access public - * @return Exception - */ - public function getException() - { - return $this->_exception; - } -} diff --git a/lib/Zend/XmlRpc/Server/System.php b/lib/Zend/XmlRpc/Server/System.php deleted file mode 100644 index 21beb4c9134..00000000000 --- a/lib/Zend/XmlRpc/Server/System.php +++ /dev/null @@ -1,162 +0,0 @@ -_server = $server; - } - - /** - * List all available XMLRPC methods - * - * Returns an array of methods. - * - * @return array - */ - public function listMethods() - { - $table = $this->_server->getDispatchTable()->getMethods(); - return array_keys($table); - } - - /** - * Display help message for an XMLRPC method - * - * @param string $method - * @return string - */ - public function methodHelp($method) - { - $table = $this->_server->getDispatchTable(); - if (!$table->hasMethod($method)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 640); - } - - return $table->getMethod($method)->getMethodHelp(); - } - - /** - * Return a method signature - * - * @param string $method - * @return array - */ - public function methodSignature($method) - { - $table = $this->_server->getDispatchTable(); - if (!$table->hasMethod($method)) { - #require_once 'Zend/XmlRpc/Server/Exception.php'; - throw new Zend_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 640); - } - $method = $table->getMethod($method)->toArray(); - return $method['prototypes']; - } - - /** - * Multicall - boxcar feature of XML-RPC for calling multiple methods - * in a single request. - * - * Expects a an array of structs representing method calls, each element - * having the keys: - * - methodName - * - params - * - * Returns an array of responses, one for each method called, with the value - * returned by the method. If an error occurs for a given method, returns a - * struct with a fault response. - * - * @see http://www.xmlrpc.com/discuss/msgReader$1208 - * @param array $methods - * @return array - */ - public function multicall($methods) - { - $responses = array(); - foreach ($methods as $method) { - $fault = false; - if (!is_array($method)) { - $fault = $this->_server->fault('system.multicall expects each method to be a struct', 601); - } elseif (!isset($method['methodName'])) { - $fault = $this->_server->fault('Missing methodName: ' . var_export($methods, 1), 602); - } elseif (!isset($method['params'])) { - $fault = $this->_server->fault('Missing params', 603); - } elseif (!is_array($method['params'])) { - $fault = $this->_server->fault('Params must be an array', 604); - } else { - if ('system.multicall' == $method['methodName']) { - // don't allow recursive calls to multicall - $fault = $this->_server->fault('Recursive system.multicall forbidden', 605); - } - } - - if (!$fault) { - try { - $request = new Zend_XmlRpc_Request(); - $request->setMethod($method['methodName']); - $request->setParams($method['params']); - $response = $this->_server->handle($request); - if ($response instanceof Zend_XmlRpc_Fault - || $response->isFault() - ) { - $fault = $response; - } else { - $responses[] = $response->getReturnValue(); - } - } catch (Exception $e) { - $fault = $this->_server->fault($e); - } - } - - if ($fault) { - $responses[] = array( - 'faultCode' => $fault->getCode(), - 'faultString' => $fault->getMessage() - ); - } - } - - return $responses; - } -} diff --git a/lib/Zend/XmlRpc/Value.php b/lib/Zend/XmlRpc/Value.php deleted file mode 100644 index 88226994079..00000000000 --- a/lib/Zend/XmlRpc/Value.php +++ /dev/null @@ -1,527 +0,0 @@ -_type; - } - - /** - * Get XML generator instance - * - * @return Zend_XmlRpc_Generator_GeneratorAbstract - */ - public static function getGenerator() - { - if (!self::$_generator) { - if (extension_loaded('xmlwriter')) { - #require_once 'Zend/XmlRpc/Generator/XmlWriter.php'; - self::$_generator = new Zend_XmlRpc_Generator_XmlWriter(); - } else { - #require_once 'Zend/XmlRpc/Generator/DomDocument.php'; - self::$_generator = new Zend_XmlRpc_Generator_DomDocument(); - } - } - - return self::$_generator; - } - - /** - * Sets XML generator instance - * - * @param Zend_XmlRpc_Generator_GeneratorAbstract $generator - * @return void - */ - public static function setGenerator(Zend_XmlRpc_Generator_GeneratorAbstract $generator) - { - self::$_generator = $generator; - } - - /** - * Changes the encoding of the generator - * - * @param string $encoding - * @return void - */ - public static function setEncoding($encoding) - { - $generator = self::getGenerator(); - $newGenerator = new $generator($encoding); - self::setGenerator($newGenerator); - } - - /** - * Return the value of this object, convert the XML-RPC native value into a PHP variable - * - * @return mixed - */ - abstract public function getValue(); - - - /** - * Return the XML code that represent a native MXL-RPC value - * - * @return string - */ - public function saveXml() - { - if (!$this->_xml) { - $this->generateXml(); - $this->_xml = (string) $this->getGenerator(); - } - return $this->_xml; - } - - /** - * Generate XML code that represent a native XML/RPC value - * - * @return void - */ - public function generateXml() - { - $this->_generateXml(); - } - - /** - * Creates a Zend_XmlRpc_Value* object, representing a native XML-RPC value - * A XmlRpcValue object can be created in 3 ways: - * 1. Autodetecting the native type out of a PHP variable - * (if $type is not set or equal to Zend_XmlRpc_Value::AUTO_DETECT_TYPE) - * 2. By specifing the native type ($type is one of the Zend_XmlRpc_Value::XMLRPC_TYPE_* constants) - * 3. From a XML string ($type is set to Zend_XmlRpc_Value::XML_STRING) - * - * By default the value type is autodetected according to it's PHP type - * - * @param mixed $value - * @param Zend_XmlRpc_Value::constant $type - * - * @return Zend_XmlRpc_Value - * @static - */ - public static function getXmlRpcValue($value, $type = self::AUTO_DETECT_TYPE) - { - switch ($type) { - case self::AUTO_DETECT_TYPE: - // Auto detect the XML-RPC native type from the PHP type of $value - return self::_phpVarToNativeXmlRpc($value); - - case self::XML_STRING: - // Parse the XML string given in $value and get the XML-RPC value in it - return self::_xmlStringToNativeXmlRpc($value); - - case self::XMLRPC_TYPE_I4: - // fall through to the next case - case self::XMLRPC_TYPE_INTEGER: - #require_once 'Zend/XmlRpc/Value/Integer.php'; - return new Zend_XmlRpc_Value_Integer($value); - - case self::XMLRPC_TYPE_I8: - // fall through to the next case - case self::XMLRPC_TYPE_APACHEI8: - #require_once 'Zend/XmlRpc/Value/BigInteger.php'; - return new Zend_XmlRpc_Value_BigInteger($value); - - case self::XMLRPC_TYPE_DOUBLE: - #require_once 'Zend/XmlRpc/Value/Double.php'; - return new Zend_XmlRpc_Value_Double($value); - - case self::XMLRPC_TYPE_BOOLEAN: - #require_once 'Zend/XmlRpc/Value/Boolean.php'; - return new Zend_XmlRpc_Value_Boolean($value); - - case self::XMLRPC_TYPE_STRING: - #require_once 'Zend/XmlRpc/Value/String.php'; - return new Zend_XmlRpc_Value_String($value); - - case self::XMLRPC_TYPE_BASE64: - #require_once 'Zend/XmlRpc/Value/Base64.php'; - return new Zend_XmlRpc_Value_Base64($value); - - case self::XMLRPC_TYPE_NIL: - // fall through to the next case - case self::XMLRPC_TYPE_APACHENIL: - #require_once 'Zend/XmlRpc/Value/Nil.php'; - return new Zend_XmlRpc_Value_Nil(); - - case self::XMLRPC_TYPE_DATETIME: - #require_once 'Zend/XmlRpc/Value/DateTime.php'; - return new Zend_XmlRpc_Value_DateTime($value); - - case self::XMLRPC_TYPE_ARRAY: - #require_once 'Zend/XmlRpc/Value/Array.php'; - return new Zend_XmlRpc_Value_Array($value); - - case self::XMLRPC_TYPE_STRUCT: - #require_once 'Zend/XmlRpc/Value/Struct.php'; - return new Zend_XmlRpc_Value_Struct($value); - - default: - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Given type is not a '. __CLASS__ .' constant'); - } - } - - /** - * Get XML-RPC type for a PHP native variable - * - * @static - * @param mixed $value - * @return string - */ - public static function getXmlRpcTypeByValue($value) - { - if (is_object($value)) { - if ($value instanceof Zend_XmlRpc_Value) { - return $value->getType(); - } elseif (($value instanceof Zend_Date) || ($value instanceof DateTime)) { - return self::XMLRPC_TYPE_DATETIME; - } - return self::getXmlRpcTypeByValue(get_object_vars($value)); - } elseif (is_array($value)) { - if (!empty($value) && is_array($value) && (array_keys($value) !== range(0, count($value) - 1))) { - return self::XMLRPC_TYPE_STRUCT; - } - return self::XMLRPC_TYPE_ARRAY; - } elseif (is_int($value)) { - return ($value > PHP_INT_MAX) ? self::XMLRPC_TYPE_I8 : self::XMLRPC_TYPE_INTEGER; - } elseif (is_double($value)) { - return self::XMLRPC_TYPE_DOUBLE; - } elseif (is_bool($value)) { - return self::XMLRPC_TYPE_BOOLEAN; - } elseif (is_null($value)) { - return self::XMLRPC_TYPE_NIL; - } elseif (is_string($value)) { - return self::XMLRPC_TYPE_STRING; - } - throw new Zend_XmlRpc_Value_Exception(sprintf( - 'No matching XMLRPC type found for php type %s.', - gettype($value) - )); - } - - /** - * Transform a PHP native variable into a XML-RPC native value - * - * @param mixed $value The PHP variable for convertion - * - * @return Zend_XmlRpc_Value - * @static - */ - protected static function _phpVarToNativeXmlRpc($value) - { - // @see http://framework.zend.com/issues/browse/ZF-8623 - if (is_object($value)) { - if ($value instanceof Zend_XmlRpc_Value) { - return $value; - } - if ($value instanceof Zend_Crypt_Math_BigInteger) { - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception( - 'Using Zend_Crypt_Math_BigInteger to get an ' . - 'instance of Zend_XmlRpc_Value_BigInteger is not ' . - 'available anymore.' - ); - } - } - - switch (self::getXmlRpcTypeByValue($value)) - { - case self::XMLRPC_TYPE_DATETIME: - #require_once 'Zend/XmlRpc/Value/DateTime.php'; - return new Zend_XmlRpc_Value_DateTime($value); - - case self::XMLRPC_TYPE_ARRAY: - #require_once 'Zend/XmlRpc/Value/Array.php'; - return new Zend_XmlRpc_Value_Array($value); - - case self::XMLRPC_TYPE_STRUCT: - #require_once 'Zend/XmlRpc/Value/Struct.php'; - return new Zend_XmlRpc_Value_Struct($value); - - case self::XMLRPC_TYPE_INTEGER: - #require_once 'Zend/XmlRpc/Value/Integer.php'; - return new Zend_XmlRpc_Value_Integer($value); - - case self::XMLRPC_TYPE_DOUBLE: - #require_once 'Zend/XmlRpc/Value/Double.php'; - return new Zend_XmlRpc_Value_Double($value); - - case self::XMLRPC_TYPE_BOOLEAN: - #require_once 'Zend/XmlRpc/Value/Boolean.php'; - return new Zend_XmlRpc_Value_Boolean($value); - - case self::XMLRPC_TYPE_NIL: - #require_once 'Zend/XmlRpc/Value/Nil.php'; - return new Zend_XmlRpc_Value_Nil; - - case self::XMLRPC_TYPE_STRING: - // Fall through to the next case - default: - // If type isn't identified (or identified as string), it treated as string - #require_once 'Zend/XmlRpc/Value/String.php'; - return new Zend_XmlRpc_Value_String($value); - } - } - - - /** - * Transform an XML string into a XML-RPC native value - * - * @param string|SimpleXMLElement $xml A SimpleXMLElement object represent the XML string - * It can be also a valid XML string for convertion - * - * @return Zend_XmlRpc_Value - * @static - */ - protected static function _xmlStringToNativeXmlRpc($xml) - { - self::_createSimpleXMLElement($xml); - - self::_extractTypeAndValue($xml, $type, $value); - - switch ($type) { - // All valid and known XML-RPC native values - case self::XMLRPC_TYPE_I4: - // Fall through to the next case - case self::XMLRPC_TYPE_INTEGER: - #require_once 'Zend/XmlRpc/Value/Integer.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Integer($value); - break; - case self::XMLRPC_TYPE_APACHEI8: - // Fall through to the next case - case self::XMLRPC_TYPE_I8: - #require_once 'Zend/XmlRpc/Value/BigInteger.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_BigInteger($value); - break; - case self::XMLRPC_TYPE_DOUBLE: - #require_once 'Zend/XmlRpc/Value/Double.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Double($value); - break; - case self::XMLRPC_TYPE_BOOLEAN: - #require_once 'Zend/XmlRpc/Value/Boolean.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Boolean($value); - break; - case self::XMLRPC_TYPE_STRING: - #require_once 'Zend/XmlRpc/Value/String.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_String($value); - break; - case self::XMLRPC_TYPE_DATETIME: // The value should already be in a iso8601 format - #require_once 'Zend/XmlRpc/Value/DateTime.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_DateTime($value); - break; - case self::XMLRPC_TYPE_BASE64: // The value should already be base64 encoded - #require_once 'Zend/XmlRpc/Value/Base64.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Base64($value, true); - break; - case self::XMLRPC_TYPE_NIL: - // Fall through to the next case - case self::XMLRPC_TYPE_APACHENIL: - // The value should always be NULL - #require_once 'Zend/XmlRpc/Value/Nil.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Nil(); - break; - case self::XMLRPC_TYPE_ARRAY: - // PHP 5.2.4 introduced a regression in how empty($xml->value) - // returns; need to look for the item specifically - $data = null; - foreach ($value->children() as $key => $value) { - if ('data' == $key) { - $data = $value; - break; - } - } - - if (null === $data) { - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Invalid XML for XML-RPC native '. self::XMLRPC_TYPE_ARRAY .' type: ARRAY tag must contain DATA tag'); - } - $values = array(); - // Parse all the elements of the array from the XML string - // (simple xml element) to Zend_XmlRpc_Value objects - foreach ($data->value as $element) { - $values[] = self::_xmlStringToNativeXmlRpc($element); - } - #require_once 'Zend/XmlRpc/Value/Array.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Array($values); - break; - case self::XMLRPC_TYPE_STRUCT: - $values = array(); - // Parse all the memebers of the struct from the XML string - // (simple xml element) to Zend_XmlRpc_Value objects - foreach ($value->member as $member) { - // @todo? If a member doesn't have a tag, we don't add it to the struct - // Maybe we want to throw an exception here ? - if (!isset($member->value) || !isset($member->name)) { - continue; - //throw new Zend_XmlRpc_Value_Exception('Member of the '. self::XMLRPC_TYPE_STRUCT .' XML-RPC native type must contain a VALUE tag'); - } - $values[(string)$member->name] = self::_xmlStringToNativeXmlRpc($member->value); - } - #require_once 'Zend/XmlRpc/Value/Struct.php'; - $xmlrpcValue = new Zend_XmlRpc_Value_Struct($values); - break; - default: - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Value type \''. $type .'\' parsed from the XML string is not a known XML-RPC native type'); - break; - } - $xmlrpcValue->_setXML($xml->asXML()); - - return $xmlrpcValue; - } - - protected static function _createSimpleXMLElement(&$xml) - { - if ($xml instanceof SimpleXMLElement) { - return; - } - - try { - $xml = new SimpleXMLElement($xml); - } catch (Exception $e) { - // The given string is not a valid XML - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Failed to create XML-RPC value from XML string: ' . $e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Extract XML/RPC type and value from SimpleXMLElement object - * - * @param SimpleXMLElement $xml - * @param string &$type Type bind variable - * @param string &$value Value bind variable - * @return void - */ - protected static function _extractTypeAndValue(SimpleXMLElement $xml, &$type, &$value) - { - $value = reset($xml); - $type = key($xml); - - if (!$type and $value === null) { - $namespaces = array('ex' => 'http://ws.apache.org/xmlrpc/namespaces/extensions'); - foreach ($namespaces as $namespaceName => $namespaceUri) { - $namespaceXml = $xml->children($namespaceUri); - $value = reset($namespaceXml); - $type = key($namespaceXml); - if ($type !== null) { - $type = $namespaceName . ':' . $type; - break; - } - } - } - - //if there is a child element, try to parse type for it - if (!$type && $value instanceof SimpleXMLElement) { - self::_extractTypeAndValue($value->children(), $type, $value); - } - - // If no type was specified, the default is string - if (!$type) { - $type = self::XMLRPC_TYPE_STRING; - if (preg_match('#^.*$#', $xml->asXML())) { - $value = str_replace(array('', ''), '', $xml->asXML()); - } - } - } - - /** - * @param string $xml - * @return void - */ - protected function _setXML($xml) - { - $this->_xml = $this->getGenerator()->stripDeclaration($xml); - } -} diff --git a/lib/Zend/XmlRpc/Value/Array.php b/lib/Zend/XmlRpc/Value/Array.php deleted file mode 100644 index 828682a1ebf..00000000000 --- a/lib/Zend/XmlRpc/Value/Array.php +++ /dev/null @@ -1,73 +0,0 @@ -_type = self::XMLRPC_TYPE_ARRAY; - parent::__construct($value); - } - - - /** - * Generate the XML code that represent an array native MXL-RPC value - * - * @return void - */ - protected function _generateXml() - { - $generator = $this->getGenerator(); - $generator->openElement('value') - ->openElement('array') - ->openElement('data'); - - if (is_array($this->_value)) { - foreach ($this->_value as $val) { - $val->generateXml(); - } - } - $generator->closeElement('data') - ->closeElement('array') - ->closeElement('value'); - } -} - diff --git a/lib/Zend/XmlRpc/Value/Base64.php b/lib/Zend/XmlRpc/Value/Base64.php deleted file mode 100644 index 92bc9ce069d..00000000000 --- a/lib/Zend/XmlRpc/Value/Base64.php +++ /dev/null @@ -1,68 +0,0 @@ -_type = self::XMLRPC_TYPE_BASE64; - - $value = (string)$value; // Make sure this value is string - if (!$alreadyEncoded) { - $value = base64_encode($value); // We encode it in base64 - } - $this->_value = $value; - } - - /** - * Return the value of this object, convert the XML-RPC native base64 value into a PHP string - * We return this value decoded (a normal string) - * - * @return string - */ - public function getValue() - { - return base64_decode($this->_value); - } -} diff --git a/lib/Zend/XmlRpc/Value/BigInteger.php b/lib/Zend/XmlRpc/Value/BigInteger.php deleted file mode 100644 index 925410a7918..00000000000 --- a/lib/Zend/XmlRpc/Value/BigInteger.php +++ /dev/null @@ -1,58 +0,0 @@ -_value = $integer->init($value); - $this->_type = self::XMLRPC_TYPE_I8; - } - - /** - * Return bigint value - * - * @return string - */ - public function getValue() - { - return $this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Boolean.php b/lib/Zend/XmlRpc/Value/Boolean.php deleted file mode 100644 index b4e8366b89f..00000000000 --- a/lib/Zend/XmlRpc/Value/Boolean.php +++ /dev/null @@ -1,63 +0,0 @@ -_type = self::XMLRPC_TYPE_BOOLEAN; - // Make sure the value is boolean and then convert it into a integer - // The double convertion is because a bug in the ZendOptimizer in PHP version 5.0.4 - $this->_value = (int)(bool)$value; - } - - /** - * Return the value of this object, convert the XML-RPC native boolean value into a PHP boolean - * - * @return bool - */ - public function getValue() - { - return (bool)$this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Collection.php b/lib/Zend/XmlRpc/Value/Collection.php deleted file mode 100644 index 0930ac14aef..00000000000 --- a/lib/Zend/XmlRpc/Value/Collection.php +++ /dev/null @@ -1,73 +0,0 @@ - $value) { - // If the elements of the given array are not Zend_XmlRpc_Value objects, - // we need to convert them as such (using auto-detection from PHP value) - if (!$value instanceof parent) { - $value = self::getXmlRpcValue($value, self::AUTO_DETECT_TYPE); - } - $this->_value[$key] = $value; - } - } - - - /** - * Return the value of this object, convert the XML-RPC native collection values into a PHP array - * - * @return arary - */ - public function getValue() - { - $values = (array)$this->_value; - foreach ($values as $key => $value) { - /* @var $value Zend_XmlRpc_Value */ - $values[$key] = $value->getValue(); - } - return $values; - } -} diff --git a/lib/Zend/XmlRpc/Value/DateTime.php b/lib/Zend/XmlRpc/Value/DateTime.php deleted file mode 100644 index 21403c49279..00000000000 --- a/lib/Zend/XmlRpc/Value/DateTime.php +++ /dev/null @@ -1,91 +0,0 @@ -_type = self::XMLRPC_TYPE_DATETIME; - - if ($value instanceof Zend_Date) { - $this->_value = $value->toString($this->_isoFormatString); - } elseif ($value instanceof DateTime) { - $this->_value = $value->format($this->_phpFormatString); - } elseif (is_numeric($value)) { // The value is numeric, we make sure it is an integer - $this->_value = date($this->_phpFormatString, (int)$value); - } else { - $timestamp = new DateTime($value); - if ($timestamp === false) { // cannot convert the value to a timestamp - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Cannot convert given value \''. $value .'\' to a timestamp'); - } - - $this->_value = $timestamp->format($this->_phpFormatString); // Convert the timestamp to iso8601 format - } - } - - /** - * Return the value of this object as iso8601 dateTime value - * - * @return int As a Unix timestamp - */ - public function getValue() - { - return $this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Double.php b/lib/Zend/XmlRpc/Value/Double.php deleted file mode 100644 index 9962efd7d84..00000000000 --- a/lib/Zend/XmlRpc/Value/Double.php +++ /dev/null @@ -1,62 +0,0 @@ -_type = self::XMLRPC_TYPE_DOUBLE; - $precision = (int)ini_get('precision'); - $formatString = '%1.' . $precision . 'F'; - $this->_value = rtrim(sprintf($formatString, (float)$value), '0'); - } - - /** - * Return the value of this object, convert the XML-RPC native double value into a PHP float - * - * @return float - */ - public function getValue() - { - return (float)$this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Exception.php b/lib/Zend/XmlRpc/Value/Exception.php deleted file mode 100644 index 84f2d051a5d..00000000000 --- a/lib/Zend/XmlRpc/Value/Exception.php +++ /dev/null @@ -1,39 +0,0 @@ - PHP_INT_MAX) { - #require_once 'Zend/XmlRpc/Value/Exception.php'; - throw new Zend_XmlRpc_Value_Exception('Overlong integer given'); - } - - $this->_type = self::XMLRPC_TYPE_INTEGER; - $this->_value = (int)$value; // Make sure this value is integer - } - - /** - * Return the value of this object, convert the XML-RPC native integer value into a PHP integer - * - * @return int - */ - public function getValue() - { - return $this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Nil.php b/lib/Zend/XmlRpc/Value/Nil.php deleted file mode 100644 index b95825e9fc3..00000000000 --- a/lib/Zend/XmlRpc/Value/Nil.php +++ /dev/null @@ -1,60 +0,0 @@ -_type = self::XMLRPC_TYPE_NIL; - $this->_value = null; - } - - /** - * Return the value of this object, convert the XML-RPC native nill value into a PHP NULL - * - * @return null - */ - public function getValue() - { - return null; - } -} - diff --git a/lib/Zend/XmlRpc/Value/Scalar.php b/lib/Zend/XmlRpc/Value/Scalar.php deleted file mode 100644 index 0e2210f896b..00000000000 --- a/lib/Zend/XmlRpc/Value/Scalar.php +++ /dev/null @@ -1,53 +0,0 @@ -getGenerator(); - - $generator->openElement('value') - ->openElement($this->_type, $this->_value) - ->closeElement($this->_type) - ->closeElement('value'); - } -} diff --git a/lib/Zend/XmlRpc/Value/String.php b/lib/Zend/XmlRpc/Value/String.php deleted file mode 100644 index 5980a825b47..00000000000 --- a/lib/Zend/XmlRpc/Value/String.php +++ /dev/null @@ -1,60 +0,0 @@ -_type = self::XMLRPC_TYPE_STRING; - - // Make sure this value is string and all XML characters are encoded - $this->_value = (string)$value; - } - - /** - * Return the value of this object, convert the XML-RPC native string value into a PHP string - * - * @return string - */ - public function getValue() - { - return (string)$this->_value; - } -} diff --git a/lib/Zend/XmlRpc/Value/Struct.php b/lib/Zend/XmlRpc/Value/Struct.php deleted file mode 100644 index e4a2d810fcd..00000000000 --- a/lib/Zend/XmlRpc/Value/Struct.php +++ /dev/null @@ -1,75 +0,0 @@ -_type = self::XMLRPC_TYPE_STRUCT; - parent::__construct($value); - } - - - /** - * Generate the XML code that represent struct native MXL-RPC value - * - * @return void - */ - protected function _generateXML() - { - $generator = $this->getGenerator(); - $generator->openElement('value') - ->openElement('struct'); - - if (is_array($this->_value)) { - foreach ($this->_value as $name => $val) { - /* @var $val Zend_XmlRpc_Value */ - $generator->openElement('member') - ->openElement('name', $name) - ->closeElement('name'); - $val->generateXml(); - $generator->closeElement('member'); - } - } - $generator->closeElement('struct') - ->closeElement('value'); - } -} diff --git a/lib/Zend/replace_recursive.php b/lib/Zend/replace_recursive.php deleted file mode 100644 index 52f56ad2d2a..00000000000 --- a/lib/Zend/replace_recursive.php +++ /dev/null @@ -1,45 +0,0 @@ - Date: Tue, 6 Dec 2022 11:37:31 +0000 Subject: [PATCH 2/9] required zf1future --- composer.json | 3 +- composer.lock | 220 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 142 insertions(+), 81 deletions(-) diff --git a/composer.json b/composer.json index e2dd0df3719..741e4727263 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,8 @@ "magento-hackathon/magento-composer-installer": "^3.1 || ^2.1 || ^4.0", "pelago/emogrifier": "^6.0", "phpseclib/mcrypt_compat": "^2.0.3", - "phpseclib/phpseclib": "^3.0.14" + "phpseclib/phpseclib": "^3.0.14", + "shardj/zf1-future": "^1.21" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", diff --git a/composer.lock b/composer.lock index 542e04b535b..36d7b5bb72f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d42d1f7b72063046f689a1fcb8bf3fd4", + "content-hash": "7ccde4329c9eac51bf53ac772bde4d38", "packages": [ { "name": "colinmollenhour/cache-backend-redis", @@ -928,6 +928,66 @@ }, "time": "2021-12-11T13:40:54+00:00" }, + { + "name": "shardj/zf1-future", + "version": "1.21.4", + "source": { + "type": "git", + "url": "https://github.com/Shardj/zf1-future.git", + "reference": "7b57530525f48c173a7cf61f5cdfb7d652f3c5d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Shardj/zf1-future/zipball/7b57530525f48c173a7cf61f5cdfb7d652f3c5d8", + "reference": "7b57530525f48c173a7cf61f5cdfb7d652f3c5d8", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-mbstring": "^1.26", + "symfony/polyfill-php81": "^1.24" + }, + "replace": { + "zendframework/zendframework1": ">=1.12.20" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "1.0.0", + "phpunit/dbunit": "1.3.*", + "zf1s/phpunit": "3.7.39" + }, + "suggest": { + "ext-mbstring": "Multibyte strings handling" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12.x-dev" + } + }, + "autoload": { + "psr-0": { + "Zend_": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "library/" + ], + "license": [ + "BSD-3-Clause" + ], + "description": "Zend Framework 1. The aim is to keep ZF1 working with the latest PHP versions", + "homepage": "http://framework.zend.com/", + "keywords": [ + "ZF1", + "framework" + ], + "support": { + "issues": "https://github.com/Shardj/zf1-future/issues", + "source": "https://github.com/Shardj/zf1-future/tree/release-1.21.4" + }, + "time": "2022-09-22T11:00:12+00:00" + }, { "name": "symfony/console", "version": "v5.4.16", @@ -1652,6 +1712,85 @@ ], "time": "2022-11-03T14:55:06+00:00" }, + { + "name": "symfony/polyfill-php81", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, { "name": "symfony/service-contracts", "version": "v2.5.2", @@ -5156,85 +5295,6 @@ ], "time": "2022-07-20T13:00:38+00:00" }, - { - "name": "symfony/polyfill-php81", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, { "name": "symfony/process", "version": "v5.4.11", From 755fa84176f208d42fd1190c8ca3ec45d44cafdb Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Wed, 7 Dec 2022 13:43:51 +0000 Subject: [PATCH 3/9] The difference doesnt justify having an overridden file --- app/code/core/Zend/Filter/PregReplace.php | 201 ---------------------- 1 file changed, 201 deletions(-) delete mode 100644 app/code/core/Zend/Filter/PregReplace.php diff --git a/app/code/core/Zend/Filter/PregReplace.php b/app/code/core/Zend/Filter/PregReplace.php deleted file mode 100644 index d549aa55499..00000000000 --- a/app/code/core/Zend/Filter/PregReplace.php +++ /dev/null @@ -1,201 +0,0 @@ - matching pattern - * 'replace' => replace with this - * - * @param string|array $options - * @return void - */ - public function __construct($options = null) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp = array(); - if (!empty($options)) { - $temp['match'] = array_shift($options); - } - - if (!empty($options)) { - $temp['replace'] = array_shift($options); - } - - $options = $temp; - } - - if (array_key_exists('match', $options)) { - $this->setMatchPattern($options['match']); - } - - if (array_key_exists('replace', $options)) { - $this->setReplacement($options['replace']); - } - } - - /** - * Set the match pattern for the regex being called within filter() - * - * @param mixed $match - same as the first argument of preg_replace - * @return $this - */ - public function setMatchPattern($match) - { - $this->_matchPattern = $match; - return $this; - } - - /** - * Get currently set match pattern - * - * @return string - */ - public function getMatchPattern() - { - return $this->_matchPattern; - } - - /** - * Set the Replacement pattern/string for the preg_replace called in filter - * - * @param mixed $replacement - same as the second argument of preg_replace - * @return $this - */ - public function setReplacement($replacement) - { - $this->_replacement = $replacement; - return $this; - } - - /** - * Get currently set replacement value - * - * @return string - */ - public function getReplacement() - { - return $this->_replacement; - } - - /** - * Perform regexp replacement as filter - * - * @param string $value - * @return string - */ - public function filter($value) - { - if ($this->_matchPattern == null) { - #require_once 'Zend/Filter/Exception.php'; - throw new Zend_Filter_Exception(get_class($this) . ' does not have a valid MatchPattern set.'); - } - if (!$this->_isValidMatchPattern()) { - throw new Zend_Filter_Exception(get_class($this) . ' uses deprecated modifier "/e".'); - } - - return preg_replace($this->_matchPattern, $this->_replacement, $value); - } - - /** - * Method for checking correctness of match pattern - * - * @return bool - */ - public function _isValidMatchPattern() - { - $result = true; - foreach ((array) $this->_matchPattern as $pattern) { - $firstDilimeter = substr($pattern, 0, 1); - $partsOfRegex = explode($firstDilimeter, $pattern); - $modifiers = array_pop($partsOfRegex); - if ($modifiers != str_replace('e', '', $modifiers)) { - $result = false; - break; - } - } - - return $result; - } -} From 432c22fa2845d2394da88b6a93e95f8513c94cba Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Wed, 7 Dec 2022 13:48:08 +0000 Subject: [PATCH 4/9] differences are about extremely old php versions --- app/code/core/Zend/Xml/Security.php | 485 ---------------------------- 1 file changed, 485 deletions(-) delete mode 100644 app/code/core/Zend/Xml/Security.php diff --git a/app/code/core/Zend/Xml/Security.php b/app/code/core/Zend/Xml/Security.php deleted file mode 100644 index 59e7ea33b92..00000000000 --- a/app/code/core/Zend/Xml/Security.php +++ /dev/null @@ -1,485 +0,0 @@ - 0) { - return true; - } - return false; - } - - /** - * Scan XML string for potential XXE and XEE attacks - * - * @param string $xml - * @param DomDocument $dom - * @throws Zend_Xml_Exception - * @return SimpleXMLElement|DomDocument|boolean - */ - public static function scan($xml, DOMDocument $dom = null) - { - // If running with PHP-FPM we perform an heuristic scan - // We cannot use libxml_disable_entity_loader because of this bug - // @see https://bugs.php.net/bug.php?id=64938 - if (self::isPhpFpm()) { - self::heuristicScan($xml); - } - - if (null === $dom) { - $simpleXml = true; - $dom = new DOMDocument(); - } - - if (!self::isPhpFpm()) { - if ((LIBXML_VERSION < 20900) && function_exists('libxml_disable_entity_loader')) { - $loadEntities = libxml_disable_entity_loader(true); - } - $useInternalXmlErrors = libxml_use_internal_errors(true); - } - - // Load XML with network access disabled (LIBXML_NONET) - // error disabled with @ for PHP-FPM scenario - set_error_handler(array('Zend_Xml_Security', 'loadXmlErrorHandler'), E_WARNING); - - $result = $dom->loadXML($xml, LIBXML_NONET); - restore_error_handler(); - - if (!$result) { - // Entity load to previous setting - if (!self::isPhpFpm()) { - if (isset($loadEntities)) { - libxml_disable_entity_loader($loadEntities); - } - libxml_use_internal_errors($useInternalXmlErrors); - } - return false; - } - - // Scan for potential XEE attacks using ENTITY, if not PHP-FPM - if (!self::isPhpFpm()) { - foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - if (isset($child->entities) && $child->entities->length > 0) { - if (isset($loadEntities)) { - libxml_disable_entity_loader($loadEntities); - } - libxml_use_internal_errors($useInternalXmlErrors); - - #require_once 'Exception.php'; - throw new Zend_Xml_Exception(self::ENTITY_DETECT); - } - } - } - } - - // Entity load to previous setting - if (!self::isPhpFpm()) { - if (isset($loadEntities)) { - libxml_disable_entity_loader($loadEntities); - } - libxml_use_internal_errors($useInternalXmlErrors); - } - - if (isset($simpleXml)) { - $result = simplexml_import_dom($dom); - if (!$result instanceof SimpleXMLElement) { - return false; - } - return $result; - } - return $dom; - } - - /** - * Scan XML file for potential XXE/XEE attacks - * - * @param string $file - * @param DOMDocument $dom - * @throws Zend_Xml_Exception - * @return SimpleXMLElement|DomDocument - */ - public static function scanFile($file, DOMDocument $dom = null) - { - if (!file_exists($file)) { - #require_once 'Exception.php'; - throw new Zend_Xml_Exception( - "The file $file specified doesn't exist" - ); - } - return self::scan(file_get_contents($file), $dom); - } - - /** - * Return true if PHP is running with PHP-FPM - * - * This method is mainly used to determine whether or not heuristic checks - * (vs libxml checks) should be made, due to threading issues in libxml; - * under php-fpm, threading becomes a concern. - * - * @return boolean - */ - public static function isPhpFpm() - { - if (substr(php_sapi_name(), 0, 3) === 'fpm') { - return true; - } - return false; - } - - /** - * Determine and return the string(s) to use for the $generator) { - $prefix = call_user_func($generator, '<' . '?xml'); - if (0 === strncmp($xml, $prefix, strlen($prefix))) { - return $encoding; - } - } - - // Fallback - return 'UTF-8'; - } - - /** - * Attempt to detect the specified XML encoding. - * - * Using the file's encoding, determines if an "encoding" attribute is - * present and well-formed in the XML declaration; if so, it returns a - * list with both the ASCII representation of that declaration and the - * original file encoding. - * - * If not, a list containing only the provided file encoding is returned. - * - * @param string $xml - * @param string $fileEncoding - * @return string[] Potential XML encodings - */ - protected static function detectXmlEncoding($xml, $fileEncoding) - { - $encodingMap = self::getAsciiEncodingMap(); - $generator = $encodingMap[$fileEncoding]; - $encAttr = call_user_func($generator, 'encoding="'); - $quote = call_user_func($generator, '"'); - $close = call_user_func($generator, '>'); - - $closePos = strpos($xml, $close); - if (false === $closePos) { - return array($fileEncoding); - } - - $encPos = strpos($xml, $encAttr); - if (false === $encPos - || $encPos > $closePos - ) { - return array($fileEncoding); - } - - $encPos += strlen($encAttr); - $quotePos = strpos($xml, $quote, $encPos); - if (false === $quotePos) { - return array($fileEncoding); - } - - $encoding = self::substr($xml, $encPos, $quotePos); - return array( - // Following line works because we're only supporting 8-bit safe encodings at this time. - str_replace('\0', '', $encoding), // detected encoding - $fileEncoding, // file encoding - ); - } - - /** - * Return a list of BOM maps. - * - * Returns a list of common encoding -> BOM maps, along with the character - * length to compare against. - * - * @link https://en.wikipedia.org/wiki/Byte_order_mark - * @return array - */ - protected static function getBomMap() - { - return array( - array( - 'encoding' => 'UTF-32BE', - 'bom' => pack('CCCC', 0x00, 0x00, 0xfe, 0xff), - 'length' => 4, - ), - array( - 'encoding' => 'UTF-32LE', - 'bom' => pack('CCCC', 0xff, 0xfe, 0x00, 0x00), - 'length' => 4, - ), - array( - 'encoding' => 'GB-18030', - 'bom' => pack('CCCC', 0x84, 0x31, 0x95, 0x33), - 'length' => 4, - ), - array( - 'encoding' => 'UTF-16BE', - 'bom' => pack('CC', 0xfe, 0xff), - 'length' => 2, - ), - array( - 'encoding' => 'UTF-16LE', - 'bom' => pack('CC', 0xff, 0xfe), - 'length' => 2, - ), - array( - 'encoding' => 'UTF-8', - 'bom' => pack('CCC', 0xef, 0xbb, 0xbf), - 'length' => 3, - ), - ); - } - - /** - * Return a map of encoding => generator pairs. - * - * Returns a map of encoding => generator pairs, where the generator is a - * callable that accepts a string and returns the appropriate byte order - * sequence of that string for the encoding. - * - * @return array - */ - protected static function getAsciiEncodingMap() - { - return array( - 'UTF-32BE' => array(__CLASS__, 'encodeToUTF32BE'), - 'UTF-32LE' => array(__CLASS__, 'encodeToUTF32LE'), - 'UTF-32odd1' => array(__CLASS__, 'encodeToUTF32odd1'), - 'UTF-32odd2' => array(__CLASS__, 'encodeToUTF32odd2'), - 'UTF-16BE' => array(__CLASS__, 'encodeToUTF16BE'), - 'UTF-16LE' => array(__CLASS__, 'encodeToUTF16LE'), - 'UTF-8' => array(__CLASS__, 'encodeToUTF8'), - 'GB-18030' => array(__CLASS__, 'encodeToUTF8'), - ); - } - - /** - * Binary-safe substr. - * - * substr() is not binary-safe; this method loops by character to ensure - * multi-byte characters are aggregated correctly. - * - * @param string $string - * @param int $start - * @param int $end - * @return string - */ - protected static function substr($string, $start, $end) - { - $substr = ''; - for ($i = $start; $i < $end; $i += 1) { - $substr .= $string[$i]; - } - return $substr; - } - - /** - * Generate an entity comparison based on the given encoding. - * - * This patch is internal only, and public only so it can be used as a - * callable to pass to array_map. - * - * @internal - * @param string $encoding - * @return string - */ - public static function generateEntityComparison($encoding) - { - $encodingMap = self::getAsciiEncodingMap(); - $generator = isset($encodingMap[$encoding]) ? $encodingMap[$encoding] : $encodingMap['UTF-8']; - return call_user_func($generator, ' Date: Wed, 7 Dec 2022 14:07:30 +0000 Subject: [PATCH 5/9] the difference doesnt justify having an overridden file --- app/code/core/Zend/Locale/Math/PhpMath.php | 252 --------------------- 1 file changed, 252 deletions(-) delete mode 100644 app/code/core/Zend/Locale/Math/PhpMath.php diff --git a/app/code/core/Zend/Locale/Math/PhpMath.php b/app/code/core/Zend/Locale/Math/PhpMath.php deleted file mode 100644 index 2a327423351..00000000000 --- a/app/code/core/Zend/Locale/Math/PhpMath.php +++ /dev/null @@ -1,252 +0,0 @@ - $precision)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("addition overflow: $op1 + $op2 != $result", $op1, $op2, $result); - } - - return self::round(self::normalize($result), $scale); - } - - public static function Sub($op1, $op2, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - $precision = Zend_Locale_Math_PhpMath::$defaultPrecision; - } else { - $precision = pow(10, -$scale); - } - - if (empty($op1)) { - $op1 = 0; - } - if (empty($op2)) { - $op2 = 0; - } - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - $result = $op1 - $op2; - if (is_infinite($result) || (abs($result + $op2 - $op1) > $precision)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("subtraction overflow: $op1 - $op2 != $result", $op1, $op2, $result); - } - - return self::round(self::normalize($result), $scale); - } - - public static function Pow($op1, $op2, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - } - - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - - // BCMath extension doesn't use decimal part of the power - // Provide the same behavior - $op2 = ($op2 > 0) ? floor($op2) : ceil($op2); - - $result = pow($op1, $op2); - if (is_infinite($result) || is_nan($result)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("power overflow: $op1 ^ $op2", $op1, $op2, $result); - } - - return self::round(self::normalize($result), $scale); - } - - public static function Mul($op1, $op2, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - } - - if (empty($op1)) { - $op1 = 0; - } - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - $result = $op1 * $op2; - if (is_infinite($result) || is_nan($result)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("multiplication overflow: $op1 * $op2 != $result", $op1, $op2, $result); - } - - return self::round(self::normalize($result), $scale); - } - - public static function Div($op1, $op2, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - } - - if (empty($op2)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("can not divide by zero", $op1, $op2, null); - } - if (empty($op1)) { - $op1 = 0; - } - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - $result = $op1 / $op2; - if (is_infinite($result) || is_nan($result)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("division overflow: $op1 / $op2 != $result", $op1, $op2, $result); - } - - return self::round(self::normalize($result), $scale); - } - - public static function Sqrt($op1, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - } - - if (empty($op1)) { - $op1 = 0; - } - $op1 = self::normalize($op1); - $result = sqrt($op1); - if (is_nan($result)) { - return null; - } - - return self::round(self::normalize($result), $scale); - } - - public static function Mod($op1, $op2) - { - if (empty($op1)) { - $op1 = 0; - } - if (empty($op2)) { - return null; - } - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - if ((int)$op2 == 0) { - return null; - } - $result = $op1 % $op2; - if (is_nan($result) || (($op1 - $result) % $op2 != 0)) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception( - "modulus calculation error: $op1 % $op2 != $result", $op1, $op2, $result); - } - - return self::normalize($result); - } - - public static function Comp($op1, $op2, $scale = null) - { - if ($scale === null) { - $scale = Zend_Locale_Math_PhpMath::$defaultScale; - } - - if (empty($op1)) { - $op1 = 0; - } - $op1 = self::normalize($op1); - $op2 = self::normalize($op2); - if ($scale <> 0) { - $op1 = self::round($op1, $scale); - $op2 = self::round($op2, $scale); - } else { - $op1 = ($op1 > 0) ? floor($op1) : ceil($op1); - $op2 = ($op2 > 0) ? floor($op2) : ceil($op2); - } - if ($op1 > $op2) { - return 1; - } else if ($op1 < $op2) { - return -1; - } - return 0; - } - - public static function Scale($scale) - { - if ($scale > 9) { - #require_once 'Zend/Locale/Math/Exception.php'; - throw new Zend_Locale_Math_Exception("can not scale to precision $scale", $scale, null, null); - } - self::$defaultScale = $scale; - self::$defaultPrecision = pow(10, -$scale); - return true; - } -} - -Zend_Locale_Math_PhpMath::disable(); // disable use of bcmath functions From 04f899ad224a9bc1984d1bcc52130e05b13f4f69 Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Wed, 7 Dec 2022 14:14:19 +0000 Subject: [PATCH 6/9] this file seems wrong, checking for is_array on an optional parameter. anyway this class should never be used anyway because of the eval --- .../core/Zend/Serializer/Adapter/PhpCode.php | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 app/code/core/Zend/Serializer/Adapter/PhpCode.php diff --git a/app/code/core/Zend/Serializer/Adapter/PhpCode.php b/app/code/core/Zend/Serializer/Adapter/PhpCode.php deleted file mode 100644 index 40077621a38..00000000000 --- a/app/code/core/Zend/Serializer/Adapter/PhpCode.php +++ /dev/null @@ -1,72 +0,0 @@ - Date: Wed, 7 Dec 2022 14:33:23 +0000 Subject: [PATCH 7/9] theres no neference anywhere to this class --- app/code/core/Zend/Form/Decorator/Form.php | 143 --------------------- 1 file changed, 143 deletions(-) delete mode 100644 app/code/core/Zend/Form/Decorator/Form.php diff --git a/app/code/core/Zend/Form/Decorator/Form.php b/app/code/core/Zend/Form/Decorator/Form.php deleted file mode 100644 index 08f36245993..00000000000 --- a/app/code/core/Zend/Form/Decorator/Form.php +++ /dev/null @@ -1,143 +0,0 @@ -_helper = (string) $helper; - return $this; - } - - /** - * Get view helper for rendering form - * - * @return string - */ - public function getHelper() - { - if (null !== ($helper = $this->getOption('helper'))) { - $this->setHelper($helper); - $this->removeOption('helper'); - } - return $this->_helper; - } - - /** - * Retrieve decorator options - * - * Assures that form action and method are set, and sets appropriate - * encoding type if current method is POST. - * - * @return array - */ - public function getOptions() - { - if (null !== ($element = $this->getElement())) { - if ($element instanceof Zend_Form) { - $element->getAction(); - $method = $element->getMethod(); - if ($method == Zend_Form::METHOD_POST) { - $this->setOption('enctype', 'application/x-www-form-urlencoded'); - } - foreach ($element->getAttribs() as $key => $value) { - $this->setOption($key, $value); - } - } elseif ($element instanceof Zend_Form_DisplayGroup) { - foreach ($element->getAttribs() as $key => $value) { - $this->setOption($key, $value); - } - } - } - - if (isset($this->_options['method'])) { - $this->_options['method'] = strtolower($this->_options['method']); - } - - return $this->_options; - } - - /** - * Render a form - * - * Replaces $content entirely from currently set element. - * - * @param string $content - * @return string - */ - public function render($content) - { - $form = $this->getElement(); - $view = $form->getView(); - if (null === $view) { - return $content; - } - - $helper = $this->getHelper(); - $attribs = $this->getOptions(); - $name = $form->getFullyQualifiedName(); - $attribs['id'] = $form->getId(); - if ($helper == 'unserialize') { - $filter = new Varien_Filter_FormElementName(true); - if($filter->filter($name) != $name){ - throw new Zend_Form_Exception(sprintf('Invalid element name:"%s"', $name)); - } - } - return $view->$helper($name, $attribs, $content); - } -} From 2ddb28e386ec1c10f8a55be11f143653c340be5c Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Wed, 7 Dec 2022 16:45:09 +0000 Subject: [PATCH 8/9] the difference is about php7.2, which is supported by zf1future --- app/code/core/Zend/Validate/File/Upload.php | 254 -------------------- 1 file changed, 254 deletions(-) delete mode 100644 app/code/core/Zend/Validate/File/Upload.php diff --git a/app/code/core/Zend/Validate/File/Upload.php b/app/code/core/Zend/Validate/File/Upload.php deleted file mode 100644 index 6a42a704a2c..00000000000 --- a/app/code/core/Zend/Validate/File/Upload.php +++ /dev/null @@ -1,254 +0,0 @@ - "File '%value%' exceeds the defined ini size", - self::FORM_SIZE => "File '%value%' exceeds the defined form size", - self::PARTIAL => "File '%value%' was only partially uploaded", - self::NO_FILE => "File '%value%' was not uploaded", - self::NO_TMP_DIR => "No temporary directory was found for file '%value%'", - self::CANT_WRITE => "File '%value%' can't be written", - self::EXTENSION => "A PHP extension returned an error while uploading the file '%value%'", - self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", - self::FILE_NOT_FOUND => "File '%value%' was not found", - self::UNKNOWN => "Unknown error while uploading file '%value%'" - ); - - /** - * Internal array of files - * @var array - */ - protected $_files = array(); - - /** - * Sets validator options - * - * The array $files must be given in syntax of Zend_File_Transfer to be checked - * If no files are given the $_FILES array will be used automatically. - * NOTE: This validator will only work with HTTP POST uploads! - * - * @param array|Zend_Config $files Array of files in syntax of Zend_File_Transfer - */ - public function __construct($files = array()) - { - if ($files instanceof Zend_Config) { - $files = $files->toArray(); - } - - $this->setFiles($files); - } - - /** - * Returns the array of set files - * - * @param string $file (Optional) The file to return in detail - * @return array - * @throws Zend_Validate_Exception If file is not found - */ - public function getFiles($file = null) - { - if ($file !== null) { - $return = array(); - foreach ($this->_files as $name => $content) { - if ($name === $file) { - $return[$file] = $this->_files[$name]; - } - - if ($content['name'] === $file) { - $return[$name] = $this->_files[$name]; - } - } - - if (count($return) === 0) { - #require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The file '$file' was not found"); - } - - return $return; - } - - return $this->_files; - } - - /** - * Sets the files to be checked - * - * @param array $files The files to check in syntax of Zend_File_Transfer - * @return $this Provides a fluent interface - */ - public function setFiles($files = array()) - { - if (count($files) === 0) { - $this->_files = $_FILES; - } else { - $this->_files = $files; - } - - // see ZF-10738 - if (is_null($this->_files)) { - $this->_files = array(); - } - - foreach($this->_files as $file => $content) { - if (!isset($content['error'])) { - unset($this->_files[$file]); - } - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file was uploaded without errors - * - * @param string $value Single file to check for upload errors, when giving null the $_FILES array - * from initialization will be used - * @param string|null $file - * @return boolean - */ - public function isValid($value, $file = null) - { - $this->_messages = null; - if (array_key_exists($value, $this->_files)) { - $files[$value] = $this->_files[$value]; - } else { - foreach ($this->_files as $file => $content) { - if (isset($content['name']) && ($content['name'] === $value)) { - $files[$file] = $this->_files[$file]; - } - - if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) { - $files[$file] = $this->_files[$file]; - } - } - } - - if (empty($files)) { - return $this->_throw($file, self::FILE_NOT_FOUND); - } - - foreach ($files as $file => $content) { - $this->_value = $file; - switch($content['error']) { - case 0: - if (!is_uploaded_file($content['tmp_name'])) { - $this->_throw($content, self::ATTACK); - } - break; - - case 1: - $this->_throw($content, self::INI_SIZE); - break; - - case 2: - $this->_throw($content, self::FORM_SIZE); - break; - - case 3: - $this->_throw($content, self::PARTIAL); - break; - - case 4: - $this->_throw($content, self::NO_FILE); - break; - - case 6: - $this->_throw($content, self::NO_TMP_DIR); - break; - - case 7: - $this->_throw($content, self::CANT_WRITE); - break; - - case 8: - $this->_throw($content, self::EXTENSION); - break; - - default: - $this->_throw($content, self::UNKNOWN); - break; - } - } - /** - * PHP7.2 compatibility fix. - * More info https://wiki.php.net/rfc/counting_non_countables - */ - if (isset($this->_messages) && count($this->_messages) > 0) { - return false; - } else { - return true; - } - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - if (is_array($file) && !empty($file['name'])) { - $this->_value = $file['name']; - } - } - - $this->_error($errorType); - return false; - } -} From 2e06e09ac0ed60eebf3f2bf56887c9b3c33322e1 Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano Date: Wed, 7 Dec 2022 17:47:39 +0000 Subject: [PATCH 9/9] this one is a mess but it seems that the zf1future is more advanced than ours --- app/code/core/Zend/Validate/Hostname.php | 2528 ---------------------- 1 file changed, 2528 deletions(-) delete mode 100644 app/code/core/Zend/Validate/Hostname.php diff --git a/app/code/core/Zend/Validate/Hostname.php b/app/code/core/Zend/Validate/Hostname.php deleted file mode 100644 index e6c4f1f303e..00000000000 --- a/app/code/core/Zend/Validate/Hostname.php +++ /dev/null @@ -1,2528 +0,0 @@ - "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", - self::INVALID => "Invalid type given. String expected", - self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", - self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", - self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", - self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", - self::INVALID_URI => "'%value%' does not appear to be a valid URI hostname", - self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed", - self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed", - self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", - self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'tld' => '_tld' - ); - - /** - * Allows Internet domain names (e.g., example.com) - */ - const ALLOW_DNS = 1; - - /** - * Allows IP addresses - */ - const ALLOW_IP = 2; - - /** - * Allows local network names (e.g., localhost, www.localdomain) - */ - const ALLOW_LOCAL = 4; - - /** - * Allows all types of hostnames - */ - const ALLOW_URI = 8; - - /** - * Allows all types of hostnames - */ - const ALLOW_ALL = 15; - - /** - * Array of valid top-level-domains - * - * Version 2017112100, Last Updated Tue Nov 21 07:07:01 2017 UTC - * - * @see http://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain - * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs - * @var array - */ - protected $_validTlds = array( - 'aaa', - 'aarp', - 'abarth', - 'abb', - 'abbott', - 'abbvie', - 'abc', - 'able', - 'abogado', - 'abudhabi', - 'ac', - 'academy', - 'accenture', - 'accountant', - 'accountants', - 'aco', - 'active', - 'actor', - 'ad', - 'adac', - 'ads', - 'adult', - 'ae', - 'aeg', - 'aero', - 'aetna', - 'af', - 'afamilycompany', - 'afl', - 'africa', - 'ag', - 'agakhan', - 'agency', - 'ai', - 'aig', - 'aigo', - 'airbus', - 'airforce', - 'airtel', - 'akdn', - 'al', - 'alfaromeo', - 'alibaba', - 'alipay', - 'allfinanz', - 'allstate', - 'ally', - 'alsace', - 'alstom', - 'am', - 'americanexpress', - 'americanfamily', - 'amex', - 'amfam', - 'amica', - 'amsterdam', - 'analytics', - 'android', - 'anquan', - 'anz', - 'ao', - 'aol', - 'apartments', - 'app', - 'apple', - 'aq', - 'aquarelle', - 'ar', - 'arab', - 'aramco', - 'archi', - 'army', - 'arpa', - 'art', - 'arte', - 'as', - 'asda', - 'asia', - 'associates', - 'at', - 'athleta', - 'attorney', - 'au', - 'auction', - 'audi', - 'audible', - 'audio', - 'auspost', - 'author', - 'auto', - 'autos', - 'avianca', - 'aw', - 'aws', - 'ax', - 'axa', - 'az', - 'azure', - 'ba', - 'baby', - 'baidu', - 'banamex', - 'bananarepublic', - 'band', - 'bank', - 'bar', - 'barcelona', - 'barclaycard', - 'barclays', - 'barefoot', - 'bargains', - 'baseball', - 'basketball', - 'bauhaus', - 'bayern', - 'bb', - 'bbc', - 'bbt', - 'bbva', - 'bcg', - 'bcn', - 'bd', - 'be', - 'beats', - 'beauty', - 'beer', - 'bentley', - 'berlin', - 'best', - 'bestbuy', - 'bet', - 'bf', - 'bg', - 'bh', - 'bharti', - 'bi', - 'bible', - 'bid', - 'bike', - 'bing', - 'bingo', - 'bio', - 'biz', - 'bj', - 'black', - 'blackfriday', - 'blanco', - 'blockbuster', - 'blog', - 'bloomberg', - 'blue', - 'bm', - 'bms', - 'bmw', - 'bn', - 'bnl', - 'bnpparibas', - 'bo', - 'boats', - 'boehringer', - 'bofa', - 'bom', - 'bond', - 'boo', - 'book', - 'booking', - 'boots', - 'bosch', - 'bostik', - 'boston', - 'bot', - 'boutique', - 'box', - 'br', - 'bradesco', - 'bridgestone', - 'broadway', - 'broker', - 'brother', - 'brussels', - 'bs', - 'bt', - 'budapest', - 'bugatti', - 'build', - 'builders', - 'business', - 'buy', - 'buzz', - 'bv', - 'bw', - 'by', - 'bz', - 'bzh', - 'ca', - 'cab', - 'cafe', - 'cal', - 'call', - 'calvinklein', - 'cam', - 'camera', - 'camp', - 'cancerresearch', - 'canon', - 'capetown', - 'capital', - 'capitalone', - 'car', - 'caravan', - 'cards', - 'care', - 'career', - 'careers', - 'cars', - 'cartier', - 'casa', - 'case', - 'caseih', - 'cash', - 'casino', - 'cat', - 'catering', - 'catholic', - 'cba', - 'cbn', - 'cbre', - 'cbs', - 'cc', - 'cd', - 'ceb', - 'center', - 'ceo', - 'cern', - 'cf', - 'cfa', - 'cfd', - 'cg', - 'ch', - 'chanel', - 'channel', - 'chase', - 'chat', - 'cheap', - 'chintai', - 'christmas', - 'chrome', - 'chrysler', - 'church', - 'ci', - 'cipriani', - 'circle', - 'cisco', - 'citadel', - 'citi', - 'citic', - 'city', - 'cityeats', - 'ck', - 'cl', - 'claims', - 'cleaning', - 'click', - 'clinic', - 'clinique', - 'clothing', - 'cloud', - 'club', - 'clubmed', - 'cm', - 'cn', - 'co', - 'coach', - 'codes', - 'coffee', - 'college', - 'cologne', - 'com', - 'comcast', - 'commbank', - 'community', - 'company', - 'compare', - 'computer', - 'comsec', - 'condos', - 'construction', - 'consulting', - 'contact', - 'contractors', - 'cooking', - 'cookingchannel', - 'cool', - 'coop', - 'corsica', - 'country', - 'coupon', - 'coupons', - 'courses', - 'cr', - 'credit', - 'creditcard', - 'creditunion', - 'cricket', - 'crown', - 'crs', - 'cruise', - 'cruises', - 'csc', - 'cu', - 'cuisinella', - 'cv', - 'cw', - 'cx', - 'cy', - 'cymru', - 'cyou', - 'cz', - 'dabur', - 'dad', - 'dance', - 'data', - 'date', - 'dating', - 'datsun', - 'day', - 'dclk', - 'dds', - 'de', - 'deal', - 'dealer', - 'deals', - 'degree', - 'delivery', - 'dell', - 'deloitte', - 'delta', - 'democrat', - 'dental', - 'dentist', - 'desi', - 'design', - 'dev', - 'dhl', - 'diamonds', - 'diet', - 'digital', - 'direct', - 'directory', - 'discount', - 'discover', - 'dish', - 'diy', - 'dj', - 'dk', - 'dm', - 'dnp', - 'do', - 'docs', - 'doctor', - 'dodge', - 'dog', - 'doha', - 'domains', - 'dot', - 'download', - 'drive', - 'dtv', - 'dubai', - 'duck', - 'dunlop', - 'duns', - 'dupont', - 'durban', - 'dvag', - 'dvr', - 'dz', - 'earth', - 'eat', - 'ec', - 'eco', - 'edeka', - 'edu', - 'education', - 'ee', - 'eg', - 'email', - 'emerck', - 'energy', - 'engineer', - 'engineering', - 'enterprises', - 'epost', - 'epson', - 'equipment', - 'er', - 'ericsson', - 'erni', - 'es', - 'esq', - 'estate', - 'esurance', - 'et', - 'etisalat', - 'eu', - 'eurovision', - 'eus', - 'events', - 'everbank', - 'exchange', - 'expert', - 'exposed', - 'express', - 'extraspace', - 'fage', - 'fail', - 'fairwinds', - 'faith', - 'family', - 'fan', - 'fans', - 'farm', - 'farmers', - 'fashion', - 'fast', - 'fedex', - 'feedback', - 'ferrari', - 'ferrero', - 'fi', - 'fiat', - 'fidelity', - 'fido', - 'film', - 'final', - 'finance', - 'financial', - 'fire', - 'firestone', - 'firmdale', - 'fish', - 'fishing', - 'fit', - 'fitness', - 'fj', - 'fk', - 'flickr', - 'flights', - 'flir', - 'florist', - 'flowers', - 'fly', - 'fm', - 'fo', - 'foo', - 'food', - 'foodnetwork', - 'football', - 'ford', - 'forex', - 'forsale', - 'forum', - 'foundation', - 'fox', - 'fr', - 'free', - 'fresenius', - 'frl', - 'frogans', - 'frontdoor', - 'frontier', - 'ftr', - 'fujitsu', - 'fujixerox', - 'fun', - 'fund', - 'furniture', - 'futbol', - 'fyi', - 'ga', - 'gal', - 'gallery', - 'gallo', - 'gallup', - 'game', - 'games', - 'gap', - 'garden', - 'gb', - 'gbiz', - 'gd', - 'gdn', - 'ge', - 'gea', - 'gent', - 'genting', - 'george', - 'gf', - 'gg', - 'ggee', - 'gh', - 'gi', - 'gift', - 'gifts', - 'gives', - 'giving', - 'gl', - 'glade', - 'glass', - 'gle', - 'global', - 'globo', - 'gm', - 'gmail', - 'gmbh', - 'gmo', - 'gmx', - 'gn', - 'godaddy', - 'gold', - 'goldpoint', - 'golf', - 'goo', - 'goodhands', - 'goodyear', - 'goog', - 'google', - 'gop', - 'got', - 'gov', - 'gp', - 'gq', - 'gr', - 'grainger', - 'graphics', - 'gratis', - 'green', - 'gripe', - 'grocery', - 'group', - 'gs', - 'gt', - 'gu', - 'guardian', - 'gucci', - 'guge', - 'guide', - 'guitars', - 'guru', - 'gw', - 'gy', - 'hair', - 'hamburg', - 'hangout', - 'haus', - 'hbo', - 'hdfc', - 'hdfcbank', - 'health', - 'healthcare', - 'help', - 'helsinki', - 'here', - 'hermes', - 'hgtv', - 'hiphop', - 'hisamitsu', - 'hitachi', - 'hiv', - 'hk', - 'hkt', - 'hm', - 'hn', - 'hockey', - 'holdings', - 'holiday', - 'homedepot', - 'homegoods', - 'homes', - 'homesense', - 'honda', - 'honeywell', - 'horse', - 'hospital', - 'host', - 'hosting', - 'hot', - 'hoteles', - 'hotels', - 'hotmail', - 'house', - 'how', - 'hr', - 'hsbc', - 'ht', - 'hu', - 'hughes', - 'hyatt', - 'hyundai', - 'ibm', - 'icbc', - 'ice', - 'icu', - 'id', - 'ie', - 'ieee', - 'ifm', - 'ikano', - 'il', - 'im', - 'imamat', - 'imdb', - 'immo', - 'immobilien', - 'in', - 'industries', - 'infiniti', - 'info', - 'ing', - 'ink', - 'institute', - 'insurance', - 'insure', - 'int', - 'intel', - 'international', - 'intuit', - 'investments', - 'io', - 'ipiranga', - 'iq', - 'ir', - 'irish', - 'is', - 'iselect', - 'ismaili', - 'ist', - 'istanbul', - 'it', - 'itau', - 'itv', - 'iveco', - 'iwc', - 'jaguar', - 'java', - 'jcb', - 'jcp', - 'je', - 'jeep', - 'jetzt', - 'jewelry', - 'jio', - 'jlc', - 'jll', - 'jm', - 'jmp', - 'jnj', - 'jo', - 'jobs', - 'joburg', - 'jot', - 'joy', - 'jp', - 'jpmorgan', - 'jprs', - 'juegos', - 'juniper', - 'kaufen', - 'kddi', - 'ke', - 'kerryhotels', - 'kerrylogistics', - 'kerryproperties', - 'kfh', - 'kg', - 'kh', - 'ki', - 'kia', - 'kim', - 'kinder', - 'kindle', - 'kitchen', - 'kiwi', - 'km', - 'kn', - 'koeln', - 'komatsu', - 'kosher', - 'kp', - 'kpmg', - 'kpn', - 'kr', - 'krd', - 'kred', - 'kuokgroup', - 'kw', - 'ky', - 'kyoto', - 'kz', - 'la', - 'lacaixa', - 'ladbrokes', - 'lamborghini', - 'lamer', - 'lancaster', - 'lancia', - 'lancome', - 'land', - 'landrover', - 'lanxess', - 'lasalle', - 'lat', - 'latino', - 'latrobe', - 'law', - 'lawyer', - 'lb', - 'lc', - 'lds', - 'lease', - 'leclerc', - 'lefrak', - 'legal', - 'lego', - 'lexus', - 'lgbt', - 'li', - 'liaison', - 'lidl', - 'life', - 'lifeinsurance', - 'lifestyle', - 'lighting', - 'like', - 'lilly', - 'limited', - 'limo', - 'lincoln', - 'linde', - 'link', - 'lipsy', - 'live', - 'living', - 'lixil', - 'lk', - 'loan', - 'loans', - 'locker', - 'locus', - 'loft', - 'lol', - 'london', - 'lotte', - 'lotto', - 'love', - 'lpl', - 'lplfinancial', - 'lr', - 'ls', - 'lt', - 'ltd', - 'ltda', - 'lu', - 'lundbeck', - 'lupin', - 'luxe', - 'luxury', - 'lv', - 'ly', - 'ma', - 'macys', - 'madrid', - 'maif', - 'maison', - 'makeup', - 'man', - 'management', - 'mango', - 'map', - 'market', - 'marketing', - 'markets', - 'marriott', - 'marshalls', - 'maserati', - 'mattel', - 'mba', - 'mc', - 'mckinsey', - 'md', - 'me', - 'med', - 'media', - 'meet', - 'melbourne', - 'meme', - 'memorial', - 'men', - 'menu', - 'meo', - 'merckmsd', - 'metlife', - 'mg', - 'mh', - 'miami', - 'microsoft', - 'mil', - 'mini', - 'mint', - 'mit', - 'mitsubishi', - 'mk', - 'ml', - 'mlb', - 'mls', - 'mm', - 'mma', - 'mn', - 'mo', - 'mobi', - 'mobile', - 'mobily', - 'moda', - 'moe', - 'moi', - 'mom', - 'monash', - 'money', - 'monster', - 'mopar', - 'mormon', - 'mortgage', - 'moscow', - 'moto', - 'motorcycles', - 'mov', - 'movie', - 'movistar', - 'mp', - 'mq', - 'mr', - 'ms', - 'msd', - 'mt', - 'mtn', - 'mtr', - 'mu', - 'museum', - 'mutual', - 'mv', - 'mw', - 'mx', - 'my', - 'mz', - 'na', - 'nab', - 'nadex', - 'nagoya', - 'name', - 'nationwide', - 'natura', - 'navy', - 'nba', - 'nc', - 'ne', - 'nec', - 'net', - 'netbank', - 'netflix', - 'network', - 'neustar', - 'new', - 'newholland', - 'news', - 'next', - 'nextdirect', - 'nexus', - 'nf', - 'nfl', - 'ng', - 'ngo', - 'nhk', - 'ni', - 'nico', - 'nike', - 'nikon', - 'ninja', - 'nissan', - 'nissay', - 'nl', - 'no', - 'nokia', - 'northwesternmutual', - 'norton', - 'now', - 'nowruz', - 'nowtv', - 'np', - 'nr', - 'nra', - 'nrw', - 'ntt', - 'nu', - 'nyc', - 'nz', - 'obi', - 'observer', - 'off', - 'office', - 'okinawa', - 'olayan', - 'olayangroup', - 'oldnavy', - 'ollo', - 'om', - 'omega', - 'one', - 'ong', - 'onl', - 'online', - 'onyourside', - 'ooo', - 'open', - 'oracle', - 'orange', - 'org', - 'organic', - 'origins', - 'osaka', - 'otsuka', - 'ott', - 'ovh', - 'pa', - 'page', - 'panasonic', - 'panerai', - 'paris', - 'pars', - 'partners', - 'parts', - 'party', - 'passagens', - 'pay', - 'pccw', - 'pe', - 'pet', - 'pf', - 'pfizer', - 'pg', - 'ph', - 'pharmacy', - 'phd', - 'philips', - 'phone', - 'photo', - 'photography', - 'photos', - 'physio', - 'piaget', - 'pics', - 'pictet', - 'pictures', - 'pid', - 'pin', - 'ping', - 'pink', - 'pioneer', - 'pizza', - 'pk', - 'pl', - 'place', - 'play', - 'playstation', - 'plumbing', - 'plus', - 'pm', - 'pn', - 'pnc', - 'pohl', - 'poker', - 'politie', - 'porn', - 'post', - 'pr', - 'pramerica', - 'praxi', - 'press', - 'prime', - 'pro', - 'prod', - 'productions', - 'prof', - 'progressive', - 'promo', - 'properties', - 'property', - 'protection', - 'pru', - 'prudential', - 'ps', - 'pt', - 'pub', - 'pw', - 'pwc', - 'py', - 'qa', - 'qpon', - 'quebec', - 'quest', - 'qvc', - 'racing', - 'radio', - 'raid', - 're', - 'read', - 'realestate', - 'realtor', - 'realty', - 'recipes', - 'red', - 'redstone', - 'redumbrella', - 'rehab', - 'reise', - 'reisen', - 'reit', - 'reliance', - 'ren', - 'rent', - 'rentals', - 'repair', - 'report', - 'republican', - 'rest', - 'restaurant', - 'review', - 'reviews', - 'rexroth', - 'rich', - 'richardli', - 'ricoh', - 'rightathome', - 'ril', - 'rio', - 'rip', - 'rmit', - 'ro', - 'rocher', - 'rocks', - 'rodeo', - 'rogers', - 'room', - 'rs', - 'rsvp', - 'ru', - 'rugby', - 'ruhr', - 'run', - 'rw', - 'rwe', - 'ryukyu', - 'sa', - 'saarland', - 'safe', - 'safety', - 'sakura', - 'sale', - 'salon', - 'samsclub', - 'samsung', - 'sandvik', - 'sandvikcoromant', - 'sanofi', - 'sap', - 'sapo', - 'sarl', - 'sas', - 'save', - 'saxo', - 'sb', - 'sbi', - 'sbs', - 'sc', - 'sca', - 'scb', - 'schaeffler', - 'schmidt', - 'scholarships', - 'school', - 'schule', - 'schwarz', - 'science', - 'scjohnson', - 'scor', - 'scot', - 'sd', - 'se', - 'search', - 'seat', - 'secure', - 'security', - 'seek', - 'select', - 'sener', - 'services', - 'ses', - 'seven', - 'sew', - 'sex', - 'sexy', - 'sfr', - 'sg', - 'sh', - 'shangrila', - 'sharp', - 'shaw', - 'shell', - 'shia', - 'shiksha', - 'shoes', - 'shop', - 'shopping', - 'shouji', - 'show', - 'showtime', - 'shriram', - 'si', - 'silk', - 'sina', - 'singles', - 'site', - 'sj', - 'sk', - 'ski', - 'skin', - 'sky', - 'skype', - 'sl', - 'sling', - 'sm', - 'smart', - 'smile', - 'sn', - 'sncf', - 'so', - 'soccer', - 'social', - 'softbank', - 'software', - 'sohu', - 'solar', - 'solutions', - 'song', - 'sony', - 'soy', - 'space', - 'spiegel', - 'spot', - 'spreadbetting', - 'sr', - 'srl', - 'srt', - 'st', - 'stada', - 'staples', - 'star', - 'starhub', - 'statebank', - 'statefarm', - 'statoil', - 'stc', - 'stcgroup', - 'stockholm', - 'storage', - 'store', - 'stream', - 'studio', - 'study', - 'style', - 'su', - 'sucks', - 'supplies', - 'supply', - 'support', - 'surf', - 'surgery', - 'suzuki', - 'sv', - 'swatch', - 'swiftcover', - 'swiss', - 'sx', - 'sy', - 'sydney', - 'symantec', - 'systems', - 'sz', - 'tab', - 'taipei', - 'talk', - 'taobao', - 'target', - 'tatamotors', - 'tatar', - 'tattoo', - 'tax', - 'taxi', - 'tc', - 'tci', - 'td', - 'tdk', - 'team', - 'tech', - 'technology', - 'tel', - 'telecity', - 'telefonica', - 'temasek', - 'tennis', - 'teva', - 'tf', - 'tg', - 'th', - 'thd', - 'theater', - 'theatre', - 'tiaa', - 'tickets', - 'tienda', - 'tiffany', - 'tips', - 'tires', - 'tirol', - 'tj', - 'tjmaxx', - 'tjx', - 'tk', - 'tkmaxx', - 'tl', - 'tm', - 'tmall', - 'tn', - 'to', - 'today', - 'tokyo', - 'tools', - 'top', - 'toray', - 'toshiba', - 'total', - 'tours', - 'town', - 'toyota', - 'toys', - 'tr', - 'trade', - 'trading', - 'training', - 'travel', - 'travelchannel', - 'travelers', - 'travelersinsurance', - 'trust', - 'trv', - 'tt', - 'tube', - 'tui', - 'tunes', - 'tushu', - 'tv', - 'tvs', - 'tw', - 'tz', - 'ua', - 'ubank', - 'ubs', - 'uconnect', - 'ug', - 'uk', - 'unicom', - 'university', - 'uno', - 'uol', - 'ups', - 'us', - 'uy', - 'uz', - 'va', - 'vacations', - 'vana', - 'vanguard', - 'vc', - 've', - 'vegas', - 'ventures', - 'verisign', - 'versicherung', - 'vet', - 'vg', - 'vi', - 'viajes', - 'video', - 'vig', - 'viking', - 'villas', - 'vin', - 'vip', - 'virgin', - 'visa', - 'vision', - 'vista', - 'vistaprint', - 'viva', - 'vivo', - 'vlaanderen', - 'vn', - 'vodka', - 'volkswagen', - 'volvo', - 'vote', - 'voting', - 'voto', - 'voyage', - 'vu', - 'vuelos', - 'wales', - 'walmart', - 'walter', - 'wang', - 'wanggou', - 'warman', - 'watch', - 'watches', - 'weather', - 'weatherchannel', - 'webcam', - 'weber', - 'website', - 'wed', - 'wedding', - 'weibo', - 'weir', - 'wf', - 'whoswho', - 'wien', - 'wiki', - 'williamhill', - 'win', - 'windows', - 'wine', - 'winners', - 'wme', - 'wolterskluwer', - 'woodside', - 'work', - 'works', - 'world', - 'wow', - 'ws', - 'wtc', - 'wtf', - 'xbox', - 'xerox', - 'xfinity', - 'xihuan', - 'xin', - 'xn--11b4c3d', - 'xn--1ck2e1b', - 'xn--1qqw23a', - 'xn--2scrj9c', - 'xn--30rr7y', - 'xn--3bst00m', - 'xn--3ds443g', - 'xn--3e0b707e', - 'xn--3hcrj9c', - 'xn--3oq18vl8pn36a', - 'xn--3pxu8k', - 'xn--42c2d9a', - 'xn--45br5cyl', - 'xn--45brj9c', - 'xn--45q11c', - 'xn--4gbrim', - 'xn--54b7fta0cc', - 'xn--55qw42g', - 'xn--55qx5d', - 'xn--5su34j936bgsg', - 'xn--5tzm5g', - 'xn--6frz82g', - 'xn--6qq986b3xl', - 'xn--80adxhks', - 'xn--80ao21a', - 'xn--80aqecdr1a', - 'xn--80asehdb', - 'xn--80aswg', - 'xn--8y0a063a', - 'xn--90a3ac', - 'xn--90ae', - 'xn--90ais', - 'xn--9dbq2a', - 'xn--9et52u', - 'xn--9krt00a', - 'xn--b4w605ferd', - 'xn--bck1b9a5dre4c', - 'xn--c1avg', - 'xn--c2br7g', - 'xn--cck2b3b', - 'xn--cg4bki', - 'xn--clchc0ea0b2g2a9gcd', - 'xn--czr694b', - 'xn--czrs0t', - 'xn--czru2d', - 'xn--d1acj3b', - 'xn--d1alf', - 'xn--e1a4c', - 'xn--eckvdtc9d', - 'xn--efvy88h', - 'xn--estv75g', - 'xn--fct429k', - 'xn--fhbei', - 'xn--fiq228c5hs', - 'xn--fiq64b', - 'xn--fiqs8s', - 'xn--fiqz9s', - 'xn--fjq720a', - 'xn--flw351e', - 'xn--fpcrj9c3d', - 'xn--fzc2c9e2c', - 'xn--fzys8d69uvgm', - 'xn--g2xx48c', - 'xn--gckr3f0f', - 'xn--gecrj9c', - 'xn--gk3at1e', - 'xn--h2breg3eve', - 'xn--h2brj9c', - 'xn--h2brj9c8c', - 'xn--hxt814e', - 'xn--i1b6b1a6a2e', - 'xn--imr513n', - 'xn--io0a7i', - 'xn--j1aef', - 'xn--j1amh', - 'xn--j6w193g', - 'xn--jlq61u9w7b', - 'xn--jvr189m', - 'xn--kcrx77d1x4a', - 'xn--kprw13d', - 'xn--kpry57d', - 'xn--kpu716f', - 'xn--kput3i', - 'xn--l1acc', - 'xn--lgbbat1ad8j', - 'xn--mgb9awbf', - 'xn--mgba3a3ejt', - 'xn--mgba3a4f16a', - 'xn--mgba7c0bbn0a', - 'xn--mgbaakc7dvf', - 'xn--mgbaam7a8h', - 'xn--mgbab2bd', - 'xn--mgbai9azgqp6j', - 'xn--mgbayh7gpa', - 'xn--mgbb9fbpob', - 'xn--mgbbh1a', - 'xn--mgbbh1a71e', - 'xn--mgbc0a9azcg', - 'xn--mgbca7dzdo', - 'xn--mgberp4a5d4ar', - 'xn--mgbgu82a', - 'xn--mgbi4ecexp', - 'xn--mgbpl2fh', - 'xn--mgbt3dhd', - 'xn--mgbtx2b', - 'xn--mgbx4cd0ab', - 'xn--mix891f', - 'xn--mk1bu44c', - 'xn--mxtq1m', - 'xn--ngbc5azd', - 'xn--ngbe9e0a', - 'xn--ngbrx', - 'xn--node', - 'xn--nqv7f', - 'xn--nqv7fs00ema', - 'xn--nyqy26a', - 'xn--o3cw4h', - 'xn--ogbpf8fl', - 'xn--p1acf', - 'xn--p1ai', - 'xn--pbt977c', - 'xn--pgbs0dh', - 'xn--pssy2u', - 'xn--q9jyb4c', - 'xn--qcka1pmc', - 'xn--qxam', - 'xn--rhqv96g', - 'xn--rovu88b', - 'xn--rvc1e0am3e', - 'xn--s9brj9c', - 'xn--ses554g', - 'xn--t60b56a', - 'xn--tckwe', - 'xn--tiq49xqyj', - 'xn--unup4y', - 'xn--vermgensberater-ctb', - 'xn--vermgensberatung-pwb', - 'xn--vhquv', - 'xn--vuq861b', - 'xn--w4r85el8fhu5dnra', - 'xn--w4rs40l', - 'xn--wgbh1c', - 'xn--wgbl6a', - 'xn--xhq521b', - 'xn--xkc2al3hye2a', - 'xn--xkc2dl3a5ee0h', - 'xn--y9a3aq', - 'xn--yfro4i67o', - 'xn--ygbi2ammx', - 'xn--zfr164b', - 'xperia', - 'xxx', - 'xyz', - 'yachts', - 'yahoo', - 'yamaxun', - 'yandex', - 'ye', - 'yodobashi', - 'yoga', - 'yokohama', - 'you', - 'youtube', - 'yt', - 'yun', - 'za', - 'zappos', - 'zara', - 'zero', - 'zip', - 'zippo', - 'zm', - 'zone', - 'zuerich', - 'zw', - 'कॉम', - 'セール', - '佛山', - 'ಭಾರತ', - '慈善', - '集团', - '在线', - '한국', - 'ଭାରତ', - '大众汽车', - '点看', - 'คอม', - 'ভাৰত', - 'ভারত', - '八卦', - 'موقع', - 'বাংলা', - '公益', - '公司', - '香格里拉', - '网站', - '移动', - '我爱你', - 'москва', - 'қаз', - 'католик', - 'онлайн', - 'сайт', - '联通', - 'срб', - 'бг', - 'бел', - 'קום', - '时尚', - '微博', - '淡马锡', - 'ファッション', - 'орг', - 'नेट', - 'ストア', - '삼성', - 'சிங்கப்பூர்', - '商标', - '商店', - '商城', - 'дети', - 'мкд', - 'ею', - 'ポイント', - '新闻', - '工行', - '家電', - 'كوم', - '中文网', - '中信', - '中国', - '中國', - '娱乐', - '谷歌', - 'భారత్', - 'ලංකා', - '電訊盈科', - '购物', - 'クラウド', - 'ભારત', - '通販', - 'भारतम्', - 'भारत', - 'भारोत', - '网店', - 'संगठन', - '餐厅', - '网络', - 'ком', - 'укр', - '香港', - '诺基亚', - '食品', - '飞利浦', - '台湾', - '台灣', - '手表', - '手机', - 'мон', - 'الجزائر', - 'عمان', - 'ارامكو', - 'ایران', - 'العليان', - 'اتصالات', - 'امارات', - 'بازار', - 'پاکستان', - 'الاردن', - 'موبايلي', - 'بارت', - 'بھارت', - 'المغرب', - 'ابوظبي', - 'السعودية', - 'ڀارت', - 'كاثوليك', - 'سودان', - 'همراه', - 'عراق', - 'مليسيا', - '澳門', - '닷컴', - '政府', - 'شبكة', - 'بيتك', - 'عرب', - 'გე', - '机构', - '组织机构', - '健康', - 'ไทย', - 'سورية', - 'рус', - 'рф', - '珠宝', - 'تونس', - '大拿', - 'みんな', - 'グーグル', - 'ελ', - '世界', - '書籍', - 'ഭാരതം', - 'ਭਾਰਤ', - '网址', - '닷넷', - 'コム', - '天主教', - '游戏', - 'vermögensberater', - 'vermögensberatung', - '企业', - '信息', - '嘉里大酒店', - '嘉里', - 'مصر', - 'قطر', - '广东', - 'இலங்கை', - 'இந்தியா', - 'հայ', - '新加坡', - 'فلسطين', - '政务', - ); - - /** - * @var string - */ - protected $_tld; - - /** - * Array for valid Idns - * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars - * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf - * (.AR) Argentinia http://www.nic.ar/faqidn.html - * (.AS) American Samoa http://www.nic.as/idn/chars.cfm - * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ - * (.BIZ) International http://www.iana.org/domains/idn-tables/ - * (.BR) Brazil http://registro.br/faq/faq6.html - * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.CA) Canada http://www.iana.org/domains/idn-tables/tables/ca_fr_1.0.html - * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html - * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html - * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.DE) Germany http://www.denic.de/en/domains/idns/liste.html - * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 - * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf - * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html - * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp - * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html - * (.INFO) International http://www.nic.info/info/idn - * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf - * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran - * (.IS) Iceland http://www.isnic.is/domain/rules.php - * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html - * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf - * (.MD) Moldova http://www.register.md/ - * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html - * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.NU) Niue http://www.worldnames.net/ - * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 - * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php - * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf - * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp - * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); - * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html - * (.RS) Serbia http://www.iana.org/domains/idn-tables/tables/rs_sr-rs_1.0.pdf - * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html - * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en - * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf - * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html - * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf - * (.TR) Turkey https://www.nic.tr/index.php - * (.UA) Ukraine http://www.iana.org/domains/idn-tables/tables/ua_cyrl_1.2.html - * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html - * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction - * - * @var array - */ - protected $_validIdns = array( - 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), - 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'), - 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'), - 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'), - 'BIZ' => 'Zend/Validate/Hostname/Biz.php', - 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'), - 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'CA' => array(1 => '/^[\x{002d}0-9a-zàâæçéèêëîïôœùûüÿ\x{00E0}\x{00E2}\x{00E7}\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{00EE}\x{00EF}\x{00F4}\x{00F9}\x{00FB}\x{00FC}\x{00E6}\x{0153}\x{00FF}]{1,63}$/iu'), - 'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'), - 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), - 'CL' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), - 'CN' => 'Zend/Validate/Hostname/Cn.php', - 'COM' => 'Zend/Validate/Hostname/Com.php', - 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťßţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'DK' => array(1 => '/^[\x{002d}0-9a-zäéöüæøå]{1,63}$/iu'), - 'ES' => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'), - 'EU' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ὼώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ῒΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'), - 'FI' => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'), - 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'), - 'HK' => 'Zend/Validate/Hostname/Cn.php', - 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'), - 'IL' => array(1 => '/^[\x{002d}0-9\x{05D0}-\x{05EA}]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-z]{1,63}$/i'), - 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', - 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), - 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'IS' => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'), - 'IT' => array(1 => '/^[\x{002d}0-9a-zàâäèéêëìîïòôöùûüæœçÿß-]{1,63}$/iu'), - 'JP' => 'Zend/Validate/Hostname/Jp.php', - 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'), - 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), - 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'), - 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'), - 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'), - 'NET' => 'Zend/Validate/Hostname/Com.php', - 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'NU' => 'Zend/Validate/Hostname/Com.php', - 'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'), - 'PE' => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'), - 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', - 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', - 11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu', - 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', - 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', - 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', - 15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', - 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', - 18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', - 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', - 20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', - 21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', - 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', - 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', - 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', - 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', - 26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', - 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', - 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', - 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', - 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', - 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'), - 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'), - 'PT' => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'), - 'RS' => array(1 => '/^[\x{002D}\x{0030}-\x{0039}\x{0061}-\x{007A}\x{0107}\x{010D}\x{0111}\x{0161}\x{017E}]{1,63}$/iu)'), - 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), - 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'), - 'SE' => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'), - 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), - 'SI' => array( - 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu'), - 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), - 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), - 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), - 'TW' => 'Zend/Validate/Hostname/Cn.php', - 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'), - 'UA' => array(1 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџґӂʼ]{1,63}$/iu'), - 'VE' => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'), - 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'), - 'мон' => array(1 => '/^[\x{002d}0-9\x{0430}-\x{044F}]{1,63}$/iu'), - 'срб' => array(1 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu'), - 'сайт' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), - 'онлайн' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), - '中国' => 'Zend/Validate/Hostname/Cn.php', - '中國' => 'Zend/Validate/Hostname/Cn.php', - 'ලංකා' => array(1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'), - '香港' => 'Zend/Validate/Hostname/Cn.php', - '台湾' => 'Zend/Validate/Hostname/Cn.php', - '台灣' => 'Zend/Validate/Hostname/Cn.php', - 'امارات' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'الاردن' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'السعودية' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'ไทย' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), - 'рф' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), - 'تونس' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'مصر' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'இலங்கை' => array(1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'), - 'فلسطين' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - 'شبكة' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), - ); - - protected $_idnLength = array( - 'BIZ' => array(5 => 17, 11 => 15, 12 => 20), - 'CN' => array(1 => 20), - 'COM' => array(3 => 17, 5 => 20), - 'HK' => array(1 => 15), - 'INFO'=> array(4 => 17), - 'KR' => array(1 => 17), - 'NET' => array(3 => 17, 5 => 20), - 'ORG' => array(6 => 17), - 'TW' => array(1 => 20), - 'ایران' => array(1 => 30), - '中国' => array(1 => 20), - '公司' => array(1 => 20), - '网络' => array(1 => 20), - ); - - protected $_options = array( - 'allow' => self::ALLOW_DNS, - 'idn' => true, - 'tld' => true, - 'ip' => null - ); - - /** - * Sets validator options - * - * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs - * @param array $options Validator options - */ - public function __construct($options = array()) - { - if ($options instanceof Zend_Config) { - $options = $options->toArray(); - } else if (!is_array($options)) { - $options = func_get_args(); - $temp['allow'] = array_shift($options); - if (!empty($options)) { - $temp['idn'] = array_shift($options); - } - - if (!empty($options)) { - $temp['tld'] = array_shift($options); - } - - if (!empty($options)) { - $temp['ip'] = array_shift($options); - } - - $options = $temp; - } - - $options += $this->_options; - $this->setOptions($options); - } - - /** - * Returns all set options - * - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Sets the options for this validator - * - * @param array $options - * @return $this - */ - public function setOptions($options) - { - if (array_key_exists('allow', $options)) { - $this->setAllow($options['allow']); - } - - if (array_key_exists('idn', $options)) { - $this->setValidateIdn($options['idn']); - } - - if (array_key_exists('tld', $options)) { - $this->setValidateTld($options['tld']); - } - - if (array_key_exists('ip', $options)) { - $this->setIpValidator($options['ip']); - } - - return $this; - } - - /** - * Returns the set ip validator - * - * @return Zend_Validate_Ip - */ - public function getIpValidator() - { - return $this->_options['ip']; - } - - /** - * @param Zend_Validate_Ip $ipValidator OPTIONAL - * @return $this - */ - public function setIpValidator(Zend_Validate_Ip $ipValidator = null) - { - if ($ipValidator === null) { - $ipValidator = new Zend_Validate_Ip(); - } - - $this->_options['ip'] = $ipValidator; - return $this; - } - - /** - * Returns the allow option - * - * @return integer - */ - public function getAllow() - { - return $this->_options['allow']; - } - - /** - * Sets the allow option - * - * @param integer $allow - * @return $this Provides a fluent interface - */ - public function setAllow($allow) - { - $this->_options['allow'] = $allow; - return $this; - } - - /** - * Returns the set idn option - * - * @return boolean - */ - public function getValidateIdn() - { - return $this->_options['idn']; - } - - /** - * Set whether IDN domains are validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them - * @return $this - */ - public function setValidateIdn ($allowed) - { - $this->_options['idn'] = (bool) $allowed; - return $this; - } - - /** - * Returns the set tld option - * - * @return boolean - */ - public function getValidateTld() - { - return $this->_options['tld']; - } - - /** - * Set whether the TLD element of a hostname is validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them - * @return $this - */ - public function setValidateTld ($allowed) - { - $this->_options['tld'] = (bool) $allowed; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the $value is a valid hostname with respect to the current allow option - * - * @param string $value - * @throws Zend_Validate_Exception if a fatal error occurs for validation process - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->_error(self::INVALID); - return false; - } - - $this->_setValue($value); - // Check input against IP address schema - if (preg_match('/^[0-9a-f:.]*$/i', $value) && - $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { - if (!($this->_options['allow'] & self::ALLOW_IP)) { - $this->_error(self::IP_ADDRESS_NOT_ALLOWED); - return false; - } else { - return true; - } - } - - // RFC3986 3.2.2 states: - // - // The rightmost domain label of a fully qualified domain name - // in DNS may be followed by a single "." and should be if it is - // necessary to distinguish between the complete domain name and - // some local domain. - // - // (see ZF-6363) - - // Local hostnames are allowed to be partitial (ending '.') - if ($this->_options['allow'] & self::ALLOW_LOCAL) { - if (substr($value, -1) === '.') { - $value = substr($value, 0, -1); - if (substr($value, -1) === '.') { - // Empty hostnames (ending '..') are not allowed - $this->_error(self::INVALID_LOCAL_NAME); - return false; - } - } - } - - $domainParts = explode('.', $value); - - // Prevent partitial IP V4 adresses (ending '.') - if ((count($domainParts) == 4) && preg_match('/^[0-9.a-e:.]*$/i', $value) && - $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { - $this->_error(self::INVALID_LOCAL_NAME); - } - - // Check input against DNS hostname schema - if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) { - $status = false; - - $origenc = PHP_VERSION_ID < 50600 - ? iconv_get_encoding('internal_encoding') - : ini_get('default_charset'); - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('internal_encoding', 'UTF-8'); - } else { - ini_set('default_charset', 'UTF-8'); - } - do { - // First check TLD - $matches = array(); - if (preg_match('/([^.]{2,63})$/iu', end($domainParts), $matches) - || (array_key_exists(end($domainParts), $this->_validIdns))) { - reset($domainParts); - - // Hostname characters are: *(label dot)(label dot label); max 254 chars - // label: id-prefix [*ldh{61} id-prefix]; max 63 chars - // id-prefix: alpha / digit - // ldh: alpha / digit / dash - - // Match TLD against known list - $this->_tld = $matches[1]; - if ($this->_options['tld']) { - if (!in_array(strtolower($this->_tld), $this->_validTlds) - && !in_array($this->_tld, $this->_validTlds) - && !$this->checkDnsRecords($this->_value) - ) { - $this->_error(self::UNKNOWN_TLD); - $status = false; - break; - } - // We have already validated that the TLD is fine. We don't want it to go through the below - // checks as new UTF-8 TLDs will incorrectly fail if there is no IDN regex for it. - array_pop($domainParts); - } - - /** - * Match against IDN hostnames - * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames - * @see Zend_Validate_Hostname_Interface - */ - $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i'); - if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) { - if (is_string($this->_validIdns[strtoupper($this->_tld)])) { - $regexChars += include($this->_validIdns[strtoupper($this->_tld)]); - } else { - $regexChars += $this->_validIdns[strtoupper($this->_tld)]; - } - } - - // Check each hostname part - $check = 0; - foreach ($domainParts as $domainPart) { - // If some domain part is empty (i.e. zend..com), it's invalid - if (empty($domainPart) && $domainPart !== '0') { - $this->_error(self::INVALID_HOSTNAME); - return false; - } - - // Decode Punycode domainnames to IDN - if (strpos($domainPart, 'xn--') === 0) { - $domainPart = $this->decodePunycode(substr($domainPart, 4)); - if ($domainPart === false) { - return false; - } - } - - // Check dash (-) does not start, end or appear in 3rd and 4th positions - if ((strpos($domainPart, '-') === 0) - || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3)) - || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) { - $this->_error(self::INVALID_DASH); - $status = false; - break 2; - } - - // Check each domain part - $checked = false; - foreach($regexChars as $regexKey => $regexChar) { - $status = preg_match($regexChar, $domainPart); - if ($status > 0) { - $length = 63; - if (array_key_exists(strtoupper($this->_tld), $this->_idnLength) - && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) { - $length = $this->_idnLength[strtoupper($this->_tld)]; - } - - if (iconv_strlen($domainPart, 'UTF-8') > $length) { - $this->_error(self::INVALID_HOSTNAME); - } else { - $checked = true; - break; - } - } - } - - if ($checked) { - ++$check; - } - } - - // If one of the labels doesn't match, the hostname is invalid - if ($check !== count($domainParts)) { - $this->_error(self::INVALID_HOSTNAME_SCHEMA); - $status = false; - } - } else { - // Hostname not long enough - $this->_error(self::UNDECIPHERABLE_TLD); - $status = false; - } - } while (false); - - if (PHP_VERSION_ID < 50600) { - iconv_set_encoding('internal_encoding', $origenc); - } else { - ini_set('default_charset', $origenc); - } - // If the input passes as an Internet domain name, and domain names are allowed, then the hostname - // passes validation - if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) { - return true; - } - } else if ($this->_options['allow'] & self::ALLOW_DNS) { - $this->_error(self::INVALID_HOSTNAME); - } - - // Check for URI Syntax (RFC3986) - if ($this->_options['allow'] & self::ALLOW_URI) { - if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { - return true; - } else { - $this->_error(self::INVALID_URI); - } - } - - // Check input against local network name schema; last chance to pass validation - $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; - $status = @preg_match($regexLocal, $value); - - // If the input passes as a local network name, and local network names are allowed, then the - // hostname passes validation - $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL; - if ($status && $allowLocal) { - return true; - } - - // If the input does not pass as a local network name, add a message - if (!$status) { - $this->_error(self::INVALID_LOCAL_NAME); - } - - // If local network names are not allowed, add a message - if ($status && !$allowLocal) { - $this->_error(self::LOCAL_NAME_NOT_ALLOWED); - } - - return false; - } - - /** - * Decodes a punycode encoded string to it's original utf8 string - * In case of a decoding failure the original string is returned - * - * @param string $encoded Punycode encoded string to decode - * @return string - */ - protected function decodePunycode($encoded) - { - if (!preg_match('/^[a-z0-9-]+$/i', $encoded)) { - // no punycode encoded string - $this->_error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - - $decoded = array(); - $separator = strrpos($encoded, '-'); - if ($separator > 0) { - for ($x = 0; $x < $separator; ++$x) { - // prepare decoding matrix - $decoded[] = ord($encoded[$x]); - } - } - - $lengthd = count($decoded); - $lengthe = strlen($encoded); - - // decoding - $init = true; - $base = 72; - $index = 0; - $char = 0x80; - - for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { - for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) { - $hex = ord($encoded[$indexe++]); - $digit = ($hex - 48 < 10) ? $hex - 22 - : (($hex - 65 < 26) ? $hex - 65 - : (($hex - 97 < 26) ? $hex - 97 - : 36)); - - $index += $digit * $pos; - $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); - if ($digit < $tag) { - break; - } - - $pos = (int) ($pos * (36 - $tag)); - } - - $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2)); - $delta += intval($delta / ($lengthd + 1)); - for ($key = 0; $delta > 910 / 2; $key += 36) { - $delta = intval($delta / 35); - } - - $base = intval($key + 36 * $delta / ($delta + 38)); - $init = false; - $char += (int) ($index / ($lengthd + 1)); - $index %= ($lengthd + 1); - if ($lengthd > 0) { - for ($i = $lengthd; $i > $index; $i--) { - $decoded[$i] = $decoded[($i - 1)]; - } - } - - $decoded[$index++] = $char; - } - - // convert decoded ucs4 to utf8 string - foreach ($decoded as $key => $value) { - if ($value < 128) { - $decoded[$key] = chr($value); - } elseif ($value < (1 << 11)) { - $decoded[$key] = chr(192 + ($value >> 6)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < (1 << 16)) { - $decoded[$key] = chr(224 + ($value >> 12)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < (1 << 21)) { - $decoded[$key] = chr(240 + ($value >> 18)); - $decoded[$key] .= chr(128 + (($value >> 12) & 63)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } else { - $this->_error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - } - - return implode($decoded); - } - - /** - * Returns true if any DNS records corresponding to a given Internet host are found. - * Returns false if no DNS records were found or if an error occurred. - * Checks A-Record. - * - * @param string $hostName - * - * @return bool - */ - protected function checkDnsRecords($hostName) - { - if (function_exists('idn_to_ascii')) { - if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) { - $toAscii = idn_to_ascii($hostName, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); - } else { - $toAscii = idn_to_ascii($hostName); - } - $result = checkdnsrr($toAscii, 'A'); - } else { - $idn = new Net_IDNA2(); - $result = checkdnsrr($idn->encode($hostName), 'A'); - } - - return $result; - } -}