diff --git a/.gitattributes b/.gitattributes index ff0ff58..d5966aa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,4 @@ .gitignore export-ignore .gitlab-ci.yml export-ignore .travis.yml export-ignore -tests/ export-ignore -CI/ export-ignore -Application/ export-ignore -DCO export-ignore \ No newline at end of file +test/ export-ignore \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3a0ba0..8f13c09 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,8 @@ before_script: # Install dependencies -- bash CI/docker_install.sh > /dev/null +- set -xe +- apt-get update -yqq +- apt-get install git zip unzip -yqq stages: - build @@ -8,23 +10,13 @@ stages: - deploy build:composer: - image: php:7.1 + image: php:7.2 stage: build script: - curl -sS https://getcomposer.org/installer | php - php composer.phar install cache: - key: "$CI_BUILD_REF/$CI_BUILD_REF_NAME" - paths: - - vendor/ - -test:7.0: - stage: test - image: php:7.0 - script: - - vendor/bin/phpunit -c tests/phpunit.xml --coverage-text - cache: - key: "$CI_BUILD_REF/$CI_BUILD_REF_NAME" + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" paths: - vendor/ @@ -32,25 +24,59 @@ test:7.1: stage: test image: php:7.1 script: - - vendor/bin/phpunit -c tests/phpunit.xml --coverage-text + - vendor/bin/phpunit -c test/phpunit.xml cache: - key: "$CI_BUILD_REF/$CI_BUILD_REF_NAME" + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" + paths: + - vendor + +test:7.2: + stage: test + image: php:7.2 + script: + - vendor/bin/phpunit -c test/phpunit.xml + cache: + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" paths: - vendor/ +test:7.3: + stage: test + image: php:7.3 + script: + - vendor/bin/phpunit -c test/phpunit.xml + cache: + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" + paths: + - vendor/ + +test:coverage: + stage: test + image: php:7.2 + script: + - pecl install xdebug + - docker-php-ext-enable xdebug + - vendor/bin/phpunit -c test/phpunit.xml --coverage-text + cache: + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" + paths: + - vendor/ + release: stage: deploy - image: php:7.1 + image: php:7.2 only: - master script: - - vendor/bin/phpunit -c tests/phpunit.xml --coverage-text + - pecl install xdebug + - docker-php-ext-enable xdebug + - vendor/bin/phpunit -c test/phpunit.xml --coverage-text artifacts: name: "${CI_BUILD_NAME}_${CI_BUILD_REF_NAME}" paths: - build/ expire_in: 3 weeks cache: - key: "$CI_BUILD_REF/$CI_BUILD_REF_NAME" + key: "$CI_BUILD_REF_$CI_BUILD_REF_NAME" paths: - vendor/ \ No newline at end of file diff --git a/.htaccess b/.htaccess deleted file mode 100644 index e25cb61..0000000 --- a/.htaccess +++ /dev/null @@ -1,4 +0,0 @@ -RewriteEngine On -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule (.*) index.php?path=$1 [QSA,L] diff --git a/.travis.yml b/.travis.yml index ec2a8ae..4930ba4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,11 @@ language: php php: - 7.1 - - 7 + - 7.2 + - 7.3 script: - - php vendor/bin/phpunit -v -c tests/phpunit.xml --coverage-text + - php vendor/bin/phpunit -v -c test/phpunit.xml --coverage-text before_script: - composer install diff --git a/CI/docker_install.sh b/CI/docker_install.sh deleted file mode 100644 index f1c4229..0000000 --- a/CI/docker_install.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# We need to install dependencies only for Docker -[[ ! -e /.dockerenv ]] && [[ ! -e /.dockerinit ]] && exit 0 - -set -xe - -# Install git (the php image doesn't have it) which is required by composer -apt-get update -yqq -apt-get install git zip unzip -yqq - -# Install xdebug -pecl install xdebug -docker-php-ext-enable xdebug - -# Install mysql driver -# Here you can install any other extension that you need -docker-php-ext-install pdo_mysql \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index a9a9e00..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,25 +0,0 @@ -# Contributing to FuzeWorks - -As an open source project, FuzeWorks welcomes contributions of many forms. - -## Bug reporting - -Please report [bugs on Gitlab][1]. - -[1]: http://git.techfuze.net/fuzeworks/core/issues/new - -## Patches submission - -Patches are welcome as [merge requests on Gitlab][2]. Please include a -Signed-off-by tag. Note that by submitting patches with the Signed-off-by -tag, you are giving permission to license the patch as GPLv3-or-later. See -[the DCO file][3] for details. - -[2]: http://git.techfuze.net/fuzeworks/core/merge_requests/new -[3]: http://git.techfuze.net/fuzeworks/core/blob/master/DCO - -## More information - -You can find more information on our website: - -https://techfuze.net/fuzeworks/ \ No newline at end of file diff --git a/DCO b/DCO deleted file mode 100644 index 9b6f3af..0000000 --- a/DCO +++ /dev/null @@ -1,45 +0,0 @@ -If you would like to make a contribution to FuzeWorks, please -certify to the following: -*** -FuzeWorks Developer's Certificate of Origin. Version 1.0 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I have the - right to submit it under the license of "GNU General Public License or - any later version" ("GPLv3-or-later"); or - -(b) The contribution is based upon previous work that, to the best of my - knowledge, is covered under an appropriate open source license and I have - the right under that license to submit that work with modifications, - whether created in whole or in part by me, under GPLv3-or-later; or - -(c) The contribution was provided directly to me by some other person who - certified (a) or (b) and I have not modified it. - -(d) I understand and agree that this project and the contribution are public - and that a record of the contribution (including all metadata and - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - FuzeWorks's policies and the requirements of the GPLv3-or-later where - they are relevant. - -(e) I am granting this work to this project under the terms of the - GPLv3-or-later. - - http://www.gnu.org/licenses/gpl-3.0.html - -*** -*** -And please confirm your certification to the above by adding the following -line to your patch: - - Signed-off-by: Jane Developer - -using your real name (sorry, no pseudonyms or anonymous contributions). - -If you are a developer who is authorized to contribute to FuzeWorks on -behalf of your employer, then please use your corporate email address in the -Signed-off-by tag. If not, then please use a personal email address. - - diff --git a/LICENSE b/LICENSE index 99fb12a..82fedfb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,185 +1,21 @@ -GNU GENERAL PUBLIC LICENSE -Version 3, 29 June 2007 - -Copyright (C) 2007 Free Software Foundation, Inc. - -Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - -Preamble -The GNU General Public License is a free, copyleft license for software and other kinds of works. - -The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. - -Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and modification follow. - -TERMS AND CONDITIONS -0. Definitions. -"This License" refers to version 3 of the GNU General Public License. - -"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. - -"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. - -To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. - -A "covered work" means either the unmodified Program or a work based on the Program. - -To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. - -To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. - -An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. - -1. Source Code. -The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. - -A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. - -The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. - -The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same work. - -2. Basic Permissions. -All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - -3. Protecting Users' Legal Rights From Anti-Circumvention Law. -No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. - -4. Conveying Verbatim Copies. -You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. - -5. Conveying Modified Source Versions. -You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: - -a) The work must carry prominent notices stating that you modified it, and giving a relevant date. -b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". -c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. -d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. -A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. - -6. Conveying Non-Source Forms. -You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: - -a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. -b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. -c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. -d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. -e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. -A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. - -A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. - -"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). - -The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. - -Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. - -7. Additional Terms. -"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: - -a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or -b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or -c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or -d) Limiting the use for publicity purposes of names of licensors or authors of the material; or -e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or -f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. -All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. - -8. Termination. -You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. - -9. Acceptance Not Required for Having Copies. -You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. - -10. Automatic Licensing of Downstream Recipients. -Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. - -An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. - -11. Patents. -A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". - -A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. - -In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. - -A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. - -12. No Surrender of Others' Freedom. -If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - -13. Use with the GNU Affero General Public License. -Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. - -14. Revised Versions of this License. -The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. - -If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. - -Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. - -15. Disclaimer of Warranty. -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -16. Limitation of Liability. -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -17. Interpretation of Sections 15 and 16. -If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. - -END OF TERMS AND CONDITIONS \ No newline at end of file +MIT License + +Copyright (c) 2013-2019 TechFuze + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index bf78667..06664c5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -FuzeWorks - Readme [![build status](http://10.0.0.32/fuzeworks/core/badges/master/build.svg)](http://10.0.0.32/fuzeworks/core/commits/master) +FuzeWorks - Readme [![pipeline status](http://git.i15.nl/fuzeworks/core/badges/development/pipeline.svg)](http://git.i15.nl/fuzeworks/core/commits/development) [![coverage report](http://git.i15.nl/fuzeworks/core/badges/development/coverage.svg)](http://git.i15.nl/fuzeworks/core/commits/development) =================== -Version 1.0.0-DEV +Version 1.2.0 A versatile PHP Framework built to perform. @@ -27,24 +27,32 @@ For full copyright information, please see ./doc/copyright.html License ------- -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License version 3, as published by the -Free Software Foundation. +MIT License -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -You should have received a copy of the GNU General Public License -along with this program. If not, see . +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. Licensing of current contributions ---------------------------------- -Beginning on 2015-08-26, new contributions to this codebase are all licensed -under terms compatible with GPLv3-or-later. FuzeWorks is currently -transitioning older code to GPLv3-or-later, but work is not yet complete. +Beginning on 2018-04-17, new contributions to this codebase are all licensed +under terms compatible with the MIT license. FuzeWorks is currently +transitioning older code to the MIT License, but work is not yet complete. Enjoy! ------ diff --git a/composer.json b/composer.json index 03a23fd..6994ba4 100644 --- a/composer.json +++ b/composer.json @@ -2,11 +2,11 @@ "name": "fuzeworks/core", "description": "FuzeWorks Framework Core", "homepage": "https://techfuze.net/fuzeworks", - "license": ["GPL-3.0"], + "license": ["MIT"], "authors": [ { - "name": "Abel Hoogeveen", - "homepage": "https://myfuze.net" + "name": "TechFuze", + "homepage": "https://techfuze.net" }, { "name": "FuzeWorks Community", @@ -14,25 +14,16 @@ } ], "require": { - "php": ">=7.0.0", - "ext-curl": "*", - "ext-json": "*" - }, - "suggest": { - "smarty/smarty": "Allows using Smarty in templates", - "latte/latte": "Allows using Latte in templates", - "tracy/tracy": "Allows for extensive debugging" + "php": ">=7.1.0", + "psr/log": "1.1.0" }, "require-dev": { - "phpunit/phpunit": "6.2.*", - "mikey179/vfsStream": "1.1.*", - "smarty/smarty": "3.1.*", - "latte/latte": "2.4.*", - "tracy/tracy": "2.4.*" + "phpunit/phpunit": "^7", + "mikey179/vfsstream": "1.1.*" }, "autoload": { "psr-4": { "FuzeWorks\\": "src/FuzeWorks/" } } -} \ No newline at end of file +} diff --git a/src/Config/config.cache.php b/src/Config/config.cache.php deleted file mode 100644 index 352820f..0000000 --- a/src/Config/config.cache.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'cache_query_string' => false, - 'memcached' => array( - 'default' => array( - 'hostname' => '127.0.0.1', - 'port' => '11211', - 'weight' => '1', - ) - ), - 'redis' => array( - '' => '' - ) -); \ No newline at end of file diff --git a/src/Config/config.contact.php b/src/Config/config.contact.php deleted file mode 100644 index 39549c6..0000000 --- a/src/Config/config.contact.php +++ /dev/null @@ -1,42 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'contact_email' => '', - 'contact_name' => '', - 'contact_adress' => '', - 'contact_phone' => '', - 'contact_postal_code' => '', - 'contact_region' => '', - 'contact_country' => '', - 'contact_city' => '', -); diff --git a/src/Config/config.core.php b/src/Config/config.core.php index 06070d0..d3611b5 100644 --- a/src/Config/config.core.php +++ b/src/Config/config.core.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 1.1.1 * - * @version Version 1.1.1 + * @version Version 1.2.0 */ return array( diff --git a/src/Config/config.database.php b/src/Config/config.database.php deleted file mode 100644 index eaf3da7..0000000 --- a/src/Config/config.database.php +++ /dev/null @@ -1,63 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'active_group' => 'default', - 'query_builder' => true, - 'databases' => array( - - 'default' => array( - 'dsn' => '', - 'hostname' => '', - 'username' => '', - 'password' => '', - 'database' => '', - 'dbdriver' => '', - 'subdriver'=> '', - 'dbprefix' => '', - 'pconnect' => FALSE, - 'db_debug' => FALSE, - 'cache_on' => FALSE, - 'char_set' => 'utf8', - 'dbcollat' => 'utf8_general_ci', - 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, - 'failover' => array(), - ), - - - ), -); - - diff --git a/src/Config/config.encryption.php b/src/Config/config.encryption.php deleted file mode 100644 index 56e72ef..0000000 --- a/src/Config/config.encryption.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'encryption_key' => '', -); diff --git a/src/Config/config.error.php b/src/Config/config.error.php index 3b0bd5f..da5bc45 100644 --- a/src/Config/config.error.php +++ b/src/Config/config.error.php @@ -1,37 +1,43 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 1.1.1 * - * @version Version 1.1.1 + * @version Version 1.2.0 */ return array( - 'error_reporting' => true, - 'log_to_file' => false, - 'logger_template' => 'logger_default', + 'fuzeworks_error_reporting' => true, + 'php_error_reporting' => false, + 'log_errors_to_file' => true, + 'log_last_request_to_file' => false, + 'logger_template' => 'logger_cli', ); \ No newline at end of file diff --git a/src/Config/config.main.php b/src/Config/config.main.php deleted file mode 100644 index 6799127..0000000 --- a/src/Config/config.main.php +++ /dev/null @@ -1,89 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'base_url' => '', - 'index_page' => 'index.php', - 'server_name' => '', - - 'administrator_mail' => '', - - 'default_controller' => 'standard', - 'default_function' => 'index', - 'application_prefix' => 'MY_', - - 'charset' => 'UTF-8', - 'language' => 'english', - - /* - |-------------------------------------------------------------------------- - | Cookie Related Variables - |-------------------------------------------------------------------------- - | - | 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions - | 'cookie_domain' = Set to .your-domain.com for site-wide cookies - | 'cookie_path' = Typically will be a forward slash - | 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. - | 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) - | - | Note: These settings (with the exception of 'cookie_prefix' and - | 'cookie_httponly') will also affect sessions. - | - */ - 'cookie_prefix' => '', - 'cookie_domain' => '', - 'cookie_path' => '/', - 'cookie_secure' => FALSE, - 'cookie_httponly' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Output Compression - |-------------------------------------------------------------------------- - | - | Enables Gzip output compression for faster page loads. When enabled, - | the output class will test whether your server supports Gzip. - | Even if it does, however, not all browsers support compression - | so enable only if you are reasonably sure your visitors can handle it. - | - | Only used if zlib.output_compression is turned off in your php.ini. - | Please do not use it together with httpd-level output compression. - | - | VERY IMPORTANT: If you are getting a blank page when compression is enabled it - | means you are prematurely outputting something to your browser. It could - | even be a line of whitespace at the end of one of your scripts. For - | compression to work, nothing can be sent before the output buffer is called - | by the output class. Do not 'echo' any values with compression enabled. - | - */ - 'compress_output' => FALSE, -); diff --git a/src/Config/config.mimes.php b/src/Config/config.mimes.php deleted file mode 100644 index f83d854..0000000 --- a/src/Config/config.mimes.php +++ /dev/null @@ -1,196 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -/* -| ------------------------------------------------------------------- -| MIME TYPES -| ------------------------------------------------------------------- -| This file contains an array of mime types. It is used by the -| Upload class to help identify allowed file types. -| -*/ -return array( - 'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'), - 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'), - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'), - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'), - 'ai' => array('application/pdf', 'application/postscript'), - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'), - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'), - 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'), - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'), - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => array('application/x-javascript', 'text/plain'), - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'z' => 'application/x-compress', - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), - 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), - 'aif' => array('audio/x-aiff', 'audio/aiff'), - 'aiff' => array('audio/x-aiff', 'audio/aiff'), - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), - 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'png' => array('image/png', 'image/x-png'), - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => array('text/css', 'text/plain'), - 'html' => array('text/html', 'text/plain'), - 'htm' => array('text/html', 'text/plain'), - 'shtml' => array('text/html', 'text/plain'), - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => array('application/xml', 'text/xml', 'text/plain'), - 'xsl' => array('application/xml', 'text/xsl', 'text/xml'), - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'), - 'movie' => 'video/x-sgi-movie', - 'doc' => array('application/msword', 'application/vnd.ms-office'), - 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'), - 'dot' => array('application/msword', 'application/vnd.ms-office'), - 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'), - 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'), - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => array('application/json', 'text/json'), - 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'), - 'p10' => array('application/x-pkcs10', 'application/pkcs10'), - 'p12' => 'application/x-pkcs12', - 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), - 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'), - 'crl' => array('application/pkix-crl', 'application/pkcs-crl'), - 'der' => 'application/x-x509-ca-cert', - 'kdb' => 'application/octet-stream', - 'pgp' => 'application/pgp', - 'gpg' => 'application/gpg-keys', - 'sst' => 'application/octet-stream', - 'csr' => 'application/octet-stream', - 'rsa' => 'application/x-pkcs7', - 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), - '3g2' => 'video/3gpp2', - '3gp' => array('video/3gp', 'video/3gpp'), - 'mp4' => 'video/mp4', - 'm4a' => 'audio/x-m4a', - 'f4v' => array('video/mp4', 'video/x-f4v'), - 'flv' => 'video/x-flv', - 'webm' => 'video/webm', - 'aac' => 'audio/x-acc', - 'm4u' => 'application/vnd.mpegurl', - 'm3u' => 'text/plain', - 'xspf' => 'application/xspf+xml', - 'vlc' => 'application/videolan', - 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'), - 'au' => 'audio/x-au', - 'ac3' => 'audio/ac3', - 'flac' => 'audio/x-flac', - 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), - 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), - 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), - 'ics' => 'text/calendar', - 'ical' => 'text/calendar', - 'zsh' => 'text/x-scriptzsh', - '7zip' => array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), - 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), - 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), - 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), - 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), - 'vcf' => 'text/x-vcard', - 'srt' => array('text/srt', 'text/plain'), - 'vtt' => array('text/vtt', 'text/plain'), - 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') -); diff --git a/src/Config/config.plugins.php b/src/Config/config.plugins.php index 602a3a2..02fbdce 100644 --- a/src/Config/config.plugins.php +++ b/src/Config/config.plugins.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 1.1.4 * - * @version Version 1.1.4 + * @version Version 1.2.0 */ /** diff --git a/src/Config/config.routes.php b/src/Config/config.routes.php deleted file mode 100644 index f736b58..0000000 --- a/src/Config/config.routes.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.4 - */ - -/** - * Possible values: - * Default callable: Adds a route that changes the URL structure. Sends all matches to the defaultCallable router - * 'routingString' - * - * Custom callable: Adds a route that sends all matches to the provided callable. Allows user to replace defaultCallable - * 'routingString' => array('callable' => array(CALLABLE)) - * - * Dynamic rewrite: Adds a route that rewrites an URL to a specific controller and method configuration, using a callable. The callable can dynamically determine which page to load. - * 'routingString' => CALLABLE - * - * Static rewrite: Adds a route that rewrites and URL to a specific controller and method using a fixed route. This allows for pre-determined rewrites of pages. - * 'routingString' => 'standard/index' - * - * Example routingString: '/^(?P.*?)(|\/(?P.*?)(|\/(?P.*?)))$/' - */ -return array( -); diff --git a/src/Config/config.routing.php b/src/Config/config.routing.php deleted file mode 100644 index df14674..0000000 --- a/src/Config/config.routing.php +++ /dev/null @@ -1,131 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - - /* - |-------------------------------------------------------------------------- - | Enable Query Strings - |-------------------------------------------------------------------------- - | - | By default CodeIgniter uses search-engine friendly segment based URLs: - | example.com/who/what/where/ - | - | By default CodeIgniter enables access to the $_GET array. If for some - | reason you would like to disable it, set 'allow_get_array' to FALSE. - | - | You can optionally enable standard query string based URLs: - | example.com?who=me&what=something&where=here - | - | Options are: TRUE or FALSE (boolean) - | - | The other items let you set the query string 'words' that will - | invoke your controllers and its functions: - | example.com/index.php?c=controller&m=function - | - | Please note that some of the helpers won't work as expected when - | this feature is enabled, since CodeIgniter is designed primarily to - | use segment based URLs. - | - */ - 'allow_get_array' => TRUE, - 'enable_query_strings' => FALSE, - 'controller_trigger' => 'c', - 'function_trigger' => 'm', - 'directory_trigger' => 'd', - - - /* - |-------------------------------------------------------------------------- - | Allowed URL Characters - |-------------------------------------------------------------------------- - | - | This lets you specify which characters are permitted within your URLs. - | When someone tries to submit a URL with disallowed characters they will - | get a warning message. - | - | As a security measure you are STRONGLY encouraged to restrict URLs to - | as few characters as possible. By default only these are allowed: a-z 0-9~%.:_- - | - | Leave blank to allow all characters -- but only if you are insane. - | - | The configured value is actually a regular expression character group - | and it will be executed as: ! preg_match('/^[]+$/i - | - | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! - | - */ - 'permitted_uri_chars' => 'a-z 0-9~%.:_\-', - - /* - |-------------------------------------------------------------------------- - | Translate URI Dashes - |-------------------------------------------------------------------------- - | Determines whether dashes in controller & method segments - | should be automatically replaced by underscores. - | - */ - 'translate_uri_dashes' => FALSE, - - /* - |-------------------------------------------------------------------------- - | URI PROTOCOL - |-------------------------------------------------------------------------- - | - | This item determines which server global should be used to retrieve the - | URI string. The default setting of 'REQUEST_URI' works for most servers. - | If your links do not seem to work, try one of the other delicious flavors: - | - | 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] - | 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] - | 'PATH_INFO' Uses $_SERVER['PATH_INFO'] - | - | WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! - */ - 'uri_protocol' => 'REQUEST_URI', - - /* - |-------------------------------------------------------------------------- - | URL suffix - |-------------------------------------------------------------------------- - | - | This option allows you to add a suffix to all URLs generated by CodeIgniter. - | For more information please see the user guide: - | - | https://codeigniter.com/user_guide/general/urls.html - */ - 'url_suffix' => '', - - 'default_controller' => 'standard', - 'default_function' => 'index', - -); diff --git a/src/Config/config.security.php b/src/Config/config.security.php deleted file mode 100644 index d35bfd1..0000000 --- a/src/Config/config.security.php +++ /dev/null @@ -1,102 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - - /* - |-------------------------------------------------------------------------- - | Cross Site Request Forgery - |-------------------------------------------------------------------------- - | Enables a CSRF cookie token to be set. When set to TRUE, token will be - | checked on a submitted form. If you are accepting user data, it is strongly - | recommended CSRF protection be enabled. - | - | 'csrf_token_name' = The token name - | 'csrf_cookie_name' = The cookie name - | 'csrf_expire' = The number in seconds the token should expire. - | 'csrf_regenerate' = Regenerate token on every submission - | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks - */ - 'csrf_protection' => true, - 'csrf_token_name' => 'fw_csrf_token', - 'csrf_cookie_name' => 'fw_csrf_cookie', - 'csrf_expire' => 7200, - 'csrf_regenerate' => TRUE, - 'csrf_exclude_uris' => array(), - - /* - |-------------------------------------------------------------------------- - | Standardize newlines - |-------------------------------------------------------------------------- - | - | Determines whether to standardize newline characters in input data, - | meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value. - | - | This is particularly useful for portability between UNIX-based OSes, - | (usually \n) and Windows (\r\n). - | - */ - 'standardize_newlines' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Global XSS Filtering - |-------------------------------------------------------------------------- - | - | Determines whether the XSS filter is always active when GET, POST or - | COOKIE data is encountered - | - | WARNING: This feature is DEPRECATED and currently available only - | for backwards compatibility purposes! - | - */ - 'global_xss_filtering' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Reverse Proxy IPs - |-------------------------------------------------------------------------- - | - | If your server is behind a reverse proxy, you must whitelist the proxy - | IP addresses from which CodeIgniter should trust headers such as - | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify - | the visitor's IP address. - | - | You can use both an array or a comma-separated list of proxy addresses, - | as well as specifying whole subnets. Here are a few examples: - | - | Comma-separated: '10.0.1.200,192.168.5.0/24' - | Array: array('10.0.1.200', '192.168.5.0/24') - */ - 'proxy_ips' => '' - -); diff --git a/src/Database/DB.php b/src/Database/DB.php deleted file mode 100644 index 1be8fbb..0000000 --- a/src/Database/DB.php +++ /dev/null @@ -1,201 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; -use FuzeWorks\Database; -use FuzeWorks\Exception\DatabaseException; -use FuzeWorks\Core; - -/** - * Initialize the database - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - * - * @param string|string[] $params - * @param bool $query_builder_override - * Determines if query builder should be used or not - */ -function &DB($params = '', $query_builder_override = NULL) -{ - // Load the DB config file if a DSN string wasn't passed - if (is_string($params) && strpos($params, '://') === FALSE) - { - // First retrieve the config file - try { - $config = Factory::getInstance()->config->get('database'); - } catch (ConfigException $e) { - throw new DatabaseException($e->getMessage(), 1); - } - - // Determine if there are actually settings in the config file - if ( ! isset($config->databases) OR count($config->databases) === 0) - { - throw new DatabaseException('No database connection settings were found in the database config file.', 1); - } - - // Define the active group - $active_group = ($params !== '' ? $params : $config->active_group); - - if ( ! isset($active_group)) - { - throw new DatabaseException('You have not specified a database connection group via $active_group in your config.database.php file.', 1); - } - elseif ( ! isset($config->databases[$active_group])) - { - throw new DatabaseException('You have specified an invalid database connection group ('.$active_group.') in your config.database.php file.', 1); - } - - $params = $config->databases[$active_group]; - } - elseif (is_string($params)) - { - /** - * Parse the URL from the DSN string - * Database settings can be passed as discreet - * parameters or as a data source name in the first - * parameter. DSNs must have this prototype: - * $dsn = 'driver://username:password@hostname/database'; - */ - if (($dsn = @parse_url($params)) === FALSE) - { - throw new DatabaseException('Invalid DB Connection String', 1); - } - - $params = array( - 'dbdriver' => $dsn['scheme'], - 'hostname' => isset($dsn['host']) ? rawurldecode($dsn['host']) : '', - 'port' => isset($dsn['port']) ? rawurldecode($dsn['port']) : '', - 'username' => isset($dsn['user']) ? rawurldecode($dsn['user']) : '', - 'password' => isset($dsn['pass']) ? rawurldecode($dsn['pass']) : '', - 'database' => isset($dsn['path']) ? rawurldecode(substr($dsn['path'], 1)) : '' - ); - - // Were additional config items set? - if (isset($dsn['query'])) - { - parse_str($dsn['query'], $extra); - - foreach ($extra as $key => $val) - { - if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL'))) - { - $val = var_export($val, TRUE); - } - - $params[$key] = $val; - } - } - } - - // No DB specified yet? Beat them senseless... - if (empty($params['dbdriver'])) - { - throw new DatabaseException('You have not selected a database type to connect to.', 1); - } - - // Load the DB classes. Note: Since the query builder class is optional - // we need to dynamically create a class that extends proper parent class - // based on whether we're using the query builder class or not. - if ($query_builder_override !== NULL) - { - $query_builder = $query_builder_override; - } - // Backwards compatibility work-around for keeping the - // $active_record config variable working. Should be - // removed in v3.1 - elseif ( ! isset($query_builder) && isset($active_record)) - { - $query_builder = $active_record; - } - - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_driver.php'); - - if ( ! isset($query_builder) OR $query_builder === TRUE) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_query_builder.php'); - if ( ! class_exists('FW_DB', FALSE)) - { - /** - * FW_DB - * - * Acts as an alias for both FW_DB_driver and FW_DB_query_builder. - * - * @see FW_DB_query_builder - * @see FW_DB_driver - */ - class FW_DB extends FW_DB_query_builder { } - } - } - elseif ( ! class_exists('FW_DB', FALSE)) - { - /** - * @ignore - */ - class FW_DB extends FW_DB_driver { } - } - - // Load the DB driver - $driver_file = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$params['dbdriver'].DS.$params['dbdriver'].'_driver.php'; - - if (!file_exists($driver_file)) - { - throw new DatabaseException("Invalid DB Driver", 1); - } - - require_once($driver_file); - - // Instantiate the DB adapter - $driver = 'FW_DB_'.$params['dbdriver'].'_driver'; - $DB = new $driver($params); - - // Check for a subdriver - if ( ! empty($DB->subdriver)) - { - $driver_file = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$DB->dbdriver.DS.'subdrivers'.DS.$DB->dbdriver.'_'.$DB->subdriver.'_driver.php'; - - if (file_exists($driver_file)) - { - require_once($driver_file); - $driver = 'FW_DB_'.$DB->dbdriver.'_'.$DB->subdriver.'_driver'; - $DB = new $driver($params); - } - } - - $DB->initialize(); - return $DB; -} diff --git a/src/Database/DB_cache.php b/src/Database/DB_cache.php deleted file mode 100644 index 8e5daa4..0000000 --- a/src/Database/DB_cache.php +++ /dev/null @@ -1,216 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use Fuzeworks\Factory; -use FuzeWorks\Core; - -/** - * Database Cache Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_Cache { - - /** - * Database object - * - * Allows passing of DB object so that multiple database connections - * and returned DB objects can be supported. - * - * @var object - */ - public $db; - - /** - * The FuzeWorks factory class - * - * @var Fuzeworks\Factory; - */ - private $factory; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object &$db - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - $this->factory = Factory::getInstance(); - $this->factory->helpers->load('file'); - - $this->check_path(); - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Directory Path - * - * @param string $path Path to the cache directory - * @return bool - */ - public function check_path($path = '') - { - $path = ($path === '' ? Core::$tempDir . DS . 'Database' : $path); - - // Add a trailing slash to the path if needed - $path = realpath($path) - ? rtrim(realpath($path), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR - : rtrim($path, '/').'/'; - - if ( ! is_dir($path)) - { - if (!mkdir($path, 0777, false)) - { - Logger::logDebug('DB cache path error: '.$path); - - // If the path is wrong we'll turn off caching - return $this->db->cache_off(); - } - } - - if ( ! Core::isReallyWritable($path)) - { - Logger::logDebug('DB cache dir not writable: '.$path); - - // If the path is not really writable we'll turn off caching - return $this->db->cache_off(); - } - - $this->db->cachedir = $path; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Retrieve a cached query - * - * The URI being requested will become the name of the cache sub-folder. - * An MD5 hash of the SQL statement will become the cache file name. - * - * @param string $sql - * @return string - */ - public function read($sql) - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - $filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql); - - if (FALSE === ($cachedata = @file_get_contents($filepath))) - { - return FALSE; - } - - return unserialize($cachedata); - } - - // -------------------------------------------------------------------- - - /** - * Write a query to a cache file - * - * @param string $sql - * @param object $object - * @return bool - */ - public function write($sql, $object) - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'; - $filename = md5($sql); - - if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750)) - { - return FALSE; - } - - if (write_file($dir_path.$filename, serialize($object)) === FALSE) - { - return FALSE; - } - - chmod($dir_path.$filename, 0640); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Delete cache files within a particular directory - * - * @param string $segment_one - * @param string $segment_two - * @return void - */ - public function delete($segment_one = '', $segment_two = '') - { - if ($segment_one === '') - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - } - - if ($segment_two === '') - { - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - } - - $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'; - delete_files($dir_path, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Delete all existing cache files - * - * @return void - */ - public function delete_all() - { - delete_files($this->db->cachedir, TRUE, TRUE); - } - -} diff --git a/src/Database/DB_driver.php b/src/Database/DB_driver.php deleted file mode 100644 index daee2c0..0000000 --- a/src/Database/DB_driver.php +++ /dev/null @@ -1,1997 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Core; -use FuzeWorks\Logger; -use FuzeWorks\Utf8; -use FuzeWorks\Language; -use FuzeWorks\DatabaseTracyBridge; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Driver Class - * - * This is the platform-independent base DB implementation class. - * This class will not be called directly. Rather, the adapter - * class for the specific database will extend and instantiate it. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_driver { - - /** - * Data Source Name / Connect string - * - * @var string - */ - public $dsn; - - /** - * Username - * - * @var string - */ - public $username; - - /** - * Password - * - * @var string - */ - public $password; - - /** - * Hostname - * - * @var string - */ - public $hostname; - - /** - * Database name - * - * @var string - */ - public $database; - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'mysqli'; - - /** - * Sub-driver - * - * @used-by FW_DB_pdo_driver - * @var string - */ - public $subdriver; - - /** - * Table prefix - * - * @var string - */ - public $dbprefix = ''; - - /** - * Character set - * - * @var string - */ - public $char_set = 'utf8'; - - /** - * Collation - * - * @var string - */ - public $dbcollat = 'utf8_general_ci'; - - /** - * Encryption flag/data - * - * @var mixed - */ - public $encrypt = FALSE; - - /** - * Swap Prefix - * - * @var string - */ - public $swap_pre = ''; - - /** - * Database port - * - * @var int - */ - public $port = ''; - - /** - * Persistent connection flag - * - * @var bool - */ - public $pconnect = FALSE; - - /** - * Connection ID - * - * @var object|resource - */ - public $conn_id = FALSE; - - /** - * Result ID - * - * @var object|resource - */ - public $result_id = FALSE; - - /** - * Debug flag - * - * Whether to display error messages. - * - * @var bool - */ - public $db_debug = TRUE; - - /** - * Benchmark time - * - * @var int - */ - public $benchmark = 0; - - /** - * Executed queries count - * - * @var int - */ - public $query_count = 0; - - /** - * Bind marker - * - * Character used to identify values in a prepared statement. - * - * @var string - */ - public $bind_marker = '?'; - - /** - * Save queries flag - * - * Whether to keep an in-memory history of queries for debugging purposes. - * - * @var bool - */ - public $save_queries = TRUE; - - /** - * Queries list - * - * @see FW_DB_driver::$save_queries - * @var string[] - */ - public $queries = array(); - - /** - * Data of performed queries - * - * @see FW_DB_driver::$save_queries - * @var array - */ - public $query_data = array(); - - /** - * Query times - * - * A list of times that queries took to execute. - * - * @var array - */ - public $query_times = array(); - - /** - * Data cache - * - * An internal generic value cache. - * - * @var array - */ - public $data_cache = array(); - - /** - * Transaction enabled flag - * - * @var bool - */ - public $trans_enabled = TRUE; - - /** - * Strict transaction mode flag - * - * @var bool - */ - public $trans_strict = TRUE; - - /** - * Transaction depth level - * - * @var int - */ - protected $_trans_depth = 0; - - /** - * Transaction status flag - * - * Used with transactions to determine if a rollback should occur. - * - * @var bool - */ - protected $_trans_status = TRUE; - - /** - * Transaction failure flag - * - * Used with transactions to determine if a transaction has failed. - * - * @var bool - */ - protected $_trans_failure = FALSE; - - /** - * Cache On flag - * - * @var bool - */ - public $cache_on = FALSE; - - /** - * Cache directory path - * - * @var bool - */ - public $cachedir = ''; - - /** - * Cache auto-delete flag - * - * @var bool - */ - public $cache_autodel = FALSE; - - /** - * DB Cache object - * - * @see FW_DB_cache - * @var object - */ - public $CACHE; - - /** - * Protect identifiers flag - * - * @var bool - */ - protected $_protect_identifiers = TRUE; - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*'); - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '"'; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " ESCAPE '%s' "; - - /** - * ESCAPE character - * - * @var string - */ - protected $_like_escape_chr = '!'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND(%d)'); - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(*) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - if (is_array($params)) - { - foreach ($params as $key => $val) - { - $this->$key = $val; - } - } - - Logger::log('Database Driver ' . get_class($this) . ' Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initialize Database Settings - * - * @return bool - */ - public function initialize() - { - /* If an established connection is available, then there's - * no need to connect and select the database. - * - * Depending on the database driver, conn_id can be either - * boolean TRUE, a resource or an object. - */ - if ($this->conn_id) - { - return TRUE; - } - - // ---------------------------------------------------------------- - - // Connect to the database and set the connection ID - $this->conn_id = $this->db_connect($this->pconnect); - - // No connection resource? Check if there is a failover else throw an error - if ( ! $this->conn_id) - { - // Check if there is a failover set - if ( ! empty($this->failover) && is_array($this->failover)) - { - // Go over all the failovers - foreach ($this->failover as $failover) - { - // Replace the current settings with those of the failover - foreach ($failover as $key => $val) - { - $this->$key = $val; - } - - // Try to connect - $this->conn_id = $this->db_connect($this->pconnect); - - // If a connection is made break the foreach loop - if ($this->conn_id) - { - break; - } - } - } - - // We still don't have a connection? - if ( ! $this->conn_id) - { - Logger::logError('Unable to connect to the database'); - - if ($this->db_debug) - { - $this->display_error('db_unable_to_connect'); - } - - return FALSE; - } - } - - // Now we set the character set and that's all - return $this->db_set_charset($this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * DB connect - * - * This is just a dummy method that all drivers will override. - * - * @return mixed - */ - public function db_connect() - { - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Persistent database connection - * - * @return mixed - */ - public function db_pconnect() - { - return $this->db_connect(TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout. - * - * This is just a dummy method to allow drivers without such - * functionality to not declare it, while others will override it. - * - * @return void - */ - public function reconnect() - { - } - - // -------------------------------------------------------------------- - - /** - * Select database - * - * This is just a dummy method to allow drivers without such - * functionality to not declare it, while others will override it. - * - * @return bool - */ - public function db_select() - { - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Last error - * - * @return array - */ - public function error() - { - return array('code' => NULL, 'message' => NULL); - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string - * @return bool - */ - public function db_set_charset($charset) - { - if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset)) - { - Logger::logError('Unable to set database connection charset: '.$charset); - - if ($this->db_debug) - { - $this->display_error('db_unable_to_set_charset', $charset); - } - - return FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * The name of the platform in use (mysql, mssql, etc...) - * - * @return string - */ - public function platform() - { - return $this->dbdriver; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * Returns a string containing the version of the database being used. - * Most drivers will override this method. - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if (FALSE === ($sql = $this->_version())) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $query = $this->query($sql)->row(); - return $this->data_cache['version'] = $query->ver; - } - - // -------------------------------------------------------------------- - - /** - * Version number query string - * - * @return string - */ - protected function _version() - { - return 'SELECT VERSION() AS ver'; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * Accepts an SQL string as input and returns a result object upon - * successful execution of a "read" type query. Returns boolean TRUE - * upon successful execution of a "write" type query. Returns boolean - * FALSE upon failure, and if the $db_debug variable is set to TRUE - * will raise an error. - * - * @param string $sql - * @param array $binds = FALSE An array of binding data - * @param bool $return_object = NULL - * @return mixed - */ - public function query($sql, $binds = FALSE, $return_object = NULL) - { - if ($sql === '') - { - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; - } - elseif ( ! is_bool($return_object)) - { - $return_object = ! $this->is_write_type($sql); - } - - // Verify table prefix and replace if necessary - if ($this->dbprefix !== '' && $this->swap_pre !== '' && $this->dbprefix !== $this->swap_pre) - { - $sql = preg_replace('/(\W)'.$this->swap_pre.'(\S+?)/', '\\1'.$this->dbprefix.'\\2', $sql); - } - - // Compile binds if needed - if ($binds !== FALSE) - { - $sql = $this->compile_binds($sql, $binds); - } - - // Is query caching enabled? If the query is a "read type" - // we will load the caching class and return the previously - // cached query if it exists - if ($this->cache_on === TRUE && $return_object === TRUE && $this->_cache_init()) - { - $this->load_rdriver(); - if (FALSE !== ($cache = $this->CACHE->read($sql))) - { - return $cache; - } - } - - // Save the query for debugging - if ($this->save_queries === TRUE) - { - $this->queries[] = $sql; - } - - // Start the Query Timer - $time_start = microtime(TRUE); - - // Run the Query - if (FALSE === ($this->result_id = $this->simple_query($sql))) - { - if ($this->save_queries === TRUE) - { - $this->query_times[] = 0; - $this->query_data[] = array('error' => $this->error(), 'rows' => 0); - } - - // This will trigger a rollback if transactions are being used - if ($this->_trans_depth !== 0) - { - $this->_trans_status = FALSE; - } - - // Grab the error now, as we might run some additional queries before displaying the error - $error = $this->error(); - - if ($this->db_debug) - { - // We call this function in order to roll-back queries - // if transactions are enabled. If we don't call this here - // the error message will trigger an exit, causing the - // transactions to remain in limbo. - while ($this->_trans_depth !== 0) - { - $trans_depth = $this->_trans_depth; - $this->trans_complete(); - if ($trans_depth === $this->_trans_depth) - { - Logger::logError('Database: Failure during an automated transaction commit/rollback!'); - break; - } - } - - // Display errors - return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql)); - } - - return FALSE; - } - - // Stop and aggregate the query time results - $time_end = microtime(TRUE); - $this->benchmark += $time_end - $time_start; - - // Increment the query counter - $this->query_count++; - - // Will we have a result object instantiated? If not - we'll simply return TRUE - if ($return_object !== TRUE) - { - // If caching is enabled we'll auto-cleanup any existing files related to this particular URI - if ($this->cache_on === TRUE && $this->cache_autodel === TRUE && $this->_cache_init()) - { - $this->CACHE->delete(); - } - - return TRUE; - } - - // Load and instantiate the result driver - $driver = $this->load_rdriver(); - $RES = new $driver($this); - - if ($this->save_queries === TRUE) - { - $this->query_times[] = $time_end - $time_start; - $this->query_data[] = array('error' => $this->error(), 'rows' => $RES->num_rows()); - } - - // Is query caching enabled? If so, we'll serialize the - // result object and save it to a cache file. - if ($this->cache_on === TRUE && $this->_cache_init()) - { - // We'll create a new instance of the result object - // only without the platform specific driver since - // we can't use it with cached data (the query result - // resource ID won't be any good once we've cached the - // result object, so we'll have to compile the data - // and save it) - $CR = new FW_DB_result($this); - $CR->result_object = $RES->result_object(); - $CR->result_array = $RES->result_array(); - $CR->num_rows = $RES->num_rows(); - - // Reset these since cached objects can not utilize resource IDs. - $CR->conn_id = NULL; - $CR->result_id = NULL; - - $this->CACHE->write($sql, $CR); - } - - return $RES; - } - - // -------------------------------------------------------------------- - - /** - * Load the result drivers - * - * @return string the name of the result class - */ - public function load_rdriver() - { - $driver = 'FW_DB_'.$this->dbdriver.'_result'; - - if ( ! class_exists($driver, FALSE)) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_result.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$this->dbdriver.DS.$this->dbdriver.'_result.php'); - } - - return $driver; - } - - // -------------------------------------------------------------------- - - /** - * Simple Query - * This is a simplified version of the query() function. Internally - * we only use it when running transaction commands since they do - * not require all the features of the main query() function. - * - * @param string the sql query - * @return mixed - */ - public function simple_query($sql) - { - if ( ! $this->conn_id) - { - if ( ! $this->initialize()) - { - return FALSE; - } - } - - return $this->_execute($sql); - } - - // -------------------------------------------------------------------- - - /** - * Disable Transactions - * This permits transactions to be disabled at run-time. - * - * @return void - */ - public function trans_off() - { - $this->trans_enabled = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Enable/disable Transaction Strict Mode - * - * When strict mode is enabled, if you are running multiple groups of - * transactions, if one group fails all subsequent groups will be - * rolled back. - * - * If strict mode is disabled, each group is treated autonomously, - * meaning a failure of one group will not affect any others - * - * @param bool $mode = TRUE - * @return void - */ - public function trans_strict($mode = TRUE) - { - $this->trans_strict = is_bool($mode) ? $mode : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Start Transaction - * - * @param bool $test_mode = FALSE - * @return bool - */ - public function trans_start($test_mode = FALSE) - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - - return $this->trans_begin($test_mode); - } - - // -------------------------------------------------------------------- - - /** - * Complete Transaction - * - * @return bool - */ - public function trans_complete() - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - - // The query() function will set this flag to FALSE in the event that a query failed - if ($this->_trans_status === FALSE OR $this->_trans_failure === TRUE) - { - $this->trans_rollback(); - - // If we are NOT running in strict mode, we will reset - // the _trans_status flag so that subsequent groups of - // transactions will be permitted. - if ($this->trans_strict === FALSE) - { - $this->_trans_status = TRUE; - } - - Logger::logDebug('DB Transaction Failure'); - return FALSE; - } - - return $this->trans_commit(); - } - - // -------------------------------------------------------------------- - - /** - * Lets you retrieve the transaction flag to determine if it has failed - * - * @return bool - */ - public function trans_status() - { - return $this->_trans_status; - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @param bool $test_mode - * @return bool - */ - public function trans_begin($test_mode = FALSE) - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 0) - { - $this->_trans_depth++; - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - - if ($this->_trans_begin()) - { - $this->_trans_depth++; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - public function trans_commit() - { - if ( ! $this->trans_enabled OR $this->_trans_depth === 0) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 1 OR $this->_trans_commit()) - { - $this->_trans_depth--; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - public function trans_rollback() - { - if ( ! $this->trans_enabled OR $this->_trans_depth === 0) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 1 OR $this->_trans_rollback()) - { - $this->_trans_depth--; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Compile Bindings - * - * @param string the sql statement - * @param array an array of bind data - * @return string - */ - public function compile_binds($sql, $binds) - { - if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) - { - return $sql; - } - elseif ( ! is_array($binds)) - { - $binds = array($binds); - $bind_count = 1; - } - else - { - // Make sure we're using numeric keys - $binds = array_values($binds); - $bind_count = count($binds); - } - - // We'll need the marker length later - $ml = strlen($this->bind_marker); - - // Make sure not to replace a chunk inside a string that happens to match the bind marker - if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) - { - $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', - str_replace($matches[0], - str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), - $sql, $c), - $matches, PREG_OFFSET_CAPTURE); - - // Bind values' count must match the count of markers in the query - if ($bind_count !== $c) - { - return $sql; - } - } - elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) - { - return $sql; - } - - do - { - $c--; - $escaped_value = $this->escape($binds[$c]); - if (is_array($escaped_value)) - { - $escaped_value = '('.implode(',', $escaped_value).')'; - } - $sql = substr_replace($sql, $escaped_value, $matches[0][$c][1], $ml); - } - while ($c !== 0); - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Calculate the aggregate query elapsed time - * - * @param int The number of decimal places - * @return string - */ - public function elapsed_time($decimals = 6) - { - return number_format($this->benchmark, $decimals); - } - - // -------------------------------------------------------------------- - - /** - * Returns the total number of queries - * - * @return int - */ - public function total_queries() - { - return $this->query_count; - } - - // -------------------------------------------------------------------- - - /** - * Returns the last query that was executed - * - * @return string - */ - public function last_query() - { - return end($this->queries); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * Sets boolean and null types - * - * @param string - * @return mixed - */ - public function escape($str) - { - if (is_array($str)) - { - $str = array_map(array(&$this, 'escape'), $str); - return $str; - } - elseif (is_string($str) OR (is_object($str) && method_exists($str, '__toString'))) - { - return "'".$this->escape_str($str)."'"; - } - elseif (is_bool($str)) - { - return ($str === FALSE) ? 0 : 1; - } - elseif ($str === NULL) - { - return 'NULL'; - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Escape String - * - * @param string|string[] $str Input string - * @param bool $like Whether or not the string will be used in a LIKE condition - * @return string - */ - public function escape_str($str, $like = FALSE) - { - if (is_array($str)) - { - foreach ($str as $key => $val) - { - $str[$key] = $this->escape_str($val, $like); - } - - return $str; - } - - $str = $this->_escape_str($str); - - // escape LIKE condition wildcards - if ($like === TRUE) - { - return str_replace( - array($this->_like_escape_chr, '%', '_'), - array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'), - $str - ); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Escape LIKE String - * - * Calls the individual driver for platform - * specific escaping for LIKE conditions - * - * @param string|string[] - * @return mixed - */ - public function escape_like_str($str) - { - return $this->escape_str($str, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return str_replace("'", "''", Utf8::remove_invisible_characters($str)); - } - - // -------------------------------------------------------------------- - - /** - * Primary - * - * Retrieves the primary key. It assumes that the row in the first - * position is the primary key - * - * @param string $table Table name - * @return string - */ - public function primary($table) - { - $fields = $this->list_fields($table); - return is_array($fields) ? current($fields) : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * "Count All" query - * - * Generates a platform-specific query string that counts all records in - * the specified database - * - * @param string - * @return int - */ - public function count_all($table = '') - { - if ($table === '') - { - return 0; - } - - $query = $this->query($this->_count_string.$this->escape_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE)); - if ($query->num_rows() === 0) - { - return 0; - } - - $query = $query->row(); - $this->_reset_select(); - return (int) $query->numrows; - } - - // -------------------------------------------------------------------- - - /** - * Returns an array of table names - * - * @param string $constrain_by_prefix = FALSE - * @return array - */ - public function list_tables($constrain_by_prefix = FALSE) - { - // Is there a cached result? - if (isset($this->data_cache['table_names'])) - { - return $this->data_cache['table_names']; - } - - if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix))) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $this->data_cache['table_names'] = array(); - $query = $this->query($sql); - - foreach ($query->result_array() as $row) - { - // Do we know from which column to get the table name? - if ( ! isset($key)) - { - if (isset($row['table_name'])) - { - $key = 'table_name'; - } - elseif (isset($row['TABLE_NAME'])) - { - $key = 'TABLE_NAME'; - } - else - { - /* We have no other choice but to just get the first element's key. - * Due to array_shift() accepting its argument by reference, if - * E_STRICT is on, this would trigger a warning. So we'll have to - * assign it first. - */ - $key = array_keys($row); - $key = array_shift($key); - } - } - - $this->data_cache['table_names'][] = $row[$key]; - } - - return $this->data_cache['table_names']; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular table exists - * - * @param string $table_name - * @return bool - */ - public function table_exists($table_name) - { - return in_array($this->protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables()); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (FALSE === ($sql = $this->_list_columns($table))) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $query = $this->query($sql); - $this->data_cache['field_names'][$table] = array(); - - foreach ($query->result_array() as $row) - { - // Do we know from where to get the column's name? - if ( ! isset($key)) - { - if (isset($row['column_name'])) - { - $key = 'column_name'; - } - elseif (isset($row['COLUMN_NAME'])) - { - $key = 'COLUMN_NAME'; - } - else - { - // We have no other choice but to just get the first element's key. - $key = key($row); - } - } - - $this->data_cache['field_names'][$table][] = $row[$key]; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular field exists - * - * @param string - * @param string - * @return bool - */ - public function field_exists($field_name, $table_name) - { - return in_array($field_name, $this->list_fields($table_name)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table the table name - * @return array - */ - public function field_data($table) - { - $query = $this->query($this->_field_data($this->protect_identifiers($table, TRUE, NULL, FALSE))); - return ($query) ? $query->field_data() : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Escape the SQL Identifiers - * - * This function escapes column and table names - * - * @param mixed - * @return mixed - */ - public function escape_identifiers($item) - { - if ($this->_escape_char === '' OR empty($item) OR in_array($item, $this->_reserved_identifiers)) - { - return $item; - } - elseif (is_array($item)) - { - foreach ($item as $key => $value) - { - $item[$key] = $this->escape_identifiers($value); - } - - return $item; - } - // Avoid breaking functions and literal values inside queries - elseif (ctype_digit($item) OR $item[0] === "'" OR ($this->_escape_char !== '"' && $item[0] === '"') OR strpos($item, '(') !== FALSE) - { - return $item; - } - - static $preg_ec = array(); - - if (empty($preg_ec)) - { - if (is_array($this->_escape_char)) - { - $preg_ec = array( - preg_quote($this->_escape_char[0], '/'), - preg_quote($this->_escape_char[1], '/'), - $this->_escape_char[0], - $this->_escape_char[1] - ); - } - else - { - $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/'); - $preg_ec[2] = $preg_ec[3] = $this->_escape_char; - } - } - - foreach ($this->_reserved_identifiers as $id) - { - if (strpos($item, '.'.$id) !== FALSE) - { - return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\./i', $preg_ec[2].'$1'.$preg_ec[3].'.', $item); - } - } - - return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?(\.)?/i', $preg_ec[2].'$1'.$preg_ec[3].'$2', $item); - } - - // -------------------------------------------------------------------- - - /** - * Generate an insert string - * - * @param string the table upon which the query will be performed - * @param array an associative array data of key/values - * @return string - */ - public function insert_string($table, $data) - { - $fields = $values = array(); - - foreach ($data as $key => $val) - { - $fields[] = $this->escape_identifiers($key); - $values[] = $this->escape($val); - } - - return $this->_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values); - } - - // -------------------------------------------------------------------- - - /** - * Insert statement - * - * Generates a platform-specific insert string from the supplied data - * - * @param string the table name - * @param array the insert keys - * @param array the insert values - * @return string - */ - protected function _insert($table, $keys, $values) - { - return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - // -------------------------------------------------------------------- - - /** - * Generate an update string - * - * @param string the table upon which the query will be performed - * @param array an associative array data of key/values - * @param mixed the "where" statement - * @return string - */ - public function update_string($table, $data, $where) - { - if (empty($where)) - { - return FALSE; - } - - $this->where($where); - - $fields = array(); - foreach ($data as $key => $val) - { - $fields[$this->protect_identifiers($key)] = $this->escape($val); - } - - $sql = $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields); - $this->_reset_write(); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string the table name - * @param array the update data - * @return string - */ - protected function _update($table, $values) - { - foreach ($values as $key => $val) - { - $valstr[] = $key.' = '.$val; - } - - return 'UPDATE '.$table.' SET '.implode(', ', $valstr) - .$this->_compile_wh('qb_where') - .$this->_compile_order_by() - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); - } - - // -------------------------------------------------------------------- - - /** - * Tests whether the string has an SQL operator - * - * @param string - * @return bool - */ - protected function _has_operator($str) - { - return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); - } - - // -------------------------------------------------------------------- - - /** - * Returns the SQL string operator - * - * @param string - * @return string - */ - protected function _get_operator($str) - { - static $_operators; - - if (empty($_operators)) - { - $_les = ($this->_like_escape_str !== '') - ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/') - : ''; - $_operators = array( - '\s*(?:<|>|!)?=\s*', // =, <=, >=, != - '\s*<>?\s*', // <, <> - '\s*>\s*', // > - '\s+IS NULL', // IS NULL - '\s+IS NOT NULL', // IS NOT NULL - '\s+EXISTS\s*\(.*\)', // EXISTS(sql) - '\s+NOT EXISTS\s*\(.*\)', // NOT EXISTS(sql) - '\s+BETWEEN\s+', // BETWEEN value AND value - '\s+IN\s*\(.*\)', // IN(list) - '\s+NOT IN\s*\(.*\)', // NOT IN (list) - '\s+LIKE\s+\S.*('.$_les.')?', // LIKE 'expr'[ ESCAPE '%s'] - '\s+NOT LIKE\s+\S.*('.$_les.')?' // NOT LIKE 'expr'[ ESCAPE '%s'] - ); - - } - - return preg_match('/'.implode('|', $_operators).'/i', $str, $match) - ? $match[0] : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Enables a native PHP function to be run, using a platform agnostic wrapper. - * - * @param string $function Function name - * @return mixed - */ - public function call_function($function) - { - $driver = ($this->dbdriver === 'postgre') ? 'pg_' : $this->dbdriver.'_'; - - if (FALSE === strpos($driver, $function)) - { - $function = $driver.$function; - } - - if ( ! function_exists($function)) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - return (func_num_args() > 1) - ? call_user_func_array($function, array_slice(func_get_args(), 1)) - : call_user_func($function); - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Directory Path - * - * @param string the path to the cache directory - * @return void - */ - public function cache_set_path($path = '') - { - $this->cachedir = $path; - } - - // -------------------------------------------------------------------- - - /** - * Enable Query Caching - * - * @return bool cache_on value - */ - public function cache_on() - { - return $this->cache_on = TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Disable Query Caching - * - * @return bool cache_on value - */ - public function cache_off() - { - return $this->cache_on = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Delete the cache files associated with a particular URI - * - * @param string $segment_one = '' - * @param string $segment_two = '' - * @return bool - */ - public function cache_delete($segment_one = '', $segment_two = '') - { - return $this->_cache_init() - ? $this->CACHE->delete($segment_one, $segment_two) - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Delete All cache files - * - * @return bool - */ - public function cache_delete_all() - { - return $this->_cache_init() - ? $this->CACHE->delete_all() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Cache Class - * - * @return bool - */ - protected function _cache_init() - { - if ( ! class_exists('FW_DB_Cache', FALSE)) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_cache.php'); - } - elseif (is_object($this->CACHE)) - { - return TRUE; - } - - $this->CACHE = new FW_DB_Cache($this); // pass db object to support multiple db connections and returned db objects - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - public function close() - { - if ($this->conn_id) - { - $this->_close(); - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * This method would be overridden by most of the drivers. - * - * @return void - */ - protected function _close() - { - $this->conn_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Display an error message - * - * @param string the error message - * @param string any "swap" values - * @param bool whether to localize the message - * @return string sends the application/layout/errors/error_db.php template - */ - public function display_error($error = '', $swap = '', $native = FALSE) - { - // First load the language - Language::get('db'); - - $heading = Language::line('db_error_heading'); - - if ($native === TRUE) - { - $message = (array) $error; - } - else - { - $message = is_array($error) ? $error : array(str_replace('%s', $swap, Language::line($error))); - } - - // Find the most likely culprit of the error by going through - // the backtrace until the source file is no longer in the - // database folder. - $trace = debug_backtrace(); - $file = ''; - $line = ''; - foreach ($trace as $call) - { - if (isset($call['file'], $call['class'])) - { - // We'll need this on Windows, as APPPATH and BASEPATH will always use forward slashes - if (DIRECTORY_SEPARATOR !== '/') - { - $call['file'] = str_replace('\\', '/', $call['file']); - } - - if (strpos($call['file'], Core::$coreDir . DS . 'Database') === FALSE && strpos($call['class'], 'Loader') === FALSE) - { - // Found it - use a relative path for safety - $file = str_replace(array('Application', 'Core'), '', $call['file']); - $line = $call['line']; - break; - } - } - } - - Logger::logError($heading . " | " . implode(' | ', $message), null, $file, $line); - throw new DatabaseException($heading . ": " . implode(' ', $this->error()), 1); - - } - - // -------------------------------------------------------------------- - - /** - * Protect Identifiers - * - * This function is used extensively by the Query Builder class, and by - * a couple functions in this class. - * It takes a column or table name (optionally with an alias) and inserts - * the table prefix onto it. Some logic is necessary in order to deal with - * column names that include the path. Consider a query like this: - * - * SELECT hostname.database.table.column AS c FROM hostname.database.table - * - * Or a query with aliasing: - * - * SELECT m.member_id, m.member_name FROM members AS m - * - * Since the column name can include up to four segments (host, DB, table, column) - * or also have an alias prefix, we need to do a bit of work to figure this out and - * insert the table prefix (if it exists) in the proper position, and escape only - * the correct identifiers. - * - * @param string - * @param bool - * @param mixed - * @param bool - * @return string - */ - public function protect_identifiers($item, $prefix_single = FALSE, $protect_identifiers = NULL, $field_exists = TRUE) - { - if ( ! is_bool($protect_identifiers)) - { - $protect_identifiers = $this->_protect_identifiers; - } - - if (is_array($item)) - { - $escaped_array = array(); - foreach ($item as $k => $v) - { - $escaped_array[$this->protect_identifiers($k)] = $this->protect_identifiers($v, $prefix_single, $protect_identifiers, $field_exists); - } - - return $escaped_array; - } - - // This is basically a bug fix for queries that use MAX, MIN, etc. - // If a parenthesis is found we know that we do not need to - // escape the data or add a prefix. There's probably a more graceful - // way to deal with this, but I'm not thinking of it -- Rick - // - // Added exception for single quotes as well, we don't want to alter - // literal strings. -- Narf - if (strcspn($item, "()'") !== strlen($item)) - { - return $item; - } - - // Convert tabs or multiple spaces into single spaces - $item = preg_replace('/\s+/', ' ', trim($item)); - - // If the item has an alias declaration we remove it and set it aside. - // Note: strripos() is used in order to support spaces in table names - if ($offset = strripos($item, ' AS ')) - { - $alias = ($protect_identifiers) - ? substr($item, $offset, 4).$this->escape_identifiers(substr($item, $offset + 4)) - : substr($item, $offset); - $item = substr($item, 0, $offset); - } - elseif ($offset = strrpos($item, ' ')) - { - $alias = ($protect_identifiers) - ? ' '.$this->escape_identifiers(substr($item, $offset + 1)) - : substr($item, $offset); - $item = substr($item, 0, $offset); - } - else - { - $alias = ''; - } - - // Break the string apart if it contains periods, then insert the table prefix - // in the correct location, assuming the period doesn't indicate that we're dealing - // with an alias. While we're at it, we will escape the components - if (strpos($item, '.') !== FALSE) - { - $parts = explode('.', $item); - - // Does the first segment of the exploded item match - // one of the aliases previously identified? If so, - // we have nothing more to do other than escape the item - // - // NOTE: The ! empty() condition prevents this method - // from breaking when QB isn't enabled. - if ( ! empty($this->qb_aliased_tables) && in_array($parts[0], $this->qb_aliased_tables)) - { - if ($protect_identifiers === TRUE) - { - foreach ($parts as $key => $val) - { - if ( ! in_array($val, $this->_reserved_identifiers)) - { - $parts[$key] = $this->escape_identifiers($val); - } - } - - $item = implode('.', $parts); - } - - return $item.$alias; - } - - // Is there a table prefix defined in the config file? If not, no need to do anything - if ($this->dbprefix !== '') - { - // We now add the table prefix based on some logic. - // Do we have 4 segments (hostname.database.table.column)? - // If so, we add the table prefix to the column name in the 3rd segment. - if (isset($parts[3])) - { - $i = 2; - } - // Do we have 3 segments (database.table.column)? - // If so, we add the table prefix to the column name in 2nd position - elseif (isset($parts[2])) - { - $i = 1; - } - // Do we have 2 segments (table.column)? - // If so, we add the table prefix to the column name in 1st segment - else - { - $i = 0; - } - - // This flag is set when the supplied $item does not contain a field name. - // This can happen when this function is being called from a JOIN. - if ($field_exists === FALSE) - { - $i++; - } - - // Verify table prefix and replace if necessary - if ($this->swap_pre !== '' && strpos($parts[$i], $this->swap_pre) === 0) - { - $parts[$i] = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $parts[$i]); - } - // We only add the table prefix if it does not already exist - elseif (strpos($parts[$i], $this->dbprefix) !== 0) - { - $parts[$i] = $this->dbprefix.$parts[$i]; - } - - // Put the parts back together - $item = implode('.', $parts); - } - - if ($protect_identifiers === TRUE) - { - $item = $this->escape_identifiers($item); - } - - return $item.$alias; - } - - // Is there a table prefix? If not, no need to insert it - if ($this->dbprefix !== '') - { - // Verify table prefix and replace if necessary - if ($this->swap_pre !== '' && strpos($item, $this->swap_pre) === 0) - { - $item = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $item); - } - // Do we prefix an item with no segments? - elseif ($prefix_single === TRUE && strpos($item, $this->dbprefix) !== 0) - { - $item = $this->dbprefix.$item; - } - } - - if ($protect_identifiers === TRUE && ! in_array($item, $this->_reserved_identifiers)) - { - $item = $this->escape_identifiers($item); - } - - return $item.$alias; - } - - // -------------------------------------------------------------------- - - /** - * Dummy method that allows Query Builder class to be disabled - * and keep count_all() working. - * - * @return void - */ - protected function _reset_select() - { - } - -} diff --git a/src/Database/DB_forge.php b/src/Database/DB_forge.php deleted file mode 100644 index 0358871..0000000 --- a/src/Database/DB_forge.php +++ /dev/null @@ -1,1032 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_forge { - - /** - * Database object - * - * @var object - */ - protected $db; - - /** - * Fields data - * - * @var array - */ - public $fields = array(); - - /** - * Keys data - * - * @var array - */ - public $keys = array(); - - /** - * Primary Keys data - * - * @var array - */ - public $primary_keys = array(); - - /** - * Database character set - * - * @var string - */ - public $db_char_set = ''; - - // -------------------------------------------------------------------- - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s'; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = 'DROP DATABASE %s'; - - /** - * CREATE TABLE statement - * - * @var string - */ - protected $_create_table = "%s %s (%s\n)"; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = FALSE; - - /** - * DROP TABLE IF EXISTS statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = 'ALTER TABLE %s RENAME TO %s;'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = TRUE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = ''; - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = ' DEFAULT '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - Logger::log('Database Forge Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return bool - */ - public function create_database($db_name) - { - if ($this->_create_database === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat))) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - if ( ! empty($this->db->data_cache['db_names'])) - { - $this->db->data_cache['db_names'][] = $db_name; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name - * @return bool - */ - public function drop_database($db_name) - { - if ($this->_drop_database === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name))) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - if ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($db_name), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Add Key - * - * @param string $key - * @param bool $primary - * @return FW_DB_forge - */ - public function add_key($key, $primary = FALSE) - { - // DO NOT change this! This condition is only applicable - // for PRIMARY keys because you can only have one such, - // and therefore all fields you add to it will be included - // in the same, composite PRIMARY KEY. - // - // It's not the same for regular indexes. - if ($primary === TRUE && is_array($key)) - { - foreach ($key as $one) - { - $this->add_key($one, $primary); - } - - return $this; - } - - if ($primary === TRUE) - { - $this->primary_keys[] = $key; - } - else - { - $this->keys[] = $key; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Add Field - * - * @param array $field - * @return FW_DB_forge - */ - public function add_field($field) - { - if (is_string($field)) - { - if ($field === 'id') - { - $this->add_field(array( - 'id' => array( - 'type' => 'INT', - 'constraint' => 9, - 'auto_increment' => TRUE - ) - )); - $this->add_key('id', TRUE); - } - else - { - if (strpos($field, ' ') === FALSE) - { - throw new DatabaseException('Field information is required for that operation.', 1); - } - - $this->fields[] = $field; - } - } - - if (is_array($field)) - { - $this->fields = array_merge($this->fields, $field); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Create Table - * - * @param string $table Table name - * @param bool $if_not_exists Whether to add IF NOT EXISTS condition - * @param array $attributes Associative array of table attributes - * @return bool - */ - public function create_table($table, $if_not_exists = FALSE, array $attributes = array()) - { - if ($table === '') - { - throw new DatabaseException('A table name is required for that operation.', 1); - } - else - { - $table = $this->db->dbprefix.$table; - } - - if (count($this->fields) === 0) - { - throw new DatabaseException('Field information is required.', 1); - } - - $sql = $this->_create_table($table, $if_not_exists, $attributes); - - if (is_bool($sql)) - { - $this->_reset(); - if ($sql === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - } - - if (($result = $this->db->query($sql)) !== FALSE) - { - empty($this->db->data_cache['table_names']) OR $this->db->data_cache['table_names'][] = $table; - - // Most databases don't support creating indexes from within the CREATE TABLE statement - if ( ! empty($this->keys)) - { - for ($i = 0, $sqls = $this->_process_indexes($table), $c = count($sqls); $i < $c; $i++) - { - $this->db->query($sqls[$i]); - } - } - } - - $this->_reset(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Create Table - * - * @param string $table Table name - * @param bool $if_not_exists Whether to add 'IF NOT EXISTS' condition - * @param array $attributes Associative array of table attributes - * @return mixed - */ - protected function _create_table($table, $if_not_exists, $attributes) - { - if ($if_not_exists === TRUE && $this->_create_table_if === FALSE) - { - if ($this->db->table_exists($table)) - { - return TRUE; - } - else - { - $if_not_exists = FALSE; - } - } - - $sql = ($if_not_exists) - ? sprintf($this->_create_table_if, $this->db->escape_identifiers($table)) - : 'CREATE TABLE'; - - $columns = $this->_process_fields(TRUE); - for ($i = 0, $c = count($columns); $i < $c; $i++) - { - $columns[$i] = ($columns[$i]['_literal'] !== FALSE) - ? "\n\t".$columns[$i]['_literal'] - : "\n\t".$this->_process_column($columns[$i]); - } - - $columns = implode(',', $columns) - .$this->_process_primary_keys($table); - - // Are indexes created from within the CREATE TABLE statement? (e.g. in MySQL) - if ($this->_create_table_keys === TRUE) - { - $columns .= $this->_process_indexes($table); - } - - // _create_table will usually have the following format: "%s %s (%s\n)" - $sql = sprintf($this->_create_table.'%s', - $sql, - $this->db->escape_identifiers($table), - $columns, - $this->_create_table_attr($attributes) - ); - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' '.$attributes[$key]; - } - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Drop Table - * - * @param string $table_name Table name - * @param bool $if_exists Whether to add an IF EXISTS condition - * @return bool - */ - public function drop_table($table_name, $if_exists = FALSE) - { - if ($table_name === '') - { - return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE; - } - - if (($query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists)) === TRUE) - { - return TRUE; - } - - $query = $this->db->query($query); - - // Update table list cache - if ($query && ! empty($this->db->data_cache['table_names'])) - { - $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['table_names'][$key]); - } - } - - return $query; - } - - // -------------------------------------------------------------------- - - /** - * Drop Table - * - * Generates a platform-specific DROP TABLE string - * - * @param string $table Table name - * @param bool $if_exists Whether to add an IF EXISTS condition - * @return string - */ - protected function _drop_table($table, $if_exists) - { - $sql = 'DROP TABLE'; - - if ($if_exists) - { - if ($this->_drop_table_if === FALSE) - { - if ( ! $this->db->table_exists($table)) - { - return TRUE; - } - } - else - { - $sql = sprintf($this->_drop_table_if, $this->db->escape_identifiers($table)); - } - } - - return $sql.' '.$this->db->escape_identifiers($table); - } - - // -------------------------------------------------------------------- - - /** - * Rename Table - * - * @param string $table_name Old table name - * @param string $new_table_name New table name - * @return bool - */ - public function rename_table($table_name, $new_table_name) - { - if ($table_name === '' OR $new_table_name === '') - { - throw new DatabaseException('A table name is required for that operation.', 1); - return FALSE; - } - elseif ($this->_rename_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $result = $this->db->query(sprintf($this->_rename_table, - $this->db->escape_identifiers($this->db->dbprefix.$table_name), - $this->db->escape_identifiers($this->db->dbprefix.$new_table_name)) - ); - - if ($result && ! empty($this->db->data_cache['table_names'])) - { - $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE); - if ($key !== FALSE) - { - $this->db->data_cache['table_names'][$key] = $this->db->dbprefix.$new_table_name; - } - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Column Add - * - * @todo Remove deprecated $_after option in 3.1+ - * @param string $table Table name - * @param array $field Column definition - * @param string $_after Column for AFTER clause (deprecated) - * @return bool - */ - public function add_column($table, $field, $_after = NULL) - { - // Work-around for literal column definitions - is_array($field) OR $field = array($field); - - foreach (array_keys($field) as $k) - { - // Backwards-compatibility work-around for MySQL/CUBRID AFTER clause (remove in 3.1+) - if ($_after !== NULL && is_array($field[$k]) && ! isset($field[$k]['after'])) - { - $field[$k]['after'] = $_after; - } - - $this->add_field(array($k => $field[$k])); - } - - $sqls = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->_process_fields()); - $this->_reset(); - if ($sqls === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - for ($i = 0, $c = count($sqls); $i < $c; $i++) - { - if ($this->db->query($sqls[$i]) === FALSE) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Column Drop - * - * @param string $table Table name - * @param string $column_name Column name - * @return bool - */ - public function drop_column($table, $column_name) - { - $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name); - if ($sql === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - return $this->db->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Column Modify - * - * @param string $table Table name - * @param string $field Column definition - * @return bool - */ - public function modify_column($table, $field) - { - // Work-around for literal column definitions - is_array($field) OR $field = array($field); - - foreach (array_keys($field) as $k) - { - $this->add_field(array($k => $field[$k])); - } - - if (count($this->fields) === 0) - { - throw new DatabaseException('Field information is required.', 1); - } - - $sqls = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->_process_fields()); - $this->_reset(); - if ($sqls === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - for ($i = 0, $c = count($sqls); $i < $c; $i++) - { - if ($this->db->query($sqls[$i]) === FALSE) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '; - - // DROP has everything it needs now. - if ($alter_type === 'DROP') - { - return $sql.'DROP COLUMN '.$this->db->escape_identifiers($field); - } - - $sql .= ($alter_type === 'ADD') - ? 'ADD ' - : $alter_type.' COLUMN '; - - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql - .($field[$i]['_literal'] !== FALSE ? $field[$i]['_literal'] : $this->_process_column($field[$i])); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process fields - * - * @param bool $create_table - * @return array - */ - protected function _process_fields($create_table = FALSE) - { - $fields = array(); - - foreach ($this->fields as $key => $attributes) - { - if (is_int($key) && ! is_array($attributes)) - { - $fields[] = array('_literal' => $attributes); - continue; - } - - $attributes = array_change_key_case($attributes, CASE_UPPER); - - if ($create_table === TRUE && empty($attributes['TYPE'])) - { - continue; - } - - isset($attributes['TYPE']) && $this->_attr_type($attributes); - - $field = array( - 'name' => $key, - 'new_name' => isset($attributes['NAME']) ? $attributes['NAME'] : NULL, - 'type' => isset($attributes['TYPE']) ? $attributes['TYPE'] : NULL, - 'length' => '', - 'unsigned' => '', - 'null' => '', - 'unique' => '', - 'default' => '', - 'auto_increment' => '', - '_literal' => FALSE - ); - - isset($attributes['TYPE']) && $this->_attr_unsigned($attributes, $field); - - if ($create_table === FALSE) - { - if (isset($attributes['AFTER'])) - { - $field['after'] = $attributes['AFTER']; - } - elseif (isset($attributes['FIRST'])) - { - $field['first'] = (bool) $attributes['FIRST']; - } - } - - $this->_attr_default($attributes, $field); - - if (isset($attributes['NULL'])) - { - if ($attributes['NULL'] === TRUE) - { - $field['null'] = empty($this->_null) ? '' : ' '.$this->_null; - } - else - { - $field['null'] = ' NOT NULL'; - } - } - elseif ($create_table === TRUE) - { - $field['null'] = ' NOT NULL'; - } - - $this->_attr_auto_increment($attributes, $field); - $this->_attr_unique($attributes, $field); - - if (isset($attributes['COMMENT'])) - { - $field['comment'] = $this->db->escape($attributes['COMMENT']); - } - - if (isset($attributes['TYPE']) && ! empty($attributes['CONSTRAINT'])) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['CONSTRAINT'] = $this->db->escape($attributes['CONSTRAINT']); - default: - $field['length'] = is_array($attributes['CONSTRAINT']) - ? '('.implode(',', $attributes['CONSTRAINT']).')' - : '('.$attributes['CONSTRAINT'].')'; - break; - } - } - - $fields[] = $field; - } - - return $fields; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['default'] - .$field['null'] - .$field['auto_increment'] - .$field['unique']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Usually overridden by drivers - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNSIGNED - * - * Depending on the _unsigned property value: - * - * - TRUE will always set $field['unsigned'] to 'UNSIGNED' - * - FALSE will always set $field['unsigned'] to '' - * - array(TYPE) will set $field['unsigned'] to 'UNSIGNED', - * if $attributes['TYPE'] is found in the array - * - array(TYPE => UTYPE) will change $field['type'], - * from TYPE to UTYPE in case of a match - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unsigned(&$attributes, &$field) - { - if (empty($attributes['UNSIGNED']) OR $attributes['UNSIGNED'] !== TRUE) - { - return; - } - - // Reset the attribute in order to avoid issues if we do type conversion - $attributes['UNSIGNED'] = FALSE; - - if (is_array($this->_unsigned)) - { - foreach (array_keys($this->_unsigned) as $key) - { - if (is_int($key) && strcasecmp($attributes['TYPE'], $this->_unsigned[$key]) === 0) - { - $field['unsigned'] = ' UNSIGNED'; - return; - } - elseif (is_string($key) && strcasecmp($attributes['TYPE'], $key) === 0) - { - $field['type'] = $key; - return; - } - } - - return; - } - - $field['unsigned'] = ($this->_unsigned === TRUE) ? ' UNSIGNED' : ''; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute DEFAULT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_default(&$attributes, &$field) - { - if ($this->_default === FALSE) - { - return; - } - - if (array_key_exists('DEFAULT', $attributes)) - { - if ($attributes['DEFAULT'] === NULL) - { - $field['default'] = empty($this->_null) ? '' : $this->_default.$this->_null; - - // Override the NULL attribute if that's our default - $attributes['NULL'] = TRUE; - $field['null'] = empty($this->_null) ? '' : ' '.$this->_null; - } - else - { - $field['default'] = $this->_default.$this->db->escape($attributes['DEFAULT']); - } - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' AUTO_INCREMENT'; - } - } - - // -------------------------------------------------------------------- - - /** - * Process primary keys - * - * @param string $table Table name - * @return string - */ - protected function _process_primary_keys($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->primary_keys); $i < $c; $i++) - { - if ( ! isset($this->fields[$this->primary_keys[$i]])) - { - unset($this->primary_keys[$i]); - } - } - - if (count($this->primary_keys) > 0) - { - $sql .= ",\n\tCONSTRAINT ".$this->db->escape_identifiers('pk_'.$table) - .' PRIMARY KEY('.implode(', ', $this->db->escape_identifiers($this->primary_keys)).')'; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table - * @return string - */ - protected function _process_indexes($table) - { - $sqls = array(); - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers($table.'_'.implode('_', $this->keys[$i])) - .' ON '.$this->db->escape_identifiers($table) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).');'; - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Reset - * - * Resets table creation vars - * - * @return void - */ - protected function _reset() - { - $this->fields = $this->keys = $this->primary_keys = array(); - } - -} diff --git a/src/Database/DB_query_builder.php b/src/Database/DB_query_builder.php deleted file mode 100644 index 5ba5f10..0000000 --- a/src/Database/DB_query_builder.php +++ /dev/null @@ -1,2781 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Query Builder Class - * - * This is the platform-independent base Query Builder implementation class. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ - -abstract class FW_DB_query_builder extends FW_DB_driver { - - /** - * Return DELETE SQL flag - * - * @var bool - */ - protected $return_delete_sql = FALSE; - - /** - * Reset DELETE data flag - * - * @var bool - */ - protected $reset_delete_data = FALSE; - - /** - * QB SELECT data - * - * @var array - */ - protected $qb_select = array(); - - /** - * QB DISTINCT flag - * - * @var bool - */ - protected $qb_distinct = FALSE; - - /** - * QB FROM data - * - * @var array - */ - protected $qb_from = array(); - - /** - * QB JOIN data - * - * @var array - */ - protected $qb_join = array(); - - /** - * QB WHERE data - * - * @var array - */ - protected $qb_where = array(); - - /** - * QB GROUP BY data - * - * @var array - */ - protected $qb_groupby = array(); - - /** - * QB HAVING data - * - * @var array - */ - protected $qb_having = array(); - - /** - * QB keys - * - * @var array - */ - protected $qb_keys = array(); - - /** - * QB LIMIT data - * - * @var int - */ - protected $qb_limit = FALSE; - - /** - * QB OFFSET data - * - * @var int - */ - protected $qb_offset = FALSE; - - /** - * QB ORDER BY data - * - * @var array - */ - protected $qb_orderby = array(); - - /** - * QB data sets - * - * @var array - */ - protected $qb_set = array(); - - /** - * QB aliased tables list - * - * @var array - */ - protected $qb_aliased_tables = array(); - - /** - * QB WHERE group started flag - * - * @var bool - */ - protected $qb_where_group_started = FALSE; - - /** - * QB WHERE group count - * - * @var int - */ - protected $qb_where_group_count = 0; - - // Query Builder Caching variables - - /** - * QB Caching flag - * - * @var bool - */ - protected $qb_caching = FALSE; - - /** - * QB Cache exists list - * - * @var array - */ - protected $qb_cache_exists = array(); - - /** - * QB Cache SELECT data - * - * @var array - */ - protected $qb_cache_select = array(); - - /** - * QB Cache FROM data - * - * @var array - */ - protected $qb_cache_from = array(); - - /** - * QB Cache JOIN data - * - * @var array - */ - protected $qb_cache_join = array(); - - /** - * QB Cache WHERE data - * - * @var array - */ - protected $qb_cache_where = array(); - - /** - * QB Cache GROUP BY data - * - * @var array - */ - protected $qb_cache_groupby = array(); - - /** - * QB Cache HAVING data - * - * @var array - */ - protected $qb_cache_having = array(); - - /** - * QB Cache ORDER BY data - * - * @var array - */ - protected $qb_cache_orderby = array(); - - /** - * QB Cache data sets - * - * @var array - */ - protected $qb_cache_set = array(); - - /** - * QB No Escape data - * - * @var array - */ - protected $qb_no_escape = array(); - - /** - * QB Cache No Escape data - * - * @var array - */ - protected $qb_cache_no_escape = array(); - - // -------------------------------------------------------------------- - - /** - * Select - * - * Generates the SELECT portion of the query - * - * @param string - * @param mixed - * @return FW_DB_query_builder - */ - public function select($select = '*', $escape = NULL) - { - if (is_string($select)) - { - $select = explode(',', $select); - } - - // If the escape value was not set, we will base it on the global setting - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($select as $val) - { - $val = trim($val); - - if ($val !== '') - { - $this->qb_select[] = $val; - $this->qb_no_escape[] = $escape; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_select[] = $val; - $this->qb_cache_exists[] = 'select'; - $this->qb_cache_no_escape[] = $escape; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Select Max - * - * Generates a SELECT MAX(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_max($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'MAX'); - } - - // -------------------------------------------------------------------- - - /** - * Select Min - * - * Generates a SELECT MIN(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_min($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'MIN'); - } - - // -------------------------------------------------------------------- - - /** - * Select Average - * - * Generates a SELECT AVG(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_avg($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'AVG'); - } - - // -------------------------------------------------------------------- - - /** - * Select Sum - * - * Generates a SELECT SUM(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_sum($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'SUM'); - } - - // -------------------------------------------------------------------- - - /** - * SELECT [MAX|MIN|AVG|SUM]() - * - * @used-by select_max() - * @used-by select_min() - * @used-by select_avg() - * @used-by select_sum() - * - * @param string $select Field name - * @param string $alias - * @param string $type - * @return FW_DB_query_builder - */ - protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX') - { - if ( ! is_string($select) OR $select === '') - { - $this->display_error('db_invalid_query'); - } - - $type = strtoupper($type); - - if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM'))) - { - throw new DatabaseException('Invalid function type: '.$type, 1); - } - - if ($alias === '') - { - $alias = $this->_create_alias_from_table(trim($select)); - } - - $sql = $type.'('.$this->protect_identifiers(trim($select)).') AS '.$this->escape_identifiers(trim($alias)); - - $this->qb_select[] = $sql; - $this->qb_no_escape[] = NULL; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_select[] = $sql; - $this->qb_cache_exists[] = 'select'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Determines the alias name based on the table - * - * @param string $item - * @return string - */ - protected function _create_alias_from_table($item) - { - if (strpos($item, '.') !== FALSE) - { - $item = explode('.', $item); - return end($item); - } - - return $item; - } - - // -------------------------------------------------------------------- - - /** - * DISTINCT - * - * Sets a flag which tells the query string compiler to add DISTINCT - * - * @param bool $val - * @return FW_DB_query_builder - */ - public function distinct($val = TRUE) - { - $this->qb_distinct = is_bool($val) ? $val : TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * From - * - * Generates the FROM portion of the query - * - * @param mixed $from can be a string or array - * @return FW_DB_query_builder - */ - public function from($from) - { - foreach ((array) $from as $val) - { - if (strpos($val, ',') !== FALSE) - { - foreach (explode(',', $val) as $v) - { - $v = trim($v); - $this->_track_aliases($v); - - $this->qb_from[] = $v = $this->protect_identifiers($v, TRUE, NULL, FALSE); - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_from[] = $v; - $this->qb_cache_exists[] = 'from'; - } - } - } - else - { - $val = trim($val); - - // Extract any aliases that might exist. We use this information - // in the protect_identifiers to know whether to add a table prefix - $this->_track_aliases($val); - - $this->qb_from[] = $val = $this->protect_identifiers($val, TRUE, NULL, FALSE); - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_from[] = $val; - $this->qb_cache_exists[] = 'from'; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * JOIN - * - * Generates the JOIN portion of the query - * - * @param string - * @param string the join condition - * @param string the type of join - * @param string whether not to try to escape identifiers - * @return FW_DB_query_builder - */ - public function join($table, $cond, $type = '', $escape = NULL) - { - if ($type !== '') - { - $type = strtoupper(trim($type)); - - if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) - { - $type = ''; - } - else - { - $type .= ' '; - } - } - - // Extract any aliases that might exist. We use this information - // in the protect_identifiers to know whether to add a table prefix - $this->_track_aliases($table); - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if ( ! $this->_has_operator($cond)) - { - $cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')'; - } - elseif ($escape === FALSE) - { - $cond = ' ON '.$cond; - } - else - { - // Split multiple conditions - if (preg_match_all('/\sAND\s|\sOR\s/i', $cond, $joints, PREG_OFFSET_CAPTURE)) - { - $conditions = array(); - $joints = $joints[0]; - array_unshift($joints, array('', 0)); - - for ($i = count($joints) - 1, $pos = strlen($cond); $i >= 0; $i--) - { - $joints[$i][1] += strlen($joints[$i][0]); // offset - $conditions[$i] = substr($cond, $joints[$i][1], $pos - $joints[$i][1]); - $pos = $joints[$i][1] - strlen($joints[$i][0]); - $joints[$i] = $joints[$i][0]; - } - } - else - { - $conditions = array($cond); - $joints = array(''); - } - - $cond = ' ON '; - for ($i = 0, $c = count($conditions); $i < $c; $i++) - { - $operator = $this->_get_operator($conditions[$i]); - $cond .= $joints[$i]; - $cond .= preg_match("/(\(*)?([\[\]\w\.'-]+)".preg_quote($operator)."(.*)/i", $conditions[$i], $match) - ? $match[1].$this->protect_identifiers($match[2]).$operator.$this->protect_identifiers($match[3]) - : $conditions[$i]; - } - } - - // Do we want to escape the table name? - if ($escape === TRUE) - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // Assemble the JOIN statement - $this->qb_join[] = $join = $type.'JOIN '.$table.$cond; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_join[] = $join; - $this->qb_cache_exists[] = 'join'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * WHERE - * - * Generates the WHERE portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed - * @param mixed - * @param bool - * @return FW_DB_query_builder - */ - public function where($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_where', $key, $value, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE - * - * Generates the WHERE portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed - * @param mixed - * @param bool - * @return FW_DB_query_builder - */ - public function or_where($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_where', $key, $value, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * WHERE, HAVING - * - * @used-by where() - * @used-by or_where() - * @used-by having() - * @used-by or_having() - * - * @param string $qb_key 'qb_where' or 'qb_having' - * @param mixed $key - * @param mixed $value - * @param string $type - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = NULL) - { - $qb_cache_key = ($qb_key === 'qb_having') ? 'qb_cache_having' : 'qb_cache_where'; - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - // If the escape value was not set will base it on the global setting - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $prefix = (count($this->$qb_key) === 0 && count($this->$qb_cache_key) === 0) - ? $this->_group_get_type('') - : $this->_group_get_type($type); - - if ($v !== NULL) - { - if ($escape === TRUE) - { - $v = ' '.$this->escape($v); - } - - if ( ! $this->_has_operator($k)) - { - $k .= ' = '; - } - } - elseif ( ! $this->_has_operator($k)) - { - // value appears not to have been set, assign the test to IS NULL - $k .= ' IS NULL'; - } - elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) - { - $k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL'); - } - - $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); - if ($this->qb_caching === TRUE) - { - $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); - $this->qb_cache_exists[] = substr($qb_key, 3); - } - - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * WHERE IN - * - * Generates a WHERE field IN('item', 'item') SQL query, - * joined with 'AND' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function where_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, FALSE, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE IN - * - * Generates a WHERE field IN('item', 'item') SQL query, - * joined with 'OR' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_where_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, FALSE, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * WHERE NOT IN - * - * Generates a WHERE field NOT IN('item', 'item') SQL query, - * joined with 'AND' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function where_not_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, TRUE, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE NOT IN - * - * Generates a WHERE field NOT IN('item', 'item') SQL query, - * joined with 'OR' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_where_not_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, TRUE, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * Internal WHERE IN - * - * @used-by where_in() - * @used-by or_where_in() - * @used-by where_not_in() - * @used-by or_where_not_in() - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $not If the statement would be IN or NOT IN - * @param string $type - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL) - { - if ($key === NULL OR $values === NULL) - { - return $this; - } - - if ( ! is_array($values)) - { - $values = array($values); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - $not = ($not) ? ' NOT' : ''; - - if ($escape === TRUE) - { - $where_in = array(); - foreach ($values as $value) - { - $where_in[] = $this->escape($value); - } - } - else - { - $where_in = array_values($values); - } - - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) - ? $this->_group_get_type('') - : $this->_group_get_type($type); - - $where_in = array( - 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')', - 'escape' => $escape - ); - - $this->qb_where[] = $where_in; - if ($this->qb_caching === TRUE) - { - $this->qb_cache_where[] = $where_in; - $this->qb_cache_exists[] = 'where'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIKE - * - * Generates a %LIKE% portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'AND ', $side, '', $escape); - } - - // -------------------------------------------------------------------- - - /** - * NOT LIKE - * - * Generates a NOT LIKE portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function not_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR LIKE - * - * Generates a %LIKE% portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'OR ', $side, '', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR NOT LIKE - * - * Generates a NOT LIKE portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_not_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape); - } - - // -------------------------------------------------------------------- - - /** - * Internal LIKE - * - * @used-by like() - * @used-by or_like() - * @used-by not_like() - * @used-by or_not_like() - * - * @param mixed $field - * @param string $match - * @param string $type - * @param string $side - * @param string $not - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '', $escape = NULL) - { - if ( ! is_array($field)) - { - $field = array($field => $match); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - // lowercase $side in case somebody writes e.g. 'BEFORE' instead of 'before' (doh) - $side = strtolower($side); - - foreach ($field as $k => $v) - { - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) - ? $this->_group_get_type('') : $this->_group_get_type($type); - - if ($escape === TRUE) - { - $v = $this->escape_like_str($v); - } - - if ($side === 'none') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'"; - } - elseif ($side === 'before') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'"; - } - elseif ($side === 'after') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'"; - } - else - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'"; - } - - // some platforms require an escape sequence definition for LIKE wildcards - if ($escape === TRUE && $this->_like_escape_str !== '') - { - $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape); - if ($this->qb_caching === TRUE) - { - $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape); - $this->qb_cache_exists[] = 'where'; - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group. - * - * @param string $not (Internal use only) - * @param string $type (Internal use only) - * @return FW_DB_query_builder - */ - public function group_start($not = '', $type = 'AND ') - { - $type = $this->_group_get_type($type); - - $this->qb_where_group_started = TRUE; - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type; - $where = array( - 'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (', - 'escape' => FALSE - ); - - $this->qb_where[] = $where; - if ($this->qb_caching) - { - $this->qb_cache_where[] = $where; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but ORs the group - * - * @return FW_DB_query_builder - */ - public function or_group_start() - { - return $this->group_start('', 'OR '); - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but NOTs the group - * - * @return FW_DB_query_builder - */ - public function not_group_start() - { - return $this->group_start('NOT ', 'AND '); - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but OR NOTs the group - * - * @return FW_DB_query_builder - */ - public function or_not_group_start() - { - return $this->group_start('NOT ', 'OR '); - } - - // -------------------------------------------------------------------- - - /** - * Ends a query group - * - * @return FW_DB_query_builder - */ - public function group_end() - { - $this->qb_where_group_started = FALSE; - $where = array( - 'condition' => str_repeat(' ', $this->qb_where_group_count--).')', - 'escape' => FALSE - ); - - $this->qb_where[] = $where; - if ($this->qb_caching) - { - $this->qb_cache_where[] = $where; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Group_get_type - * - * @used-by group_start() - * @used-by _like() - * @used-by _wh() - * @used-by _where_in() - * - * @param string $type - * @return string - */ - protected function _group_get_type($type) - { - if ($this->qb_where_group_started) - { - $type = ''; - $this->qb_where_group_started = FALSE; - } - - return $type; - } - - // -------------------------------------------------------------------- - - /** - * GROUP BY - * - * @param string $by - * @param bool $escape - * @return FW_DB_query_builder - */ - public function group_by($by, $escape = NULL) - { - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if (is_string($by)) - { - $by = ($escape === TRUE) - ? explode(',', $by) - : array($by); - } - - foreach ($by as $val) - { - $val = trim($val); - - if ($val !== '') - { - $val = array('field' => $val, 'escape' => $escape); - - $this->qb_groupby[] = $val; - if ($this->qb_caching === TRUE) - { - $this->qb_cache_groupby[] = $val; - $this->qb_cache_exists[] = 'groupby'; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * HAVING - * - * Separates multiple calls with 'AND'. - * - * @param string $key - * @param string $value - * @param bool $escape - * @return FW_DB_query_builder - */ - public function having($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_having', $key, $value, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR HAVING - * - * Separates multiple calls with 'OR'. - * - * @param string $key - * @param string $value - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_having($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_having', $key, $value, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return FW_DB_query_builder - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - - if ($direction === 'RANDOM') - { - $direction = ''; - - // Do we have a seed value? - $orderby = ctype_digit((string) $orderby) - ? sprintf($this->_random_keyword[1], $orderby) - : $this->_random_keyword[0]; - } - elseif (empty($orderby)) - { - return $this; - } - elseif ($direction !== '') - { - $direction = in_array($direction, array('ASC', 'DESC'), TRUE) ? ' '.$direction : ''; - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if ($escape === FALSE) - { - $qb_orderby[] = array('field' => $orderby, 'direction' => $direction, 'escape' => FALSE); - } - else - { - $qb_orderby = array(); - foreach (explode(',', $orderby) as $field) - { - $qb_orderby[] = ($direction === '' && preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE)) - ? array('field' => ltrim(substr($field, 0, $match[0][1])), 'direction' => ' '.$match[1][0], 'escape' => TRUE) - : array('field' => trim($field), 'direction' => $direction, 'escape' => TRUE); - } - } - - $this->qb_orderby = array_merge($this->qb_orderby, $qb_orderby); - if ($this->qb_caching === TRUE) - { - $this->qb_cache_orderby = array_merge($this->qb_cache_orderby, $qb_orderby); - $this->qb_cache_exists[] = 'orderby'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * @param int $value LIMIT value - * @param int $offset OFFSET value - * @return FW_DB_query_builder - */ - public function limit($value, $offset = 0) - { - is_null($value) OR $this->qb_limit = (int) $value; - empty($offset) OR $this->qb_offset = (int) $offset; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Sets the OFFSET value - * - * @param int $offset OFFSET value - * @return FW_DB_query_builder - */ - public function offset($offset) - { - empty($offset) OR $this->qb_offset = (int) $offset; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIMIT string - * - * Generates a platform-specific LIMIT clause. - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').$this->qb_limit; - } - - // -------------------------------------------------------------------- - - /** - * The "set" function. - * - * Allows key/value pairs to be set for inserting or updating - * - * @param mixed - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set($key, $value = '', $escape = NULL) - { - $key = $this->_object_to_array($key); - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $this->qb_set[$this->protect_identifiers($k, FALSE, $escape)] = ($escape) - ? $this->escape($v) : $v; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get SELECT query string - * - * Compiles a SELECT query string and returns the sql. - * - * @param string the table name to select from (optional) - * @param bool TRUE: resets QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_select($table = '', $reset = TRUE) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - $select = $this->_compile_select(); - - if ($reset === TRUE) - { - $this->_reset_select(); - } - - return $select; - } - - // -------------------------------------------------------------------- - - /** - * Get - * - * Compiles the select statement based on the other functions called - * and runs the query - * - * @param string the table - * @param string the limit clause - * @param string the offset clause - * @return FW_DB_result - */ - public function get($table = '', $limit = NULL, $offset = NULL) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - if ( ! empty($limit)) - { - $this->limit($limit, $offset); - } - - $result = $this->query($this->_compile_select()); - $this->_reset_select(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * "Count All Results" query - * - * Generates a platform-specific query string that counts all records - * returned by an Query Builder query. - * - * @param string - * @param bool the reset clause - * @return int - */ - public function count_all_results($table = '', $reset = TRUE) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - // ORDER BY usage is often problematic here (most notably - // on Microsoft SQL Server) and ultimately unnecessary - // for selecting COUNT(*) ... - if ( ! empty($this->qb_orderby)) - { - $orderby = $this->qb_orderby; - $this->qb_orderby = NULL; - } - - $result = ($this->qb_distinct === TRUE) - ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) FW_count_all_results") - : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); - - if ($reset === TRUE) - { - $this->_reset_select(); - } - // If we've previously reset the qb_orderby values, get them back - elseif ( ! isset($this->qb_orderby)) - { - $this->qb_orderby = $orderby; - } - - if ($result->num_rows() === 0) - { - return 0; - } - - $row = $result->row(); - return (int) $row->numrows; - } - - // -------------------------------------------------------------------- - - /** - * Get_Where - * - * Allows the where clause, limit and offset to be added directly - * - * @param string $table - * @param string $where - * @param int $limit - * @param int $offset - * @return FW_DB_result - */ - public function get_where($table = '', $where = NULL, $limit = NULL, $offset = NULL) - { - if ($table !== '') - { - $this->from($table); - } - - if ($where !== NULL) - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit, $offset); - } - - $result = $this->query($this->_compile_select()); - $this->_reset_select(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Insert_Batch - * - * Compiles batch insert strings and runs the queries - * - * @param string $table Table to insert into - * @param array $set An associative array of insert values - * @param bool $escape Whether to escape values and identifiers - * @return int Number of rows inserted or FALSE on failure - */ - public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 100) - { - if ($set === NULL) - { - if (empty($this->qb_set)) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - } - else - { - if (empty($set)) - { - return ($this->db_debug) ? $this->display_error('insert_batch() called with no data') : FALSE; - } - - $this->set_insert_batch($set, '', $escape); - } - - if (strlen($table) === 0) - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - // Batch this baby - $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) - { - $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size))); - $affected_rows += $this->affected_rows(); - } - - $this->_reset_write(); - return $affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values); - } - - // -------------------------------------------------------------------- - - /** - * The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts - * - * @param mixed - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set_insert_batch($key, $value = '', $escape = NULL) - { - $key = $this->_object_to_array_batch($key); - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - $keys = array_keys($this->_object_to_array(current($key))); - sort($keys); - - foreach ($key as $row) - { - $row = $this->_object_to_array($row); - if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0) - { - // batch function above returns an error on an empty array - $this->qb_set[] = array(); - return; - } - - ksort($row); // puts $row in the same order as our keys - - if ($escape !== FALSE) - { - $clean = array(); - foreach ($row as $value) - { - $clean[] = $this->escape($value); - } - - $row = $clean; - } - - $this->qb_set[] = '('.implode(',', $row).')'; - } - - foreach ($keys as $k) - { - $this->qb_keys[] = $this->protect_identifiers($k, FALSE, $escape); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get INSERT query string - * - * Compiles an insert query and returns the sql - * - * @param string the table to insert into - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_insert($table = '', $reset = TRUE) - { - if ($this->_validate_insert($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_insert( - $this->protect_identifiers( - $this->qb_from[0], TRUE, NULL, FALSE - ), - array_keys($this->qb_set), - array_values($this->qb_set) - ); - - if ($reset === TRUE) - { - $this->_reset_write(); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Insert - * - * Compiles an insert string and runs the query - * - * @param string the table to insert data into - * @param array an associative array of insert values - * @param bool $escape Whether to escape values and identifiers - * @return bool TRUE on success, FALSE on failure - */ - public function insert($table = '', $set = NULL, $escape = NULL) - { - if ($set !== NULL) - { - $this->set($set, '', $escape); - } - - if ($this->_validate_insert($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_insert( - $this->protect_identifiers( - $this->qb_from[0], TRUE, $escape, FALSE - ), - array_keys($this->qb_set), - array_values($this->qb_set) - ); - - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Validate Insert - * - * This method is used by both insert() and get_compiled_insert() to - * validate that the there data is actually being set and that table - * has been chosen to be inserted into. - * - * @param string the table to insert data into - * @return string - */ - protected function _validate_insert($table = '') - { - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table !== '') - { - $this->qb_from[0] = $table; - } - elseif ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Replace - * - * Compiles an replace into string and runs the query - * - * @param string the table to replace data into - * @param array an associative array of insert values - * @return bool TRUE on success, FALSE on failure - */ - public function replace($table = '', $set = NULL) - { - if ($set !== NULL) - { - $this->set($set); - } - - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - $sql = $this->_replace($this->protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->qb_set), array_values($this->qb_set)); - - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string the table name - * @param array the insert keys - * @param array the insert values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * Note: This is only used (and overridden) by MySQL and CUBRID. - * - * @return string - */ - protected function _from_tables() - { - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Get UPDATE query string - * - * Compiles an update query and returns the sql - * - * @param string the table to update - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_update($table = '', $reset = TRUE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($this->_validate_update($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_update($this->qb_from[0], $this->qb_set); - - if ($reset === TRUE) - { - $this->_reset_write(); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * UPDATE - * - * Compiles an update string and runs the query. - * - * @param string $table - * @param array $set An associative array of update values - * @param mixed $where - * @param int $limit - * @return bool TRUE on success, FALSE on failure - */ - public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($set !== NULL) - { - $this->set($set); - } - - if ($this->_validate_update($table) === FALSE) - { - return FALSE; - } - - if ($where !== NULL) - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit); - } - - $sql = $this->_update($this->qb_from[0], $this->qb_set); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Validate Update - * - * This method is used by both update() and get_compiled_update() to - * validate that data is actually being set and that a table has been - * chosen to be update. - * - * @param string the table to update data on - * @return bool - */ - protected function _validate_update($table) - { - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table !== '') - { - $this->qb_from = array($this->protect_identifiers($table, TRUE, NULL, FALSE)); - } - elseif ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch - * - * Compiles an update string and runs the query - * - * @param string the table to retrieve the results from - * @param array an associative array of update values - * @param string the where key - * @return int number of rows affected or FALSE on failure - */ - public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 100) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($index === NULL) - { - return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE; - } - - if ($set === NULL) - { - if (empty($this->qb_set)) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - } - else - { - if (empty($set)) - { - return ($this->db_debug) ? $this->display_error('update_batch() called with no data') : FALSE; - } - - $this->set_update_batch($set, $index); - } - - if (strlen($table) === 0) - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - // Batch this baby - $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) - { - $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index))); - $affected_rows += $this->affected_rows(); - $this->qb_where = array(); - } - - $this->_reset_write(); - return $affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * The "set_update_batch" function. Allows key/value pairs to be set for batch updating - * - * @param array - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set_update_batch($key, $index = '', $escape = NULL) - { - $key = $this->_object_to_array_batch($key); - - if ( ! is_array($key)) - { - // @todo error - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $index_set = FALSE; - $clean = array(); - foreach ($v as $k2 => $v2) - { - if ($k2 === $index) - { - $index_set = TRUE; - } - - $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2); - } - - if ($index_set === FALSE) - { - return $this->display_error('db_batch_missing_index'); - } - - $this->qb_set[] = $clean; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Empty Table - * - * Compiles a delete string and runs "DELETE FROM table" - * - * @param string the table to empty - * @return bool TRUE on success, FALSE on failure - */ - public function empty_table($table = '') - { - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - $sql = $this->_delete($table); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Truncate - * - * Compiles a truncate string and runs the query - * If the database does not support the truncate() command - * This function maps to "DELETE FROM table" - * - * @param string the table to truncate - * @return bool TRUE on success, FALSE on failure - */ - public function truncate($table = '') - { - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - $sql = $this->_truncate($table); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the truncate() command, - * then this method maps to 'DELETE FROM table' - * - * @param string the table name - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Get DELETE query string - * - * Compiles a delete query string and returns the sql - * - * @param string the table to delete from - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_delete($table = '', $reset = TRUE) - { - $this->return_delete_sql = TRUE; - $sql = $this->delete($table, '', NULL, $reset); - $this->return_delete_sql = FALSE; - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Delete - * - * Compiles a delete string and runs the query - * - * @param mixed the table(s) to delete from. String or array - * @param mixed the where clause - * @param mixed the limit clause - * @param bool - * @return mixed - */ - public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - elseif (is_array($table)) - { - empty($where) && $reset_data = FALSE; - - foreach ($table as $single_table) - { - $this->delete($single_table, $where, $limit, $reset_data); - } - - return; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - if ($where !== '') - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit); - } - - if (count($this->qb_where) === 0) - { - return ($this->db_debug) ? $this->display_error('db_del_must_use_where') : FALSE; - } - - $sql = $this->_delete($table); - if ($reset_data) - { - $this->_reset_write(); - } - - return ($this->return_delete_sql === TRUE) ? $sql : $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - return 'DELETE FROM '.$table.$this->_compile_wh('qb_where') - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); - } - - // -------------------------------------------------------------------- - - /** - * DB Prefix - * - * Prepends a database prefix if one exists in configuration - * - * @param string the table - * @return string - */ - public function dbprefix($table = '') - { - if ($table === '') - { - $this->display_error('db_table_name_required'); - } - - return $this->dbprefix.$table; - } - - // -------------------------------------------------------------------- - - /** - * Set DB Prefix - * - * Set's the DB Prefix to something new without needing to reconnect - * - * @param string the prefix - * @return string - */ - public function set_dbprefix($prefix = '') - { - return $this->dbprefix = $prefix; - } - - // -------------------------------------------------------------------- - - /** - * Track Aliases - * - * Used to track SQL statements written with aliased tables. - * - * @param string The table to inspect - * @return string - */ - protected function _track_aliases($table) - { - if (is_array($table)) - { - foreach ($table as $t) - { - $this->_track_aliases($t); - } - return; - } - - // Does the string contain a comma? If so, we need to separate - // the string into discreet statements - if (strpos($table, ',') !== FALSE) - { - return $this->_track_aliases(explode(',', $table)); - } - - // if a table alias is used we can recognize it by a space - if (strpos($table, ' ') !== FALSE) - { - // if the alias is written with the AS keyword, remove it - $table = preg_replace('/\s+AS\s+/i', ' ', $table); - - // Grab the alias - $table = trim(strrchr($table, ' ')); - - // Store the alias, if it doesn't already exist - if ( ! in_array($table, $this->qb_aliased_tables)) - { - $this->qb_aliased_tables[] = $table; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Compile the SELECT statement - * - * Generates a query string based on which functions were used. - * Should not be called directly. - * - * @param bool $select_override - * @return string - */ - protected function _compile_select($select_override = FALSE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - // Write the "select" portion of the query - if ($select_override !== FALSE) - { - $sql = $select_override; - } - else - { - $sql = ( ! $this->qb_distinct) ? 'SELECT ' : 'SELECT DISTINCT '; - - if (count($this->qb_select) === 0) - { - $sql .= '*'; - } - else - { - // Cycle through the "select" portion of the query and prep each column name. - // The reason we protect identifiers here rather than in the select() function - // is because until the user calls the from() function we don't know if there are aliases - foreach ($this->qb_select as $key => $val) - { - $no_escape = isset($this->qb_no_escape[$key]) ? $this->qb_no_escape[$key] : NULL; - $this->qb_select[$key] = $this->protect_identifiers($val, FALSE, $no_escape); - } - - $sql .= implode(', ', $this->qb_select); - } - } - - // Write the "FROM" portion of the query - if (count($this->qb_from) > 0) - { - $sql .= "\nFROM ".$this->_from_tables(); - } - - // Write the "JOIN" portion of the query - if (count($this->qb_join) > 0) - { - $sql .= "\n".implode("\n", $this->qb_join); - } - - $sql .= $this->_compile_wh('qb_where') - .$this->_compile_group_by() - .$this->_compile_wh('qb_having') - .$this->_compile_order_by(); // ORDER BY - - // LIMIT - if ($this->qb_limit) - { - return $this->_limit($sql."\n"); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Compile WHERE, HAVING statements - * - * Escapes identifiers in WHERE and HAVING statements at execution time. - * - * Required so that aliases are tracked properly, regardless of whether - * where(), or_where(), having(), or_having are called prior to from(), - * join() and dbprefix is added only if needed. - * - * @param string $qb_key 'qb_where' or 'qb_having' - * @return string SQL statement - */ - protected function _compile_wh($qb_key) - { - if (count($this->$qb_key) > 0) - { - for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++) - { - // Is this condition already compiled? - if (is_string($this->{$qb_key}[$i])) - { - continue; - } - elseif ($this->{$qb_key}[$i]['escape'] === FALSE) - { - $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition']; - continue; - } - - // Split multiple conditions - $conditions = preg_split( - '/((?:^|\s+)AND\s+|(?:^|\s+)OR\s+)/i', - $this->{$qb_key}[$i]['condition'], - -1, - PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY - ); - - for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++) - { - if (($op = $this->_get_operator($conditions[$ci])) === FALSE - OR ! preg_match('/^(\(?)(.*)('.preg_quote($op, '/').')\s*(.*(? '(test <= foo)', /* the whole thing */ - // 1 => '(', /* optional */ - // 2 => 'test', /* the field name */ - // 3 => ' <= ', /* $op */ - // 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */ - // 5 => ')' /* optional */ - // ); - - if ( ! empty($matches[4])) - { - $this->_is_literal($matches[4]) OR $matches[4] = $this->protect_identifiers(trim($matches[4])); - $matches[4] = ' '.$matches[4]; - } - - $conditions[$ci] = $matches[1].$this->protect_identifiers(trim($matches[2])) - .' '.trim($matches[3]).$matches[4].$matches[5]; - } - - $this->{$qb_key}[$i] = implode('', $conditions); - } - - return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ") - .implode("\n", $this->$qb_key); - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Compile GROUP BY - * - * Escapes identifiers in GROUP BY statements at execution time. - * - * Required so that aliases are tracked properly, regardless of wether - * group_by() is called prior to from(), join() and dbprefix is added - * only if needed. - * - * @return string SQL statement - */ - protected function _compile_group_by() - { - if (count($this->qb_groupby) > 0) - { - for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++) - { - // Is it already compiled? - if (is_string($this->qb_groupby[$i])) - { - continue; - } - - $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field'])) - ? $this->qb_groupby[$i]['field'] - : $this->protect_identifiers($this->qb_groupby[$i]['field']); - } - - return "\nGROUP BY ".implode(', ', $this->qb_groupby); - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Compile ORDER BY - * - * Escapes identifiers in ORDER BY statements at execution time. - * - * Required so that aliases are tracked properly, regardless of wether - * order_by() is called prior to from(), join() and dbprefix is added - * only if needed. - * - * @return string SQL statement - */ - protected function _compile_order_by() - { - if (is_array($this->qb_orderby) && count($this->qb_orderby) > 0) - { - for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++) - { - if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field'])) - { - $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']); - } - - $this->qb_orderby[$i] = $this->qb_orderby[$i]['field'].$this->qb_orderby[$i]['direction']; - } - - return $this->qb_orderby = "\nORDER BY ".implode(', ', $this->qb_orderby); - } - elseif (is_string($this->qb_orderby)) - { - return $this->qb_orderby; - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Object to Array - * - * Takes an object as input and converts the class variables to array key/vals - * - * @param object - * @return array - */ - protected function _object_to_array($object) - { - if ( ! is_object($object)) - { - return $object; - } - - $array = array(); - foreach (get_object_vars($object) as $key => $val) - { - // There are some built in keys we need to ignore for this conversion - if ( ! is_object($val) && ! is_array($val) && $key !== '_parent_name') - { - $array[$key] = $val; - } - } - - return $array; - } - - // -------------------------------------------------------------------- - - /** - * Object to Array - * - * Takes an object as input and converts the class variables to array key/vals - * - * @param object - * @return array - */ - protected function _object_to_array_batch($object) - { - if ( ! is_object($object)) - { - return $object; - } - - $array = array(); - $out = get_object_vars($object); - $fields = array_keys($out); - - foreach ($fields as $val) - { - // There are some built in keys we need to ignore for this conversion - if ($val !== '_parent_name') - { - $i = 0; - foreach ($out[$val] as $data) - { - $array[$i++][$val] = $data; - } - } - } - - return $array; - } - - // -------------------------------------------------------------------- - - /** - * Start Cache - * - * Starts QB caching - * - * @return FW_DB_query_builder - */ - public function start_cache() - { - $this->qb_caching = TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Stop Cache - * - * Stops QB caching - * - * @return FW_DB_query_builder - */ - public function stop_cache() - { - $this->qb_caching = FALSE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Flush Cache - * - * Empties the QB cache - * - * @return FW_DB_query_builder - */ - public function flush_cache() - { - $this->_reset_run(array( - 'qb_cache_select' => array(), - 'qb_cache_from' => array(), - 'qb_cache_join' => array(), - 'qb_cache_where' => array(), - 'qb_cache_groupby' => array(), - 'qb_cache_having' => array(), - 'qb_cache_orderby' => array(), - 'qb_cache_set' => array(), - 'qb_cache_exists' => array(), - 'qb_cache_no_escape' => array() - )); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Merge Cache - * - * When called, this function merges any cached QB arrays with - * locally called ones. - * - * @return void - */ - protected function _merge_cache() - { - if (count($this->qb_cache_exists) === 0) - { - return; - } - elseif (in_array('select', $this->qb_cache_exists, TRUE)) - { - $qb_no_escape = $this->qb_cache_no_escape; - } - - foreach (array_unique($this->qb_cache_exists) as $val) // select, from, etc. - { - $qb_variable = 'qb_'.$val; - $qb_cache_var = 'qb_cache_'.$val; - $qb_new = $this->$qb_cache_var; - - for ($i = 0, $c = count($this->$qb_variable); $i < $c; $i++) - { - if ( ! in_array($this->{$qb_variable}[$i], $qb_new, TRUE)) - { - $qb_new[] = $this->{$qb_variable}[$i]; - if ($val === 'select') - { - $qb_no_escape[] = $this->qb_no_escape[$i]; - } - } - } - - $this->$qb_variable = $qb_new; - if ($val === 'select') - { - $this->qb_no_escape = $qb_no_escape; - } - } - - // If we are "protecting identifiers" we need to examine the "from" - // portion of the query to determine if there are any aliases - if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0) - { - $this->_track_aliases($this->qb_from); - } - } - - // -------------------------------------------------------------------- - - /** - * Is literal - * - * Determines if a string represents a literal value or a field name - * - * @param string $str - * @return bool - */ - protected function _is_literal($str) - { - $str = trim($str); - - if (empty($str) OR ctype_digit($str) OR (string) (float) $str === $str OR in_array(strtoupper($str), array('TRUE', 'FALSE'), TRUE)) - { - return TRUE; - } - - static $_str; - - if (empty($_str)) - { - $_str = ($this->_escape_char !== '"') - ? array('"', "'") : array("'"); - } - - return in_array($str[0], $_str, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Reset Query Builder values. - * - * Publicly-visible method to reset the QB values. - * - * @return FW_DB_query_builder - */ - public function reset_query() - { - $this->_reset_select(); - $this->_reset_write(); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder values. Called by the get() function - * - * @param array An array of fields to reset - * @return void - */ - protected function _reset_run($qb_reset_items) - { - foreach ($qb_reset_items as $item => $default_value) - { - $this->$item = $default_value; - } - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder values. Called by the get() function - * - * @return void - */ - protected function _reset_select() - { - $this->_reset_run(array( - 'qb_select' => array(), - 'qb_from' => array(), - 'qb_join' => array(), - 'qb_where' => array(), - 'qb_groupby' => array(), - 'qb_having' => array(), - 'qb_orderby' => array(), - 'qb_aliased_tables' => array(), - 'qb_no_escape' => array(), - 'qb_distinct' => FALSE, - 'qb_limit' => FALSE, - 'qb_offset' => FALSE - )); - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder "write" values. - * - * Called by the insert() update() insert_batch() update_batch() and delete() functions - * - * @return void - */ - protected function _reset_write() - { - $this->_reset_run(array( - 'qb_set' => array(), - 'qb_from' => array(), - 'qb_join' => array(), - 'qb_where' => array(), - 'qb_orderby' => array(), - 'qb_keys' => array(), - 'qb_limit' => FALSE - )); - } - -} diff --git a/src/Database/DB_result.php b/src/Database/DB_result.php deleted file mode 100644 index 7882a2e..0000000 --- a/src/Database/DB_result.php +++ /dev/null @@ -1,666 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Result Class - * - * This is the platform-independent result class. - * This class will not be called directly. Rather, the adapter - * class for the specific database will extend and instantiate it. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_result { - - /** - * Connection ID - * - * @var resource|object - */ - public $conn_id; - - /** - * Result ID - * - * @var resource|object - */ - public $result_id; - - /** - * Result Array - * - * @var array[] - */ - public $result_array = array(); - - /** - * Result Object - * - * @var object[] - */ - public $result_object = array(); - - /** - * Custom Result Object - * - * @var object[] - */ - public $custom_result_object = array(); - - /** - * Current Row index - * - * @var int - */ - public $current_row = 0; - - /** - * Number of rows - * - * @var int - */ - public $num_rows; - - /** - * Row data - * - * @var array - */ - public $row_data; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object $driver_object - * @return void - */ - public function __construct(&$driver_object) - { - $this->conn_id = $driver_object->conn_id; - $this->result_id = $driver_object->result_id; - } - - // -------------------------------------------------------------------- - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Query result. Acts as a wrapper function for the following functions. - * - * @param string $type 'object', 'array' or a custom class name - * @return array - */ - public function result($type = 'object') - { - if ($type === 'array') - { - return $this->result_array(); - } - elseif ($type === 'object') - { - return $this->result_object(); - } - else - { - return $this->custom_result_object($type); - } - } - - // -------------------------------------------------------------------- - - /** - * Custom query result. - * - * @param string $class_name - * @return array - */ - public function custom_result_object($class_name) - { - if (isset($this->custom_result_object[$class_name])) - { - return $this->custom_result_object[$class_name]; - } - elseif ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - // Don't fetch the result set again if we already have it - $_data = NULL; - if (($c = count($this->result_array)) > 0) - { - $_data = 'result_array'; - } - elseif (($c = count($this->result_object)) > 0) - { - $_data = 'result_object'; - } - - if ($_data !== NULL) - { - for ($i = 0; $i < $c; $i++) - { - $this->custom_result_object[$class_name][$i] = new $class_name(); - - foreach ($this->{$_data}[$i] as $key => $value) - { - $this->custom_result_object[$class_name][$i]->$key = $value; - } - } - - return $this->custom_result_object[$class_name]; - } - - is_null($this->row_data) OR $this->data_seek(0); - $this->custom_result_object[$class_name] = array(); - - while ($row = $this->_fetch_object($class_name)) - { - $this->custom_result_object[$class_name][] = $row; - } - - return $this->custom_result_object[$class_name]; - } - - // -------------------------------------------------------------------- - - /** - * Query result. "object" version. - * - * @return array - */ - public function result_object() - { - if (count($this->result_object) > 0) - { - return $this->result_object; - } - - // In the event that query caching is on, the result_id variable - // will not be a valid resource so we'll simply return an empty - // array. - if ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - if (($c = count($this->result_array)) > 0) - { - for ($i = 0; $i < $c; $i++) - { - $this->result_object[$i] = (object) $this->result_array[$i]; - } - - return $this->result_object; - } - - is_null($this->row_data) OR $this->data_seek(0); - while ($row = $this->_fetch_object()) - { - $this->result_object[] = $row; - } - - return $this->result_object; - } - - // -------------------------------------------------------------------- - - /** - * Query result. "array" version. - * - * @return array - */ - public function result_array() - { - if (count($this->result_array) > 0) - { - return $this->result_array; - } - - // In the event that query caching is on, the result_id variable - // will not be a valid resource so we'll simply return an empty - // array. - if ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - if (($c = count($this->result_object)) > 0) - { - for ($i = 0; $i < $c; $i++) - { - $this->result_array[$i] = (array) $this->result_object[$i]; - } - - return $this->result_array; - } - - is_null($this->row_data) OR $this->data_seek(0); - while ($row = $this->_fetch_assoc()) - { - $this->result_array[] = $row; - } - - return $this->result_array; - } - - // -------------------------------------------------------------------- - - /** - * Row - * - * A wrapper method. - * - * @param mixed $n - * @param string $type 'object' or 'array' - * @return mixed - */ - public function row($n = 0, $type = 'object') - { - if ( ! is_numeric($n)) - { - // We cache the row data for subsequent uses - is_array($this->row_data) OR $this->row_data = $this->row_array(0); - - // array_key_exists() instead of isset() to allow for NULL values - if (empty($this->row_data) OR ! array_key_exists($n, $this->row_data)) - { - return NULL; - } - - return $this->row_data[$n]; - } - - if ($type === 'object') return $this->row_object($n); - elseif ($type === 'array') return $this->row_array($n); - else return $this->custom_row_object($n, $type); - } - - // -------------------------------------------------------------------- - - /** - * Assigns an item into a particular column slot - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function set_row($key, $value = NULL) - { - // We cache the row data for subsequent uses - if ( ! is_array($this->row_data)) - { - $this->row_data = $this->row_array(0); - } - - if (is_array($key)) - { - foreach ($key as $k => $v) - { - $this->row_data[$k] = $v; - } - return; - } - - if ($key !== '' && $value !== NULL) - { - $this->row_data[$key] = $value; - } - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - custom object version - * - * @param int $n - * @param string $type - * @return object - */ - public function custom_row_object($n, $type) - { - isset($this->custom_result_object[$type]) OR $this->custom_result_object($type); - - if (count($this->custom_result_object[$type]) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($this->custom_result_object[$type][$n])) - { - $this->current_row = $n; - } - - return $this->custom_result_object[$type][$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - object version - * - * @param int $n - * @return object - */ - public function row_object($n = 0) - { - $result = $this->result_object(); - if (count($result) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($result[$n])) - { - $this->current_row = $n; - } - - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - array version - * - * @param int $n - * @return array - */ - public function row_array($n = 0) - { - $result = $this->result_array(); - if (count($result) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($result[$n])) - { - $this->current_row = $n; - } - - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "first" row - * - * @param string $type - * @return mixed - */ - public function first_row($type = 'object') - { - $result = $this->result($type); - return (count($result) === 0) ? NULL : $result[0]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "last" row - * - * @param string $type - * @return mixed - */ - public function last_row($type = 'object') - { - $result = $this->result($type); - return (count($result) === 0) ? NULL : $result[count($result) - 1]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "next" row - * - * @param string $type - * @return mixed - */ - public function next_row($type = 'object') - { - $result = $this->result($type); - if (count($result) === 0) - { - return NULL; - } - - return isset($result[$this->current_row + 1]) - ? $result[++$this->current_row] - : NULL; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "previous" row - * - * @param string $type - * @return mixed - */ - public function previous_row($type = 'object') - { - $result = $this->result($type); - if (count($result) === 0) - { - return NULL; - } - - if (isset($result[$this->current_row - 1])) - { - --$this->current_row; - } - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an unbuffered row and move pointer to next row - * - * @param string $type 'array', 'object' or a custom class name - * @return mixed - */ - public function unbuffered_row($type = 'object') - { - if ($type === 'array') - { - return $this->_fetch_assoc(); - } - elseif ($type === 'object') - { - return $this->_fetch_object(); - } - - return $this->_fetch_object($type); - } - - // -------------------------------------------------------------------- - - /** - * The following methods are normally overloaded by the identically named - * methods in the platform-specific driver -- except when query caching - * is used. When caching is enabled we do not load the other driver. - * These functions are primarily here to prevent undefined function errors - * when a cached result object is in use. They are not otherwise fully - * operational due to the unavailability of the database resource IDs with - * cached results. - */ - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * Overridden by driver result classes. - * - * @return int - */ - public function num_fields() - { - return 0; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names. - * - * Overridden by driver result classes. - * - * @return array - */ - public function list_fields() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data. - * - * Overridden by driver result classes. - * - * @return array - */ - public function field_data() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * Overridden by driver result classes. - * - * @return void - */ - public function free_result() - { - $this->result_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * Overridden by driver result classes. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array. - * - * Overridden by driver result classes. - * - * @return array - */ - protected function _fetch_assoc() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object. - * - * Overridden by driver result classes. - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return array(); - } - -} diff --git a/src/Database/DB_utility.php b/src/Database/DB_utility.php deleted file mode 100644 index 321c83a..0000000 --- a/src/Database/DB_utility.php +++ /dev/null @@ -1,434 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Helpers; -use FuzeWorks\Libraries; -use Fuzeworks\Factory; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_utility { - - /** - * Database object - * - * @var object - */ - protected $db; - - // -------------------------------------------------------------------- - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = FALSE; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = FALSE; - - /** - * REPAIR TABLE statement - * - * @var string - */ - protected $_repair_table = FALSE; - - /** - * The FuzeWorks factory class - * - * @var Fuzeworks\Factory; - */ - private $factory; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - $this->factory = Factory::getInstance(); - Logger::log('Database Utility Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * List databases - * - * @return array - */ - public function list_databases() - { - // Is there a cached result? - if (isset($this->db->data_cache['db_names'])) - { - return $this->db->data_cache['db_names']; - } - elseif ($this->_list_databases === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $this->db->data_cache['db_names'] = array(); - - $query = $this->db->query($this->_list_databases); - if ($query === FALSE) - { - return $this->db->data_cache['db_names']; - } - - for ($i = 0, $query = $query->result_array(), $c = count($query); $i < $c; $i++) - { - $this->db->data_cache['db_names'][] = current($query[$i]); - } - - return $this->db->data_cache['db_names']; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular database exists - * - * @param string $database_name - * @return bool - */ - public function database_exists($database_name) - { - return in_array($database_name, $this->list_databases()); - } - - // -------------------------------------------------------------------- - - /** - * Optimize Table - * - * @param string $table_name - * @return mixed - */ - public function optimize_table($table_name) - { - if ($this->_optimize_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name))); - if ($query !== FALSE) - { - $query = $query->result_array(); - return current($query); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Optimize Database - * - * @return mixed - */ - public function optimize_database() - { - if ($this->_optimize_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $result = array(); - foreach ($this->db->list_tables() as $table_name) - { - $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name))); - if (is_bool($res)) - { - return $res; - } - - // Build the result array... - $res = $res->result_array(); - $res = current($res); - $key = str_replace($this->db->database.'.', '', current($res)); - $keys = array_keys($res); - unset($res[$keys[0]]); - - $result[$key] = $res; - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Repair Table - * - * @param string $table_name - * @return mixed - */ - public function repair_table($table_name) - { - if ($this->_repair_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name))); - if (is_bool($query)) - { - return $query; - } - - $query = $query->result_array(); - return current($query); - } - - // -------------------------------------------------------------------- - - /** - * Generate CSV from a query result object - * - * @param object $query Query result object - * @param string $delim Delimiter (default: ,) - * @param string $newline Newline character (default: \n) - * @param string $enclosure Enclosure (default: ") - * @return string - */ - public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"') - { - if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) - { - throw new DatabaseException('You must submit a valid result object', 1); - } - - $out = ''; - // First generate the headings from the table column names - foreach ($query->list_fields() as $name) - { - $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim; - } - - $out = substr($out, 0, -strlen($delim)).$newline; - - // Next blast through the result array and build out the rows - while ($row = $query->unbuffered_row('array')) - { - $line = array(); - foreach ($row as $item) - { - $line[] = $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure; - } - $out .= implode($delim, $line).$newline; - } - - return $out; - } - - // -------------------------------------------------------------------- - - /** - * Generate XML data from a query result object - * - * @param object $query Query result object - * @param array $params Any preferences - * @return string - */ - public function xml_from_result($query, $params = array()) - { - if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) - { - throw new DatabaseException('You must submit a valid result object', 1); - } - - // Set our default values - foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val) - { - if ( ! isset($params[$key])) - { - $params[$key] = $val; - } - } - - // Create variables for convenience - extract($params); - - // Load the xml helper - $this->factory->helpers->load('xml'); - - // Generate the result - $xml = '<'.$root.'>'.$newline; - while ($row = $query->unbuffered_row()) - { - $xml .= $tab.'<'.$element.'>'.$newline; - foreach ($row as $key => $val) - { - $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).''.$newline; - } - $xml .= $tab.''.$newline; - } - - return $xml.''.$newline; - } - - // -------------------------------------------------------------------- - - /** - * Database Backup - * - * @param array $params - * @return string - */ - public function backup($params = array()) - { - // If the parameters have not been submitted as an - // array then we know that it is simply the table - // name, which is a valid short cut. - if (is_string($params)) - { - $params = array('tables' => $params); - } - - // Set up our default preferences - $prefs = array( - 'tables' => array(), - 'ignore' => array(), - 'filename' => '', - 'format' => 'gzip', // gzip, zip, txt - 'add_drop' => TRUE, - 'add_insert' => TRUE, - 'newline' => "\n", - 'foreign_key_checks' => TRUE - ); - - // Did the user submit any preferences? If so set them.... - if (count($params) > 0) - { - foreach ($prefs as $key => $val) - { - if (isset($params[$key])) - { - $prefs[$key] = $params[$key]; - } - } - } - - // Are we backing up a complete database or individual tables? - // If no table names were submitted we'll fetch the entire table list - if (count($prefs['tables']) === 0) - { - $prefs['tables'] = $this->db->list_tables(); - } - - // Validate the format - if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE)) - { - $prefs['format'] = 'txt'; - } - - // Is the encoder supported? If not, we'll either issue an - // error or use plain text depending on the debug settings - if (($prefs['format'] === 'gzip' && ! function_exists('gzencode')) - OR ($prefs['format'] === 'zip' && ! function_exists('gzcompress'))) - { - if ($this->db->db_debug) - { - return $this->db->display_error('db_unsupported_compression'); - } - - $prefs['format'] = 'txt'; - } - - // Was a Zip file requested? - if ($prefs['format'] === 'zip') - { - // Set the filename if not provided (only needed with Zip files) - if ($prefs['filename'] === '') - { - $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database) - .date('Y-m-d_H-i', time()).'.sql'; - } - else - { - // If they included the .zip file extension we'll remove it - if (preg_match('|.+?\.zip$|', $prefs['filename'])) - { - $prefs['filename'] = str_replace('.zip', '', $prefs['filename']); - } - - // Tack on the ".sql" file extension if needed - if ( ! preg_match('|.+?\.sql$|', $prefs['filename'])) - { - $prefs['filename'] .= '.sql'; - } - } - - // Load the Zip class and output it - $zip = Libraries::get('zip'); - $zip->add_data($prefs['filename'], $this->_backup($prefs)); - return $zip->get_zip(); - } - elseif ($prefs['format'] === 'txt') // Was a text file requested? - { - return $this->_backup($prefs); - } - elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested? - { - return gzencode($this->_backup($prefs)); - } - - return; - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_driver.php b/src/Database/drivers/cubrid/cubrid_driver.php deleted file mode 100644 index ac3c141..0000000 --- a/src/Database/drivers/cubrid/cubrid_driver.php +++ /dev/null @@ -1,401 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'cubrid'; - - /** - * Auto-commit flag - * - * @var bool - */ - public $auto_commit = TRUE; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches)) - { - if (stripos($matches[2], 'autocommit=off') !== FALSE) - { - $this->auto_commit = FALSE; - } - } - else - { - // If no port is defined by the user, use the default value - empty($this->port) OR $this->port = 33000; - } - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:([^:]*):([^:]*):(\?.+)?$/', $this->dsn, $matches)) - { - $func = ($persistent !== TRUE) ? 'cubrid_connect_with_url' : 'cubrid_pconnect_with_url'; - return ($matches[2] === '' && $matches[3] === '' && $this->username !== '' && $this->password !== '') - ? $func($this->dsn, $this->username, $this->password) - : $func($this->dsn); - } - - $func = ($persistent !== TRUE) ? 'cubrid_connect' : 'cubrid_pconnect'; - return ($this->username !== '') - ? $func($this->hostname, $this->port, $this->database, $this->username, $this->password) - : $func($this->hostname, $this->port, $this->database); - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if (cubrid_ping($this->conn_id) === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - return ( ! $this->conn_id OR ($version = cubrid_get_server_info($this->conn_id)) === FALSE) - ? FALSE - : $this->data_cache['version'] = $version; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return cubrid_query($sql, $this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - if (($autocommit = cubrid_get_autocommit($this->conn_id)) === NULL) - { - return FALSE; - } - elseif ($autocommit === TRUE) - { - return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if ( ! cubrid_commit($this->conn_id)) - { - return FALSE; - } - - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) - { - return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if ( ! cubrid_rollback($this->conn_id)) - { - return FALSE; - } - - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) - { - cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return cubrid_real_escape_string($str, $this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return cubrid_affected_rows(); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return cubrid_insert_id($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - cubrid_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_forge.php b/src/Database/drivers/cubrid/cubrid_forge.php deleted file mode 100644 index 0063235..0000000 --- a/src/Database/drivers/cubrid/cubrid_forge.php +++ /dev/null @@ -1,224 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SHORT' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'BIGINT' => 'NUMERIC', - 'FLOAT' => 'DOUBLE', - 'REAL' => 'DOUBLE' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $sqls[] = $sql.' CHANGE '.$field[$i]['_literal']; - } - else - { - $alter_type = empty($field[$i]['new_name']) ? ' MODIFY ' : ' CHANGE '; - $sqls[] = $sql.$alter_type.$this->_process_column($field[$i]); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_result.php b/src/Database/drivers/cubrid/cubrid_result.php deleted file mode 100644 index ceff132..0000000 --- a/src/Database/drivers/cubrid/cubrid_result.php +++ /dev/null @@ -1,174 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = cubrid_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return cubrid_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - return cubrid_column_names($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = cubrid_field_name($this->result_id, $i); - $retval[$i]->type = cubrid_field_type($this->result_id, $i); - $retval[$i]->max_length = cubrid_field_len($this->result_id, $i); - $retval[$i]->primary_key = (int) (strpos(cubrid_field_flags($this->result_id, $i), 'primary_key') !== FALSE); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id) OR - (get_resource_type($this->result_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->result_id)))) - { - cubrid_close_request($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return cubrid_data_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return cubrid_fetch_assoc($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return cubrid_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_utility.php b/src/Database/drivers/cubrid/cubrid_utility.php deleted file mode 100644 index a0bc94b..0000000 --- a/src/Database/drivers/cubrid/cubrid_utility.php +++ /dev/null @@ -1,76 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_utility extends FW_DB_utility { - - /** - * List databases - * - * @return array - */ - public function list_databases() - { - if (isset($this->db->data_cache['db_names'])) - { - return $this->db->data_cache['db_names']; - } - - return $this->db->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * CUBRID Export - * - * @param array Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // No SQL based support in CUBRID as of version 8.4.0. Database or - // table backup can be performed using CUBRID Manager - // database administration tool. - return $this->db->display_error('db_unsupported_feature'); - } -} diff --git a/src/Database/drivers/ibase/ibase_driver.php b/src/Database/drivers/ibase/ibase_driver.php deleted file mode 100644 index 099c92d..0000000 --- a/src/Database/drivers/ibase/ibase_driver.php +++ /dev/null @@ -1,392 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Firebird/Interbase Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'ibase'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND()'); - - /** - * IBase Transaction status flag - * - * @var resource - */ - protected $_ibase_trans; - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - return ($persistent === TRUE) - ? ibase_pconnect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set) - : ibase_connect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if (($service = ibase_service_attach($this->hostname, $this->username, $this->password))) - { - $this->data_cache['version'] = ibase_server_info($service, IBASE_SVC_SERVER_VERSION); - - // Don't keep the service open - ibase_service_detach($service); - return $this->data_cache['version']; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return ibase_query(isset($this->_ibase_trans) ? $this->_ibase_trans : $this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - if (($trans_handle = ibase_trans($this->conn_id)) === FALSE) - { - return FALSE; - } - - $this->_ibase_trans = $trans_handle; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if (ibase_commit($this->_ibase_trans)) - { - $this->_ibase_trans = NULL; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if (ibase_rollback($this->_ibase_trans)) - { - $this->_ibase_trans = NULL; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return ibase_affected_rows($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $generator_name - * @param int $inc_by - * @return int - */ - public function insert_id($generator_name, $inc_by = 0) - { - //If a generator hasn't been used before it will return 0 - return ibase_gen_id('"'.$generator_name.'"', $inc_by); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT TRIM("RDB$RELATION_NAME") AS TABLE_NAME FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\''; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' AND TRIM("RDB$RELATION_NAME") AS TABLE_NAME LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT TRIM("RDB$FIELD_NAME") AS COLUMN_NAME FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "rfields"."RDB$FIELD_NAME" AS "name", - CASE "fields"."RDB$FIELD_TYPE" - WHEN 7 THEN \'SMALLINT\' - WHEN 8 THEN \'INTEGER\' - WHEN 9 THEN \'QUAD\' - WHEN 10 THEN \'FLOAT\' - WHEN 11 THEN \'DFLOAT\' - WHEN 12 THEN \'DATE\' - WHEN 13 THEN \'TIME\' - WHEN 14 THEN \'CHAR\' - WHEN 16 THEN \'INT64\' - WHEN 27 THEN \'DOUBLE\' - WHEN 35 THEN \'TIMESTAMP\' - WHEN 37 THEN \'VARCHAR\' - WHEN 40 THEN \'CSTRING\' - WHEN 261 THEN \'BLOB\' - ELSE NULL - END AS "type", - "fields"."RDB$FIELD_LENGTH" AS "max_length", - "rfields"."RDB$DEFAULT_VALUE" AS "default" - FROM "RDB$RELATION_FIELDS" "rfields" - JOIN "RDB$FIELDS" "fields" ON "rfields"."RDB$FIELD_SOURCE" = "fields"."RDB$FIELD_NAME" - WHERE "rfields"."RDB$RELATION_NAME" = '.$this->escape($table).' - ORDER BY "rfields"."RDB$FIELD_POSITION"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => ibase_errcode(), 'message' => ibase_errmsg()); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // Limit clause depends on if Interbase or Firebird - if (stripos($this->version(), 'firebird') !== FALSE) - { - $select = 'FIRST '.$this->qb_limit - .($this->qb_offset ? ' SKIP '.$this->qb_offset : ''); - } - else - { - $select = 'ROWS ' - .($this->qb_offset ? $this->qb_offset.' TO '.($this->qb_limit + $this->qb_offset) : $this->qb_limit); - } - - return preg_replace('`SELECT`i', 'SELECT '.$select, $sql, 1); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - ibase_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/ibase/ibase_forge.php b/src/Database/drivers/ibase/ibase_forge.php deleted file mode 100644 index 1cc3b5b..0000000 --- a/src/Database/drivers/ibase/ibase_forge.php +++ /dev/null @@ -1,248 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INTEGER' => 'INT64', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return string - */ - public function create_database($db_name) - { - // Firebird databases are flat files, so a path is required - - // Hostname is needed for remote access - empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name; - - return parent::create_database('"'.$db_name.'"'); - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! ibase_drop_db($this->conn_id)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identififers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = 'UPDATE "RDB$RELATION_FIELDS" SET "RDB$NULL_FLAG" = ' - .($field[$i]['null'] === TRUE ? 'NULL' : '1') - .' WHERE "RDB$FIELD_NAME" = '.$this->db->escape($field[$i]['name']) - .' AND "RDB$RELATION_NAME" = '.$this->db->escape($table); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INT': - $attributes['TYPE'] = 'INTEGER'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/ibase/ibase_result.php b/src/Database/drivers/ibase/ibase_result.php deleted file mode 100644 index 85b3219..0000000 --- a/src/Database/drivers/ibase/ibase_result.php +++ /dev/null @@ -1,158 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_result extends FW_DB_result { - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return ibase_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $num_fields = $this->num_fields(); $i < $num_fields; $i++) - { - $info = ibase_field_info($this->result_id, $i); - $field_names[] = $info['name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $info = ibase_field_info($this->result_id, $i); - - $retval[$i] = new stdClass(); - $retval[$i]->name = $info['name']; - $retval[$i]->type = $info['type']; - $retval[$i]->max_length = $info['length']; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - ibase_free_result($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return ibase_fetch_assoc($this->result_id, IBASE_FETCH_BLOBS); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = ibase_fetch_object($this->result_id, IBASE_FETCH_BLOBS); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} diff --git a/src/Database/drivers/ibase/ibase_utility.php b/src/Database/drivers/ibase/ibase_utility.php deleted file mode 100644 index 39ec8b9..0000000 --- a/src/Database/drivers/ibase/ibase_utility.php +++ /dev/null @@ -1,66 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_utility extends FW_DB_utility { - - /** - * Export - * - * @param string $filename - * @return mixed - */ - protected function _backup($filename) - { - if ($service = ibase_service_attach($this->db->hostname, $this->db->username, $this->db->password)) - { - $res = ibase_backup($service, $this->db->database, $filename.'.fbk'); - - // Close the service connection - ibase_service_detach($service); - return $res; - } - - return FALSE; - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_driver.php b/src/Database/drivers/mysqli/mysqli_driver.php deleted file mode 100644 index 6193313..0000000 --- a/src/Database/drivers/mysqli/mysqli_driver.php +++ /dev/null @@ -1,543 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * MySQLi Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'mysqli'; - - /** - * Compression flag - * - * @var bool - */ - public $compress = FALSE; - - /** - * DELETE hack flag - * - * Whether to use the MySQL "delete hack" which allows the number - * of affected rows to be shown. Uses a preg_replace when enabled, - * adding a bit more processing to all queries. - * - * @var bool - */ - public $delete_hack = TRUE; - - /** - * Strict ON flag - * - * Whether we're running in strict SQL mode. - * - * @var bool - */ - public $stricton; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - // -------------------------------------------------------------------- - - /** - * MySQLi object - * - * Has to be preserved without being assigned to $conn_id. - * - * @var MySQLi - */ - protected $_mysqli; - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - // Do we have a socket path? - if ($this->hostname[0] === '/') - { - $hostname = NULL; - $port = NULL; - $socket = $this->hostname; - } - else - { - // Persistent connection support was added in PHP 5.3.0 - $hostname = ($persistent === TRUE && Core::isPHP('5.3')) - ? 'p:'.$this->hostname : $this->hostname; - $port = empty($this->port) ? NULL : $this->port; - $socket = NULL; - } - - $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0; - $this->_mysqli = mysqli_init(); - - $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); - - if (isset($this->stricton)) - { - if ($this->stricton) - { - $this->_mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'); - } - else - { - $this->_mysqli->options(MYSQLI_INIT_COMMAND, - 'SET SESSION sql_mode = - REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( - @@sql_mode, - "STRICT_ALL_TABLES,", ""), - ",STRICT_ALL_TABLES", ""), - "STRICT_ALL_TABLES", ""), - "STRICT_TRANS_TABLES,", ""), - ",STRICT_TRANS_TABLES", ""), - "STRICT_TRANS_TABLES", "")' - ); - } - } - - if (is_array($this->encrypt)) - { - $ssl = array(); - empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key']; - empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert']; - empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca']; - empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath']; - empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher']; - - if ( ! empty($ssl)) - { - if (isset($this->encrypt['ssl_verify'])) - { - if ($this->encrypt['ssl_verify']) - { - defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT') && $this->_mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, TRUE); - } - // Apparently (when it exists), setting MYSQLI_OPT_SSL_VERIFY_SERVER_CERT - // to FALSE didn't do anything, so PHP 5.6.16 introduced yet another - // constant ... - // - // https://secure.php.net/ChangeLog-5.php#5.6.16 - // https://bugs.php.net/bug.php?id=68344 - elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) - { - $this->_mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, TRUE); - } - } - - $client_flags |= MYSQLI_CLIENT_SSL; - $this->_mysqli->ssl_set( - isset($ssl['key']) ? $ssl['key'] : NULL, - isset($ssl['cert']) ? $ssl['cert'] : NULL, - isset($ssl['ca']) ? $ssl['ca'] : NULL, - isset($ssl['capath']) ? $ssl['capath'] : NULL, - isset($ssl['cipher']) ? $ssl['cipher'] : NULL - ); - } - } - - if ($this->_mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags)) - { - // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails - if ( - ($client_flags & MYSQLI_CLIENT_SSL) - && version_compare($this->_mysqli->client_info, '5.7.3', '<=') - && empty($this->_mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value) - ) - { - $this->_mysqli->close(); - $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!'; - Logger::logError($message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; - } - - return $this->_mysqli; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if ($this->conn_id->select_db($database)) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string $charset - * @return bool - */ - protected function _db_set_charset($charset) - { - return $this->conn_id->set_charset($charset); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - return $this->data_cache['version'] = $this->conn_id->server_info; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return mixed - */ - protected function _execute($sql) - { - return $this->conn_id->query($this->_prep_query($sql)); - } - - // -------------------------------------------------------------------- - - /** - * Prep the query - * - * If needed, each database adapter can prep the query string - * - * @param string $sql an SQL query - * @return string - */ - protected function _prep_query($sql) - { - // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack - // modifies the query so that it a proper number of affected rows is returned. - if ($this->delete_hack === TRUE && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) - { - return trim($sql).' WHERE 1=1'; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - $this->conn_id->autocommit(FALSE); - return Core::isPHP('5.5') - ? $this->conn_id->begin_transaction() - : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if ($this->conn_id->commit()) - { - $this->conn_id->autocommit(TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if ($this->conn_id->rollback()) - { - $this->conn_id->autocommit(TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return $this->conn_id->real_escape_string($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return $this->conn_id->affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return $this->conn_id->insert_id; - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database); - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occurred. - * - * @return array - */ - public function error() - { - if ( ! empty($this->_mysqli->connect_errno)) - { - return array( - 'code' => $this->_mysqli->connect_errno, - 'message' => Core::isPHP('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error() - ); - } - - return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error); - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - $this->conn_id->close(); - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_forge.php b/src/Database/drivers/mysqli/mysqli_forge.php deleted file mode 100644 index aac9099..0000000 --- a/src/Database/drivers/mysqli/mysqli_forge.php +++ /dev/null @@ -1,240 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT', - 'SMALLINT', - 'MEDIUMINT', - 'INT', - 'INTEGER', - 'BIGINT', - 'REAL', - 'DOUBLE', - 'DOUBLE PRECISION', - 'FLOAT', - 'DECIMAL', - 'NUMERIC' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; - } - } - - if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) - { - $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; - } - - if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) - { - $sql .= ' COLLATE = '.$this->db->dbcollat; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = ($alter_type === 'ADD') - ? "\n\tADD ".$field[$i]['_literal'] - : "\n\tMODIFY ".$field[$i]['_literal']; - } - else - { - if ($alter_type === 'ADD') - { - $field[$i]['_literal'] = "\n\tADD "; - } - else - { - $field[$i]['_literal'] = empty($field[$i]['new_name']) ? "\n\tMODIFY " : "\n\tCHANGE "; - } - - $field[$i] = $field[$i]['_literal'].$this->_process_column($field[$i]); - } - } - - return array($sql.implode(',', $field)); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .(empty($field['comment']) ? '' : ' COMMENT '.$field['comment']) - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_result.php b/src/Database/drivers/mysqli/mysqli_result.php deleted file mode 100644 index 6039764..0000000 --- a/src/Database/drivers/mysqli/mysqli_result.php +++ /dev/null @@ -1,182 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = $this->result_id->num_rows; - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->field_count; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - $this->result_id->field_seek(0); - while ($field = $this->result_id->fetch_field()) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - $field_data = $this->result_id->fetch_fields(); - for ($i = 0, $c = count($field_data); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $field_data[$i]->name; - $retval[$i]->type = $field_data[$i]->type; - $retval[$i]->max_length = $field_data[$i]->max_length; - $retval[$i]->primary_key = (int) ($field_data[$i]->flags & 2); - $retval[$i]->default = $field_data[$i]->def; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id->free(); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return $this->result_id->data_seek($n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetch_assoc(); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return $this->result_id->fetch_object($class_name); - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_utility.php b/src/Database/drivers/mysqli/mysqli_utility.php deleted file mode 100644 index 0a0ab95..0000000 --- a/src/Database/drivers/mysqli/mysqli_utility.php +++ /dev/null @@ -1,209 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SHOW DATABASES'; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'OPTIMIZE TABLE %s'; - - /** - * REPAIR TABLE statement - * - * @var string - */ - protected $_repair_table = 'REPAIR TABLE %s'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - if (count($params) === 0) - { - return FALSE; - } - - // Extract the prefs for simplicity - extract($params); - - // Build the output - $output = ''; - - // Do we need to include a statement to disable foreign key checks? - if ($foreign_key_checks === FALSE) - { - $output .= 'SET foreign_key_checks = 0;'.$newline; - } - - foreach ( (array) $tables as $table) - { - // Is the table in the "ignore" list? - if (in_array($table, (array) $ignore, TRUE)) - { - continue; - } - - // Get the table schema - $query = $this->db->query('SHOW CREATE TABLE '.$this->db->escape_identifiers($this->db->database.'.'.$table)); - - // No result means the table name was invalid - if ($query === FALSE) - { - continue; - } - - // Write out the table schema - $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline; - - if ($add_drop === TRUE) - { - $output .= 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table).';'.$newline.$newline; - } - - $i = 0; - $result = $query->result_array(); - foreach ($result[0] as $val) - { - if ($i++ % 2) - { - $output .= $val.';'.$newline.$newline; - } - } - - // If inserts are not needed we're done... - if ($add_insert === FALSE) - { - continue; - } - - // Grab all the data from the current table - $query = $this->db->query('SELECT * FROM '.$this->db->protect_identifiers($table)); - - if ($query->num_rows() === 0) - { - continue; - } - - // Fetch the field names and determine if the field is an - // integer type. We use this info to decide whether to - // surround the data with quotes or not - - $i = 0; - $field_str = ''; - $is_int = array(); - while ($field = $query->result_id->fetch_field()) - { - // Most versions of MySQL store timestamp as a string - $is_int[$i] = in_array(strtolower($field->type), - array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), - TRUE); - - // Create a string of field names - $field_str .= $this->db->escape_identifiers($field->name).', '; - $i++; - } - - // Trim off the end comma - $field_str = preg_replace('/, $/' , '', $field_str); - - // Build the insert string - foreach ($query->result_array() as $row) - { - $val_str = ''; - - $i = 0; - foreach ($row as $v) - { - // Is the value NULL? - if ($v === NULL) - { - $val_str .= 'NULL'; - } - else - { - // Escape the data if it's not an integer - $val_str .= ($is_int[$i] === FALSE) ? $this->db->escape($v) : $v; - } - - // Append a comma - $val_str .= ', '; - $i++; - } - - // Remove the comma at the end of the string - $val_str = preg_replace('/, $/' , '', $val_str); - - // Build the INSERT string - $output .= 'INSERT INTO '.$this->db->protect_identifiers($table).' ('.$field_str.') VALUES ('.$val_str.');'.$newline; - } - - $output .= $newline.$newline; - } - - // Do we need to include a statement to re-enable foreign key checks? - if ($foreign_key_checks === FALSE) - { - $output .= 'SET foreign_key_checks = 1;'.$newline; - } - - return $output; - } - -} diff --git a/src/Database/drivers/oci8/oci8_driver.php b/src/Database/drivers/oci8/oci8_driver.php deleted file mode 100644 index 9211f30..0000000 --- a/src/Database/drivers/oci8/oci8_driver.php +++ /dev/null @@ -1,680 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * oci8 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ - -/** - * oci8 Database Adapter Class - * - * This is a modification of the DB_driver class to - * permit access to oracle databases - * - * @author Kelly McArdle - */ -class FW_DB_oci8_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'oci8'; - - /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** - * Commit mode flag - * - * @var int - */ - - /** - * Limit used flag - * - * If we use LIMIT, we'll add a field that will - * throw off num_fields later. - * - * @var bool - */ - public $limit_used; - - // -------------------------------------------------------------------- - - /** - * Reset $stmt_id flag - * - * Used by stored_procedure() to prevent _execute() from - * re-setting the statement ID. - */ - protected $_reset_stmt_id = TRUE; - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*', 'rownum'); - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // not currently supported - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(1) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - $valid_dsns = array( - 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS - // Easy Connect string (Oracle 10g+) - 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i', - 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora) - ); - - /* Space characters don't have any effect when actually - * connecting, but can be a hassle while validating the DSN. - */ - $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn); - - if ($this->dsn !== '') - { - foreach ($valid_dsns as $regexp) - { - if (preg_match($regexp, $this->dsn)) - { - return; - } - } - } - - // Legacy support for TNS in the hostname configuration field - $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname); - if (preg_match($valid_dsns['tns'], $this->hostname)) - { - $this->dsn = $this->hostname; - return; - } - elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE - && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== '')) - { - /* If the hostname field isn't empty, doesn't contain - * ':' and/or '/' and if port and/or database aren't - * empty, then the hostname field is most likely indeed - * just a hostname. Therefore we'll try and build an - * Easy Connect string from these 3 settings, assuming - * that the database field is a service name. - */ - $this->dsn = $this->hostname - .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '') - .($this->database !== '' ? '/'.ltrim($this->database, '/') : ''); - - if (preg_match($valid_dsns['ec'], $this->dsn)) - { - return; - } - } - - /* At this point, we can only try and validate the hostname and - * database fields separately as DSNs. - */ - if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname)) - { - $this->dsn = $this->hostname; - return; - } - - $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database); - foreach ($valid_dsns as $regexp) - { - if (preg_match($regexp, $this->database)) - { - return; - } - } - - /* Well - OK, an empty string should work as well. - * PHP will try to use environment variables to - * determine which Oracle instance to connect to. - */ - $this->dsn = ''; - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $func = ($persistent === TRUE) ? 'oci_pconnect' : 'oci_connect'; - return empty($this->char_set) - ? $func($this->username, $this->password, $this->dsn) - : $func($this->username, $this->password, $this->dsn, $this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($version_string = oci_server_version($this->conn_id)) === FALSE) - { - return FALSE; - } - elseif (preg_match('#Release\s(\d+(?:\.\d+)+)#', $version_string, $match)) - { - return $this->data_cache['version'] = $match[1]; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - /* Oracle must parse the query before it is run. All of the actions with - * the query are based on the statement id returned by oci_parse(). - */ - if ($this->_reset_stmt_id === TRUE) - { - $this->stmt_id = oci_parse($this->conn_id, $sql); - } - - oci_set_prefetch($this->stmt_id, 1000); - return oci_execute($this->stmt_id, $this->commit_mode); - } - - // -------------------------------------------------------------------- - - /** - * Get cursor. Returns a cursor from the database - * - * @return resource - */ - public function get_cursor() - { - return $this->curs_id = oci_new_cursor($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Stored Procedure. Executes a stored procedure - * - * @param string package name in which the stored procedure is in - * @param string stored procedure name to execute - * @param array parameters - * @return mixed - * - * params array keys - * - * KEY OPTIONAL NOTES - * name no the name of the parameter should be in : format - * value no the value of the parameter. If this is an OUT or IN OUT parameter, - * this should be a reference to a variable - * type yes the type of the parameter - * length yes the max size of the parameter - */ - public function stored_procedure($package, $procedure, array $params) - { - if ($package === '' OR $procedure === '') - { - Logger::logError('Invalid query: '.$package.'.'.$procedure); - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; - } - - // Build the query string - $sql = 'BEGIN '.$package.'.'.$procedure.'('; - - $have_cursor = FALSE; - foreach ($params as $param) - { - $sql .= $param['name'].','; - - if (isset($param['type']) && $param['type'] === OCI_B_CURSOR) - { - $have_cursor = TRUE; - } - } - $sql = trim($sql, ',').'); END;'; - - $this->_reset_stmt_id = FALSE; - $this->stmt_id = oci_parse($this->conn_id, $sql); - $this->_bind_params($params); - $result = $this->query($sql, FALSE, $have_cursor); - $this->_reset_stmt_id = TRUE; - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Bind parameters - * - * @param array $params - * @return void - */ - protected function _bind_params($params) - { - if ( ! is_array($params) OR ! is_resource($this->stmt_id)) - { - return; - } - - foreach ($params as $param) - { - foreach (array('name', 'value', 'type', 'length') as $val) - { - if ( ! isset($param[$val])) - { - $param[$val] = ''; - } - } - - oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']); - } - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - $this->commit_mode = Core::isPHP('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; - - return oci_commit($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; - return oci_rollback($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return oci_num_rows($this->stmt_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - // not supported in oracle - return $this->display_error('db_unsupported_function'); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"'; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE - FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - - $length = ($query[$i]->CHAR_LENGTH > 0) - ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION; - if ($length === NULL) - { - $length = $query[$i]->DATA_LENGTH; - } - $retval[$i]->max_length = $length; - - $default = $query[$i]->DATA_DEFAULT; - if ($default === NULL && $query[$i]->NULLABLE === 'N') - { - $default = ''; - } - $retval[$i]->default = $default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - /* oci_error() returns an array that already contains the - * 'code' and 'message' keys, so we can just return it. - */ - if (is_resource($this->curs_id)) - { - return oci_error($this->curs_id); - } - elseif (is_resource($this->stmt_id)) - { - return oci_error($this->stmt_id); - } - elseif (is_resource($this->conn_id)) - { - return oci_error($this->conn_id); - } - - return oci_error(); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - $keys = implode(', ', $keys); - $sql = "INSERT ALL\n"; - - for ($i = 0, $c = count($values); $i < $c; $i++) - { - $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n"; - } - - return $sql.'SELECT * FROM dual'; - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - $this->where('rownum <= ',$this->qb_limit, FALSE); - $this->qb_limit = FALSE; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - if (version_compare($this->version(), '12.1', '>=')) - { - // OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $this->limit_used = TRUE; - return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' - .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1) : ''); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - oci_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/oci8/oci8_forge.php b/src/Database/drivers/oci8/oci8_forge.php deleted file mode 100644 index 533d17a..0000000 --- a/src/Database/drivers/oci8/oci8_forge.php +++ /dev/null @@ -1,146 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Oracle Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - elseif ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = "\n\t".$field[$i]['_literal']; - } - else - { - $field[$i]['_literal'] = "\n\t".$this->_process_column($field[$i]); - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - - if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - } - - $sql .= ' '.$alter_type.' '; - $sql .= (count($field) === 1) - ? $field[0] - : '('.implode(',', $field).')'; - - // RENAME COLUMN must be executed after MODIFY - array_unshift($sqls, $sql); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - sequences and triggers must be used instead - } - -} diff --git a/src/Database/drivers/oci8/oci8_result.php b/src/Database/drivers/oci8/oci8_result.php deleted file mode 100644 index 8bd66a5..0000000 --- a/src/Database/drivers/oci8/oci8_result.php +++ /dev/null @@ -1,226 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * oci8 Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_result extends FW_DB_result { - - /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** - * Limit used flag - * - * @var bool - */ - public $limit_used; - - /** - * Commit mode flag - * - * @var int - */ - public $commit_mode; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$driver_object - * @return void - */ - public function __construct(&$driver_object) - { - parent::__construct($driver_object); - - $this->stmt_id = $driver_object->stmt_id; - $this->curs_id = $driver_object->curs_id; - $this->limit_used = $driver_object->limit_used; - $this->commit_mode =& $driver_object->commit_mode; - $driver_object->stmt_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - $count = oci_num_fields($this->stmt_id); - - // if we used a limit we subtract it - return ($this->limit_used) ? $count - 1 : $count; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) - { - $field_names[] = oci_field_name($this->stmt_id, $c); - } - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) - { - $F = new stdClass(); - $F->name = oci_field_name($this->stmt_id, $c); - $F->type = oci_field_type($this->stmt_id, $c); - $F->max_length = oci_field_size($this->stmt_id, $c); - - $retval[] = $F; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - oci_free_statement($this->result_id); - $this->result_id = FALSE; - } - - if (is_resource($this->stmt_id)) - { - oci_free_statement($this->stmt_id); - } - - if (is_resource($this->curs_id)) - { - oci_cancel($this->curs_id); - $this->curs_id = NULL; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; - return oci_fetch_assoc($id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = ($this->curs_id) - ? oci_fetch_object($this->curs_id) - : oci_fetch_object($this->stmt_id); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} diff --git a/src/Database/drivers/oci8/oci8_utility.php b/src/Database/drivers/oci8/oci8_utility.php deleted file mode 100644 index 0fbdda6..0000000 --- a/src/Database/drivers/oci8/oci8_utility.php +++ /dev/null @@ -1,65 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Oracle Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SELECT username FROM dba_users'; // Schemas are actual usernames - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/odbc/odbc_driver.php b/src/Database/drivers/odbc/odbc_driver.php deleted file mode 100644 index 05baae7..0000000 --- a/src/Database/drivers/odbc/odbc_driver.php +++ /dev/null @@ -1,374 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Utf8; - -/** - * ODBC Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'odbc'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * Must be empty for ODBC. - * - * @var string - */ - protected $_escape_char = ''; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " {escape '%s'} "; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RND()', 'RND(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - // Legacy support for DSN in the hostname field - if (empty($this->dsn)) - { - $this->dsn = $this->hostname; - } - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - return ($persistent === TRUE) - ? odbc_pconnect($this->dsn, $this->username, $this->password) - : odbc_connect($this->dsn, $this->username, $this->password); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return odbc_exec($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return odbc_autocommit($this->conn_id, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if (odbc_commit($this->conn_id)) - { - odbc_autocommit($this->conn_id, TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if (odbc_rollback($this->conn_id)) - { - odbc_autocommit($this->conn_id, TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return Utf8::remove_invisible_characters($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return odbc_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return bool - */ - public function insert_id() - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = '".$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT TOP 1 FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => odbc_error($this->conn_id), 'message' => odbc_errormsg($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - odbc_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/odbc/odbc_forge.php b/src/Database/drivers/odbc/odbc_forge.php deleted file mode 100644 index 71a8d88..0000000 --- a/src/Database/drivers/odbc/odbc_forge.php +++ /dev/null @@ -1,82 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported (in most databases at least) - } - -} diff --git a/src/Database/drivers/odbc/odbc_result.php b/src/Database/drivers/odbc/odbc_result.php deleted file mode 100644 index 4635eda..0000000 --- a/src/Database/drivers/odbc/odbc_result.php +++ /dev/null @@ -1,264 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (($this->num_rows = odbc_num_rows($this->result_id)) !== -1) - { - return $this->num_rows; - } - - // Work-around for ODBC subdrivers that don't support num_rows() - if (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return odbc_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - $num_fields = $this->num_fields(); - - if ($num_fields > 0) - { - for ($i = 1; $i <= $num_fields; $i++) - { - $field_names[] = odbc_field_name($this->result_id, $i); - } - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $odbc_index = 1, $c = $this->num_fields(); $i < $c; $i++, $odbc_index++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = odbc_field_name($this->result_id, $odbc_index); - $retval[$i]->type = odbc_field_type($this->result_id, $odbc_index); - $retval[$i]->max_length = odbc_field_len($this->result_id, $odbc_index); - $retval[$i]->primary_key = 0; - $retval[$i]->default = ''; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - odbc_free_result($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return odbc_fetch_array($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = odbc_fetch_object($this->result_id); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('odbc_fetch_array')) -{ - /** - * ODBC Fetch array - * - * Emulates the native odbc_fetch_array() function when - * it is not available (odbc_fetch_array() requires unixODBC) - * - * @param resource &$result - * @param int $rownumber - * @return array - */ - function odbc_fetch_array(&$result, $rownumber = 1) - { - $rs = array(); - if ( ! odbc_fetch_into($result, $rs, $rownumber)) - { - return FALSE; - } - - $rs_assoc = array(); - foreach ($rs as $k => $v) - { - $field_name = odbc_field_name($result, $k+1); - $rs_assoc[$field_name] = $v; - } - - return $rs_assoc; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('odbc_fetch_object')) -{ - /** - * ODBC Fetch object - * - * Emulates the native odbc_fetch_object() function when - * it is not available. - * - * @param resource &$result - * @param int $rownumber - * @return object - */ - function odbc_fetch_object(&$result, $rownumber = 1) - { - $rs = array(); - if ( ! odbc_fetch_into($result, $rs, $rownumber)) - { - return FALSE; - } - - $rs_object = new stdClass(); - foreach ($rs as $k => $v) - { - $field_name = odbc_field_name($result, $k+1); - $rs_object->$field_name = $v; - } - - return $rs_object; - } -} diff --git a/src/Database/drivers/odbc/odbc_utility.php b/src/Database/drivers/odbc/odbc_utility.php deleted file mode 100644 index d1aa41f..0000000 --- a/src/Database/drivers/odbc/odbc_utility.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/pdo/pdo_driver.php b/src/Database/drivers/pdo/pdo_driver.php deleted file mode 100644 index 10d5325..0000000 --- a/src/Database/drivers/pdo/pdo_driver.php +++ /dev/null @@ -1,371 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * PDO Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'pdo'; - - /** - * PDO Options - * - * @var array - */ - public $options = array(); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Validates the DSN string and/or detects the subdriver. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (preg_match('/([^:]+):/', $this->dsn, $match) && count($match) === 2) - { - // If there is a minimum valid dsn string pattern found, we're done - // This is for general PDO users, who tend to have a full DSN string. - $this->subdriver = $match[1]; - return; - } - // Legacy support for DSN specified in the hostname field - elseif (preg_match('/([^:]+):/', $this->hostname, $match) && count($match) === 2) - { - $this->dsn = $this->hostname; - $this->hostname = NULL; - $this->subdriver = $match[1]; - return; - } - elseif (in_array($this->subdriver, array('mssql', 'sybase'), TRUE)) - { - $this->subdriver = 'dblib'; - } - elseif ($this->subdriver === '4D') - { - $this->subdriver = '4d'; - } - elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'pgsql', 'sqlite', 'sqlsrv'), TRUE)) - { - Logger::logError('PDO: Invalid or non-existent subdriver'); - - if ($this->db_debug) - { - throw new DatabaseException('Invalid or non-existent PDO subdriver', 1); - } - } - - $this->dsn = NULL; - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->options[PDO::ATTR_PERSISTENT] = $persistent; - - try - { - return new PDO($this->dsn, $this->username, $this->password, $this->options); - } - catch (PDOException $e) - { - if ($this->db_debug && empty($this->failover)) - { - $this->display_error($e->getMessage(), '', TRUE); - } - - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - // Not all subdrivers support the getAttribute() method - try - { - return $this->data_cache['version'] = $this->conn_id->getAttribute(PDO::ATTR_SERVER_VERSION); - } - catch (PDOException $e) - { - return parent::version(); - } - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql SQL query - * @return mixed - */ - protected function _execute($sql) - { - return $this->conn_id->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->conn_id->beginTransaction(); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->conn_id->commit(); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->conn_id->rollBack(); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - // Escape the string - $str = $this->conn_id->quote($str); - - // If there are duplicated quotes, trim them away - return ($str[0] === "'") - ? substr($str, 1, -1) - : $str; - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return is_object($this->result_id) ? $this->result_id->rowCount() : 0; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $name - * @return int - */ - public function insert_id($name = NULL) - { - return $this->conn_id->lastInsertId($name); - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT TOP 1 * FROM '.$this->protect_identifiers($table); - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => '00000', 'message' => ''); - $pdo_error = $this->conn_id->errorInfo(); - - if (empty($pdo_error[0])) - { - return $error; - } - - $error['code'] = isset($pdo_error[1]) ? $pdo_error[0].'/'.$pdo_error[1] : $pdo_error[0]; - if (isset($pdo_error[2])) - { - $error['message'] = $pdo_error[2]; - } - - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = CASE '."\n"; - - foreach ($v as $row) - { - $cases .= $row."\n"; - } - - $cases .= 'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - -} diff --git a/src/Database/drivers/pdo/pdo_forge.php b/src/Database/drivers/pdo/pdo_forge.php deleted file mode 100644 index 18998fa..0000000 --- a/src/Database/drivers/pdo/pdo_forge.php +++ /dev/null @@ -1,61 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - -} diff --git a/src/Database/drivers/pdo/pdo_result.php b/src/Database/drivers/pdo/pdo_result.php deleted file mode 100644 index 4bac608..0000000 --- a/src/Database/drivers/pdo/pdo_result.php +++ /dev/null @@ -1,194 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - elseif (($num_rows = $this->result_id->rowCount()) > 0) - { - return $this->num_rows = $num_rows; - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->columnCount(); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return bool - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - // Might trigger an E_WARNING due to not all subdrivers - // supporting getColumnMeta() - $field_names[$i] = @$this->result_id->getColumnMeta($i); - $field_names[$i] = $field_names[$i]['name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - try - { - $retval = array(); - - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field = $this->result_id->getColumnMeta($i); - - $retval[$i] = new stdClass(); - $retval[$i]->name = $field['name']; - $retval[$i]->type = $field['native_type']; - $retval[$i]->max_length = ($field['len'] > 0) ? $field['len'] : NULL; - $retval[$i]->primary_key = (int) ( ! empty($field['flags']) && in_array('primary_key', $field['flags'], TRUE)); - } - - return $retval; - } - catch (Exception $e) - { - if ($this->db->db_debug) - { - return $this->db->display_error('db_unsupported_feature'); - } - - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetch(PDO::FETCH_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return $this->result_id->fetchObject($class_name); - } - -} diff --git a/src/Database/drivers/pdo/pdo_utility.php b/src/Database/drivers/pdo/pdo_utility.php deleted file mode 100644 index a4b40b3..0000000 --- a/src/Database/drivers/pdo/pdo_utility.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php deleted file mode 100644 index d5c20b2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ /dev/null @@ -1,196 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO 4D Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_4d_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = '4d'; - - /** - * Identifier escape character - * - * @var string[] - */ - protected $_escape_char = array('[', ']'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = '4D:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 3) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('TABLE_NAME').' FROM '.$this->escape_identifiers('_USER_TABLES'); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' WHERE '.$this->escape_identifiers('TABLE_NAME')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT '.$this->escape_identifiers('COLUMN_NAME').' FROM '.$this->escape_identifiers('_USER_COLUMNS') - .' WHERE '.$this->escape_identifiers('TABLE_NAME').' = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT * FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE).' LIMIT 1'; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php deleted file mode 100644 index 0c39529..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ /dev/null @@ -1,214 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO 4D Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_4d_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE SCHEMA %s'; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = 'DROP SCHEMA %s'; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT16' => 'INT', - 'SMALLINT' => 'INT', - 'INT' => 'INT64', - 'INT32' => 'INT64' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - // No method of modifying columns is supported - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['auto_increment']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - - // UNIQUE must be used with NOT NULL - $field['null'] = ' NOT NULL'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - if (stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' AUTO_INCREMENT'; - } - elseif (strcasecmp($field['type'], 'UUID') === 0) - { - $field['auto_increment'] = ' AUTO_GENERATE'; - } - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php deleted file mode 100644 index 88d659e..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ /dev/null @@ -1,246 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO CUBRID Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_cubrid_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'cubrid'; - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'cubrid:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php deleted file mode 100644 index e1383e2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ /dev/null @@ -1,224 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO CUBRID Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_cubrid_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SHORT' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'BIGINT' => 'NUMERIC', - 'FLOAT' => 'DOUBLE', - 'REAL' => 'DOUBLE' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $sqls[] = $sql.' CHANGE '.$field[$i]['_literal']; - } - else - { - $alter_type = empty($field[$i]['new_name']) ? ' MODIFY ' : ' CHANGE '; - $sqls[] = $sql.$alter_type.$this->_process_column($field[$i]); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php deleted file mode 100644 index 77bdb5f..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ /dev/null @@ -1,328 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO DBLIB Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_dblib_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'dblib'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = $params['subdriver'].':host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - if ( ! empty($this->port)) - { - $this->dsn .= (DIRECTORY_SEPARATOR === '\\' ? ',' : ':').$this->port; - } - - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - empty($this->appname) OR $this->dsn .= ';appname='.$this->appname; - } - else - { - if ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - - $this->subdriver = 'dblib'; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = parent::db_connect($persistent); - - if ( ! is_object($this->conn_id)) - { - return $this->conn_id; - } - - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - $limit = $this->qb_offset + $this->qb_limit; - - // As of SQL Server 2005 (9.0.*) ROW_NUMBER() is supported, - // however an ORDER BY clause is required for it to work - if (version_compare($this->version(), '9', '>=') && $this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php deleted file mode 100644 index 8c3ddd3..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO DBLIB Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_dblib_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php deleted file mode 100644 index c589048..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ /dev/null @@ -1,259 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Firebird Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_firebird_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'firebird'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'firebird:'; - - if ( ! empty($this->database)) - { - $this->dsn .= 'dbname='.$this->database; - } - elseif ( ! empty($this->hostname)) - { - $this->dsn .= 'dbname='.$this->hostname; - } - - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - empty($this->role) OR $this->dsn .= ';role='.$this->role; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 9) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\''; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "rfields"."RDB$FIELD_NAME" AS "name", - CASE "fields"."RDB$FIELD_TYPE" - WHEN 7 THEN \'SMALLINT\' - WHEN 8 THEN \'INTEGER\' - WHEN 9 THEN \'QUAD\' - WHEN 10 THEN \'FLOAT\' - WHEN 11 THEN \'DFLOAT\' - WHEN 12 THEN \'DATE\' - WHEN 13 THEN \'TIME\' - WHEN 14 THEN \'CHAR\' - WHEN 16 THEN \'INT64\' - WHEN 27 THEN \'DOUBLE\' - WHEN 35 THEN \'TIMESTAMP\' - WHEN 37 THEN \'VARCHAR\' - WHEN 40 THEN \'CSTRING\' - WHEN 261 THEN \'BLOB\' - ELSE NULL - END AS "type", - "fields"."RDB$FIELD_LENGTH" AS "max_length", - "rfields"."RDB$DEFAULT_VALUE" AS "default" - FROM "RDB$RELATION_FIELDS" "rfields" - JOIN "RDB$FIELDS" "fields" ON "rfields"."RDB$FIELD_SOURCE" = "fields"."RDB$FIELD_NAME" - WHERE "rfields"."RDB$RELATION_NAME" = '.$this->escape($table).' - ORDER BY "rfields"."RDB$FIELD_POSITION"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // Limit clause depends on if Interbase or Firebird - if (stripos($this->version(), 'firebird') !== FALSE) - { - $select = 'FIRST '.$this->qb_limit - .($this->qb_offset > 0 ? ' SKIP '.$this->qb_offset : ''); - } - else - { - $select = 'ROWS ' - .($this->qb_offset > 0 ? $this->qb_offset.' TO '.($this->qb_limit + $this->qb_offset) : $this->qb_limit); - } - - return preg_replace('`SELECT`i', 'SELECT '.$select, $sql); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php deleted file mode 100644 index 3cb7bd3..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ /dev/null @@ -1,234 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Firebird Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_firebird_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INTEGER' => 'INT64', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return string - */ - public function create_database($db_name) - { - // Firebird databases are flat files, so a path is required - - // Hostname is needed for remote access - empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name; - - return parent::create_database('"'.$db_name.'"'); - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! ibase_drop_db($this->conn_id)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = 'UPDATE "RDB$RELATION_FIELDS" SET "RDB$NULL_FLAG" = ' - .($field[$i]['null'] === TRUE ? 'NULL' : '1') - .' WHERE "RDB$FIELD_NAME" = '.$this->db->escape($field[$i]['name']) - .' AND "RDB$RELATION_NAME" = '.$this->db->escape($table); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INT': - $attributes['TYPE'] = 'INTEGER'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php deleted file mode 100644 index 3a361b0..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ /dev/null @@ -1,240 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO IBM DB2 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_ibm_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'ibm'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'ibm:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->HOSTNAME) && empty($this->port) && empty($this->PORT)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - $this->dsn .= 'DRIVER='.(isset($this->DRIVER) ? '{'.$this->DRIVER.'}' : '{IBM DB2 ODBC DRIVER}').';'; - - if (isset($this->DATABASE)) - { - $this->dsn .= 'DATABASE='.$this->DATABASE.';'; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DATABASE='.$this->database.';'; - } - - if (isset($this->HOSTNAME)) - { - $this->dsn .= 'HOSTNAME='.$this->HOSTNAME.';'; - } - else - { - $this->dsn .= 'HOSTNAME='.(empty($this->hostname) ? '127.0.0.1;' : $this->hostname.';'); - } - - if (isset($this->PORT)) - { - $this->dsn .= 'PORT='.$this->port.';'; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= ';PORT='.$this->port.';'; - } - - $this->dsn .= 'PROTOCOL='.(isset($this->PROTOCOL) ? $this->PROTOCOL.';' : 'TCPIP;'); - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "tabname" FROM "syscat"."tables" - WHERE "type" = \'T\' AND LOWER("tabschema") = '.$this->escape(strtolower($this->database)); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND "tabname" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return array - */ - protected function _list_columns($table = '') - { - return 'SELECT "colname" FROM "syscat"."columns" - WHERE LOWER("tabschema") = '.$this->escape(strtolower($this->database)).' - AND LOWER("tabname") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "colname" AS "name", "typename" AS "type", "default" AS "default", "length" AS "max_length", - CASE "keyseq" WHEN NULL THEN 0 ELSE 1 END AS "primary_key" - FROM "syscat"."columns" - WHERE LOWER("tabschema") = '.$this->escape(strtolower($this->database)).' - AND LOWER("tabname") = '.$this->escape(strtolower($table)).' - ORDER BY "colno"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - $sql .= ' FETCH FIRST '.($this->qb_limit + $this->qb_offset).' ROWS ONLY'; - - return ($this->qb_offset) - ? 'SELECT * FROM ('.$sql.') WHERE rownum > '.$this->qb_offset - : $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php deleted file mode 100644 index cc2d48a..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ /dev/null @@ -1,151 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO IBM DB2 Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_ibm_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE IF statement - * - * @var string - */ - protected $_rename_table = 'RENAME TABLE %s TO %s'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - - // UNIQUE must be used with NOT NULL - $field['null'] = ' NOT NULL'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php deleted file mode 100644 index 47da5af..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ /dev/null @@ -1,305 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Informix Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_informix_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'informix'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'informix:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->host) && empty($this->port) && empty($this->service)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - if (isset($this->host)) - { - $this->dsn .= 'host='.$this->host; - } - else - { - $this->dsn .= 'host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - } - - if (isset($this->service)) - { - $this->dsn .= '; service='.$this->service; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= '; service='.$this->port; - } - - empty($this->database) OR $this->dsn .= '; database='.$this->database; - empty($this->server) OR $this->dsn .= '; server='.$this->server; - - $this->dsn .= '; protocol='.(isset($this->protocol) ? $this->protocol : 'onsoctcp') - .'; EnableScrollableCursors=1'; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "tabname" FROM "systables" - WHERE "tabid" > 99 AND "tabtype" = \'T\' AND LOWER("owner") = '.$this->escape(strtolower($this->username)); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND "tabname" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT "colname" FROM "systables", "syscolumns" - WHERE "systables"."tabid" = "syscolumns"."tabid" - AND "systables"."tabtype" = \'T\' - AND LOWER("systables"."owner") = '.$this->escape(strtolower($owner)).' - AND LOWER("systables"."tabname") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "syscolumns"."colname" AS "name", - CASE "syscolumns"."coltype" - WHEN 0 THEN \'CHAR\' - WHEN 1 THEN \'SMALLINT\' - WHEN 2 THEN \'INTEGER\' - WHEN 3 THEN \'FLOAT\' - WHEN 4 THEN \'SMALLFLOAT\' - WHEN 5 THEN \'DECIMAL\' - WHEN 6 THEN \'SERIAL\' - WHEN 7 THEN \'DATE\' - WHEN 8 THEN \'MONEY\' - WHEN 9 THEN \'NULL\' - WHEN 10 THEN \'DATETIME\' - WHEN 11 THEN \'BYTE\' - WHEN 12 THEN \'TEXT\' - WHEN 13 THEN \'VARCHAR\' - WHEN 14 THEN \'INTERVAL\' - WHEN 15 THEN \'NCHAR\' - WHEN 16 THEN \'NVARCHAR\' - WHEN 17 THEN \'INT8\' - WHEN 18 THEN \'SERIAL8\' - WHEN 19 THEN \'SET\' - WHEN 20 THEN \'MULTISET\' - WHEN 21 THEN \'LIST\' - WHEN 22 THEN \'Unnamed ROW\' - WHEN 40 THEN \'LVARCHAR\' - WHEN 41 THEN \'BLOB/CLOB/BOOLEAN\' - WHEN 4118 THEN \'Named ROW\' - ELSE "syscolumns"."coltype" - END AS "type", - "syscolumns"."collength" as "max_length", - CASE "sysdefaults"."type" - WHEN \'L\' THEN "sysdefaults"."default" - ELSE NULL - END AS "default" - FROM "syscolumns", "systables", "sysdefaults" - WHERE "syscolumns"."tabid" = "systables"."tabid" - AND "systables"."tabid" = "sysdefaults"."tabid" - AND "syscolumns"."colno" = "sysdefaults"."colno" - AND "systables"."tabtype" = \'T\' - AND LOWER("systables"."owner") = '.$this->escape(strtolower($this->username)).' - AND LOWER("systables"."tabname") = '.$this->escape(strtolower($table)).' - ORDER BY "syscolumns"."colno"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE ONLY '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql $SQL Query - * @return string - */ - protected function _limit($sql) - { - $select = 'SELECT '.($this->qb_offset ? 'SKIP '.$this->qb_offset : '').'FIRST '.$this->qb_limit.' '; - return preg_replace('/^(SELECT\s)/i', $select, $sql, 1); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php deleted file mode 100644 index 266bc82..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ /dev/null @@ -1,160 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Informix Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_informix_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = 'RENAME TABLE %s TO %s'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'REAL' => 'DOUBLE PRECISION', - 'SMALLFLOAT' => 'DOUBLE PRECISION' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = ', '; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'BYTE': - case 'TEXT': - case 'BLOB': - case 'CLOB': - $attributes['UNIQUE'] = FALSE; - if (isset($attributes['DEFAULT'])) - { - unset($attributes['DEFAULT']); - } - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE CONSTRAINT '.$this->db->escape_identifiers($field['name']); - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php deleted file mode 100644 index 07876ae..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ /dev/null @@ -1,335 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * PDO MySQL Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_mysql_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'mysql'; - - /** - * Compression flag - * - * @var bool - */ - public $compress = FALSE; - - /** - * Strict ON flag - * - * Whether we're running in strict SQL mode. - * - * @var bool - */ - public $stricton; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'mysql:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE && Core::isPHP('5.3.6')) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - /* Prior to PHP 5.3.6, even if the charset was supplied in the DSN - * on connect - it was ignored. This is a work-around for the issue. - * - * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php - */ - if ( ! Core::isPHP('5.3.6') && ! empty($this->char_set)) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set - .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); - } - - if (isset($this->stricton)) - { - if ($this->stricton) - { - $sql = 'CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'; - } - else - { - $sql = 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( - @@sql_mode, - "STRICT_ALL_TABLES,", ""), - ",STRICT_ALL_TABLES", ""), - "STRICT_ALL_TABLES", ""), - "STRICT_TRANS_TABLES,", ""), - ",STRICT_TRANS_TABLES", ""), - "STRICT_TRANS_TABLES", "")'; - } - - if ( ! empty($sql)) - { - if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = '.$sql; - } - else - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = '.$sql; - } - } - } - - if ($this->compress === TRUE) - { - $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; - } - - // SSL support was added to PDO_MYSQL in PHP 5.3.7 - if (is_array($this->encrypt) && Core::isPHP('5.3.7')) - { - $ssl = array(); - empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; - empty($this->encrypt['ssl_cert']) OR $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert']; - empty($this->encrypt['ssl_ca']) OR $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca']; - empty($this->encrypt['ssl_capath']) OR $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath']; - empty($this->encrypt['ssl_cipher']) OR $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher']; - - // DO NOT use array_merge() here! - // It re-indexes numeric keys and the PDO_MYSQL_ATTR_SSL_* constants are integers. - empty($ssl) OR $this->options += $ssl; - } - - // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails - if ( - ($pdo = parent::db_connect($persistent)) !== FALSE - && ! empty($ssl) - && version_compare($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), '5.7.3', '<=') - && empty($pdo->query("SHOW STATUS LIKE 'ssl_cipher'")->fetchObject()->Value) - ) - { - $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!'; - Logger::logError($message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; - } - - return $pdo; - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if (FALSE !== $this->simple_query('USE '.$this->escape_identifiers($database))) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php deleted file mode 100644 index 9cd27d2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ /dev/null @@ -1,253 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO MySQL Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_mysql_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s'; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT', - 'SMALLINT', - 'MEDIUMINT', - 'INT', - 'INTEGER', - 'BIGINT', - 'REAL', - 'DOUBLE', - 'DOUBLE PRECISION', - 'FLOAT', - 'DECIMAL', - 'NUMERIC' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; - } - } - - if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) - { - $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; - } - - if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) - { - $sql .= ' COLLATE = '.$this->db->dbcollat; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = ($alter_type === 'ADD') - ? "\n\tADD ".$field[$i]['_literal'] - : "\n\tMODIFY ".$field[$i]['_literal']; - } - else - { - if ($alter_type === 'ADD') - { - $field[$i]['_literal'] = "\n\tADD "; - } - else - { - $field[$i]['_literal'] = empty($field[$i]['new_name']) ? "\n\tMODIFY " : "\n\tCHANGE "; - } - - $field[$i] = $field[$i]['_literal'].$this->_process_column($field[$i]); - } - } - - return array($sql.implode(',', $field)); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .(empty($field['comment']) ? '' : ' COMMENT '.$field['comment']) - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php deleted file mode 100644 index 091d995..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ /dev/null @@ -1,322 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Oracle Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_oci_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'oci'; - - // -------------------------------------------------------------------- - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*', 'rownum'); - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(1) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'oci:dbname='; - - // Oracle has a slightly different PDO DSN format (Easy Connect), - // which also supports pre-defined DSNs. - if (empty($this->hostname) && empty($this->port)) - { - $this->dsn .= $this->database; - } - else - { - $this->dsn .= '//'.(empty($this->hostname) ? '127.0.0.1' : $this->hostname) - .(empty($this->port) ? '' : ':'.$this->port).'/'; - - empty($this->database) OR $this->dsn .= $this->database; - } - - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 4) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - $version_string = parent::version(); - if (preg_match('#Release\s(?\d+(?:\.\d+)+)#', $version_string, $match)) - { - return $this->data_cache['version'] = $match[1]; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE - FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - - $length = ($query[$i]->CHAR_LENGTH > 0) - ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION; - if ($length === NULL) - { - $length = $query[$i]->DATA_LENGTH; - } - $retval[$i]->max_length = $length; - - $default = $query[$i]->DATA_DEFAULT; - if ($default === NULL && $query[$i]->NULLABLE === 'N') - { - $default = ''; - } - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - $keys = implode(', ', $keys); - $sql = "INSERT ALL\n"; - - for ($i = 0, $c = count($values); $i < $c; $i++) - { - $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n"; - } - - return $sql.'SELECT * FROM dual'; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - $this->where('rownum <= ',$this->qb_limit, FALSE); - $this->qb_limit = FALSE; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - if (version_compare($this->version(), '12.1', '>=')) - { - // OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' - .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1): ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php deleted file mode 100644 index c27d0c2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ /dev/null @@ -1,146 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Oracle Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_oci_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - elseif ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = "\n\t".$field[$i]['_literal']; - } - else - { - $field[$i]['_literal'] = "\n\t".$this->_process_column($field[$i]); - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - - if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - } - - $sql .= ' '.$alter_type.' '; - $sql .= (count($field) === 1) - ? $field[0] - : '('.implode(',', $field).')'; - - // RENAME COLUMN must be executed after MODIFY - array_unshift($sqls, $sql); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - sequences and triggers must be used instead - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php deleted file mode 100644 index b3064b6..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ /dev/null @@ -1,280 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO ODBC Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_odbc_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'odbc'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * Must be empty for ODBC. - * - * @var string - */ - protected $_escape_char = ''; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " {escape '%s'} "; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RND()', 'RND(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'odbc:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->HOSTNAME) && empty($this->port) && empty($this->PORT)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - // If the DSN is not pre-configured - try to build an IBM DB2 connection string - $this->dsn .= 'DRIVER='.(isset($this->DRIVER) ? '{'.$this->DRIVER.'}' : '{IBM DB2 ODBC DRIVER}').';'; - - if (isset($this->DATABASE)) - { - $this->dsn .= 'DATABASE='.$this->DATABASE.';'; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DATABASE='.$this->database.';'; - } - - if (isset($this->HOSTNAME)) - { - $this->dsn .= 'HOSTNAME='.$this->HOSTNAME.';'; - } - else - { - $this->dsn .= 'HOSTNAME='.(empty($this->hostname) ? '127.0.0.1;' : $this->hostname.';'); - } - - if (isset($this->PORT)) - { - $this->dsn .= 'PORT='.$this->port.';'; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= ';PORT='.$this->port.';'; - } - - $this->dsn .= 'PROTOCOL='.(isset($this->PROTOCOL) ? $this->PROTOCOL.';' : 'TCPIP;'); - } - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = '".$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT column_name FROM information_schema.columns WHERE table_name = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$this->qb_limit.' ', $sql); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php deleted file mode 100644 index 7670315..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php +++ /dev/null @@ -1,67 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO ODBC Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_odbc_forge extends FW_DB_pdo_forge { - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported (in most databases at least) - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php deleted file mode 100644 index c0e1aa6..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ /dev/null @@ -1,380 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO PostgreSQL Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_pgsql_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'pgsql'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'pgsql:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - - if ( ! empty($this->username)) - { - $this->dsn .= ';username='.$this->username; - empty($this->password) OR $this->dsn .= ';password='.$this->password; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = parent::db_connect($persistent); - - if (is_object($this->conn_id) && ! empty($this->schema)) - { - $this->simple_query('SET search_path TO '.$this->schema.',public'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $name - * @return int - */ - public function insert_id($name = NULL) - { - if ($name === NULL && version_compare($this->version(), '8.1', '>=')) - { - $query = $this->query('SELECT LASTVAL() AS ins_id'); - $query = $query->row(); - return $query->ins_id; - } - - return $this->conn_id->lastInsertId($name); - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * - * @param string $str - * @return mixed - */ - public function escape($str) - { - if (is_bool($str)) - { - return ($str) ? 'TRUE' : 'FALSE'; - } - - return parent::escape($str); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return object - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - if ($direction === 'RANDOM') - { - if ( ! is_float($orderby) && ctype_digit((string) $orderby)) - { - $orderby = ($orderby > 1) - ? (float) '0.'.$orderby - : (float) $orderby; - } - - if (is_float($orderby)) - { - $this->simple_query('SET SEED '.$orderby); - } - - $orderby = $this->_random_keyword[0]; - $direction = ''; - $escape = FALSE; - } - - return parent::order_by($orderby, $direction, $escape); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \''.$this->schema."'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "table_name" LIKE \'' - .$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "column_name" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->column_name; - $retval[$i]->type = $query[$i]->data_type; - $retval[$i]->max_length = ($query[$i]->character_maximum_length > 0) ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision; - $retval[$i]->default = $query[$i]->column_default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = (CASE '.$index."\n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php deleted file mode 100644 index 595bdcc..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ /dev/null @@ -1,207 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO PostgreSQL Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_pgsql_forge extends FW_DB_pdo_forge { - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT2' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INT4' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'INT8' => 'NUMERIC', - 'BIGINT' => 'NUMERIC', - 'REAL' => 'DOUBLE PRECISION', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '9.0', '>')) - { - $this->create_table_if = 'CREATE TABLE IF NOT EXISTS'; - } - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (version_compare($this->db->version(), '8', '>=') && isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .($field[$i]['null'] === TRUE ? ' DROP NOT NULL' : ' SET NOT NULL'); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Reset field lenghts for data types that don't support it - if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) - { - $attributes['CONSTRAINT'] = NULL; - } - - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - $field['type'] = ($field['type'] === 'NUMERIC') - ? 'BIGSERIAL' - : 'SERIAL'; - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php deleted file mode 100644 index 5a685fc..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ /dev/null @@ -1,215 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLite Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlite_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'sqlite'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = ' RANDOM()'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'sqlite:'; - - if (empty($this->database) && empty($this->hostname)) - { - $this->database = ':memory:'; - } - - $this->database = empty($this->database) ? $this->hostname : $this->database; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $this->data_cache['field_names'][$table] = array(); - foreach ($result->result_array() as $row) - { - $this->data_cache['field_names'][$table][] = $row['name']; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php deleted file mode 100644 index 294b127..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ /dev/null @@ -1,235 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLite Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlite_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '3.3', '<')) - { - $this->_create_table_if = FALSE; - $this->_drop_table_if = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name (ignored) - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - // In SQLite, a database is dropped when we delete a file - if (file_exists($this->db->database)) - { - // We need to close the pseudo-connection first - $this->db->close(); - if ( ! @unlink($this->db->database)) - { - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php deleted file mode 100644 index 102d84e..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ /dev/null @@ -1,365 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLSRV Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlsrv_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'sqlsrv'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'sqlsrv:Server='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ','.$this->port; - empty($this->database) OR $this->dsn .= ';Database='.$this->database; - - // Some custom options - - if (isset($this->QuotedId)) - { - $this->dsn .= ';QuotedId='.$this->QuotedId; - $this->_quoted_identifier = (bool) $this->QuotedId; - } - - if (isset($this->ConnectionPooling)) - { - $this->dsn .= ';ConnectionPooling='.$this->ConnectionPooling; - } - - if ($this->encrypt === TRUE) - { - $this->dsn .= ';Encrypt=1'; - } - - if (isset($this->TraceOn)) - { - $this->dsn .= ';TraceOn='.$this->TraceOn; - } - - if (isset($this->TrustServerCertificate)) - { - $this->dsn .= ';TrustServerCertificate='.$this->TrustServerCertificate; - } - - empty($this->APP) OR $this->dsn .= ';APP='.$this->APP; - empty($this->Failover_Partner) OR $this->dsn .= ';Failover_Partner='.$this->Failover_Partner; - empty($this->LoginTimeout) OR $this->dsn .= ';LoginTimeout='.$this->LoginTimeout; - empty($this->MultipleActiveResultSets) OR $this->dsn .= ';MultipleActiveResultSets='.$this->MultipleActiveResultSets; - empty($this->TraceFile) OR $this->dsn .= ';TraceFile='.$this->TraceFile; - empty($this->WSID) OR $this->dsn .= ';WSID='.$this->WSID; - } - elseif (preg_match('/QuotedId=(0|1)/', $this->dsn, $match)) - { - $this->_quoted_identifier = (bool) $match[1]; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - if ( ! empty($this->char_set) && preg_match('/utf[^8]*8/i', $this->char_set)) - { - $this->options[PDO::SQLSRV_ENCODING_UTF8] = 1; - } - - $this->conn_id = parent::db_connect($persistent); - - if ( ! is_object($this->conn_id) OR is_bool($this->_quoted_identifier)) - { - return $this->conn_id; - } - - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // As of SQL Server 2012 (11.0.*) OFFSET is supported - if (version_compare($this->version(), '11', '>=')) - { - // SQL Server OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $limit = $this->qb_offset + $this->qb_limit; - - // An ORDER BY clause is required for ROW_NUMBER() to work - if ($this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php deleted file mode 100644 index 46bd93a..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLSRV Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlsrv_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/postgre/postgre_driver.php b/src/Database/drivers/postgre/postgre_driver.php deleted file mode 100644 index e9e6b47..0000000 --- a/src/Database/drivers/postgre/postgre_driver.php +++ /dev/null @@ -1,618 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Core; - -/** - * Postgre Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'postgre'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Creates a DSN string to be used for db_connect() and db_pconnect() - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if ( ! empty($this->dsn)) - { - return; - } - - $this->dsn === '' OR $this->dsn = ''; - - if (strpos($this->hostname, '/') !== FALSE) - { - // If UNIX sockets are used, we shouldn't set a port - $this->port = ''; - } - - $this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' '; - - if ( ! empty($this->port) && ctype_digit($this->port)) - { - $this->dsn .= 'port='.$this->port.' '; - } - - if ($this->username !== '') - { - $this->dsn .= 'user='.$this->username.' '; - - /* An empty password is valid! - * - * $db['password'] = NULL must be done in order to ignore it. - */ - $this->password === NULL OR $this->dsn .= "password='".$this->password."' "; - } - - $this->database === '' OR $this->dsn .= 'dbname='.$this->database.' '; - - /* We don't have these options as elements in our standard configuration - * array, but they might be set by parse_url() if the configuration was - * provided via string. Example: - * - * postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1 - */ - foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key) - { - if (isset($this->$key) && is_string($this->key) && $this->key !== '') - { - $this->dsn .= $key."='".$this->key."' "; - } - } - - $this->dsn = rtrim($this->dsn); - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = ($persistent === TRUE) - ? pg_pconnect($this->dsn) - : pg_connect($this->dsn); - - if ($this->conn_id !== FALSE) - { - if ($persistent === TRUE - && pg_connection_status($this->conn_id) === PGSQL_CONNECTION_BAD - && pg_ping($this->conn_id) === FALSE - ) - { - return FALSE; - } - - empty($this->schema) OR $this->simple_query('SET search_path TO '.$this->schema.',public'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if (pg_ping($this->conn_id) === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string $charset - * @return bool - */ - protected function _db_set_charset($charset) - { - return (pg_set_client_encoding($this->conn_id, $charset) === 0); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($pg_version = pg_version($this->conn_id)) === FALSE) - { - return FALSE; - } - - /* If PHP was compiled with PostgreSQL lib versions earlier - * than 7.4, pg_version() won't return the server version - * and so we'll have to fall back to running a query in - * order to get it. - */ - return isset($pg_version['server']) - ? $this->data_cache['version'] = $pg_version['server'] - : parent::version(); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return pg_query($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return (bool) pg_query($this->conn_id, 'BEGIN'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return (bool) pg_query($this->conn_id, 'COMMIT'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return (bool) pg_query($this->conn_id, 'ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return pg_escape_string($this->conn_id, $str); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * - * @param string $str - * @return mixed - */ - public function escape($str) - { - if (Core::isPHP('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))) - { - return pg_escape_literal($this->conn_id, $str); - } - elseif (is_bool($str)) - { - return ($str) ? 'TRUE' : 'FALSE'; - } - - return parent::escape($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return pg_affected_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return string - */ - public function insert_id() - { - $v = pg_version($this->conn_id); - $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4 - - $table = (func_num_args() > 0) ? func_get_arg(0) : NULL; - $column = (func_num_args() > 1) ? func_get_arg(1) : NULL; - - if ($table === NULL && $v >= '8.1') - { - $sql = 'SELECT LASTVAL() AS ins_id'; - } - elseif ($table !== NULL) - { - if ($column !== NULL && $v >= '8.0') - { - $sql = 'SELECT pg_get_serial_sequence(\''.$table."', '".$column."') AS seq"; - $query = $this->query($sql); - $query = $query->row(); - $seq = $query->seq; - } - else - { - // seq_name passed in table parameter - $seq = $table; - } - - $sql = 'SELECT CURRVAL(\''.$seq."') AS ins_id"; - } - else - { - return pg_last_oid($this->result_id); - } - - $query = $this->query($sql); - $query = $query->row(); - return (int) $query->ins_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \''.$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' AND "table_name" LIKE \'' - .$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "column_name" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->column_name; - $retval[$i]->type = $query[$i]->data_type; - $retval[$i]->max_length = ($query[$i]->character_maximum_length > 0) ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision; - $retval[$i]->default = $query[$i]->column_default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => '', 'message' => pg_last_error($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return object - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - if ($direction === 'RANDOM') - { - if ( ! is_float($orderby) && ctype_digit((string) $orderby)) - { - $orderby = ($orderby > 1) - ? (float) '0.'.$orderby - : (float) $orderby; - } - - if (is_float($orderby)) - { - $this->simple_query('SET SEED '.$orderby); - } - - $orderby = $this->_random_keyword[0]; - $direction = ''; - $escape = FALSE; - } - - return parent::order_by($orderby, $direction, $escape); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = (CASE '.$index."\n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - pg_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/postgre/postgre_forge.php b/src/Database/drivers/postgre/postgre_forge.php deleted file mode 100644 index 39495bf..0000000 --- a/src/Database/drivers/postgre/postgre_forge.php +++ /dev/null @@ -1,201 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgre Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_forge extends FW_DB_forge { - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT2' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INT4' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'INT8' => 'NUMERIC', - 'BIGINT' => 'NUMERIC', - 'REAL' => 'DOUBLE PRECISION', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '9.0', '>')) - { - $this->create_table_if = 'CREATE TABLE IF NOT EXISTS'; - } - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (version_compare($this->db->version(), '8', '>=') && isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .($field[$i]['null'] === TRUE ? ' DROP NOT NULL' : ' SET NOT NULL'); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Reset field lenghts for data types that don't support it - if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) - { - $attributes['CONSTRAINT'] = NULL; - } - - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - $field['type'] = ($field['type'] === 'NUMERIC') - ? 'BIGSERIAL' - : 'SERIAL'; - } - } - -} diff --git a/src/Database/drivers/postgre/postgre_result.php b/src/Database/drivers/postgre/postgre_result.php deleted file mode 100644 index d0a8433..0000000 --- a/src/Database/drivers/postgre/postgre_result.php +++ /dev/null @@ -1,178 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgres Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = pg_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return pg_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[] = pg_field_name($this->result_id, $i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = pg_field_name($this->result_id, $i); - $retval[$i]->type = pg_field_type($this->result_id, $i); - $retval[$i]->max_length = pg_field_size($this->result_id, $i); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - pg_free_result($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return pg_result_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return pg_fetch_assoc($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return pg_fetch_object($this->result_id, NULL, $class_name); - } - -} diff --git a/src/Database/drivers/postgre/postgre_utility.php b/src/Database/drivers/postgre/postgre_utility.php deleted file mode 100644 index adc3a90..0000000 --- a/src/Database/drivers/postgre/postgre_utility.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgre Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SELECT datname FROM pg_database'; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'REINDEX TABLE %s'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } -} diff --git a/src/Database/drivers/sqlite/sqlite_driver.php b/src/Database/drivers/sqlite/sqlite_driver.php deleted file mode 100644 index 4714d91..0000000 --- a/src/Database/drivers/sqlite/sqlite_driver.php +++ /dev/null @@ -1,328 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; - -/** - * SQLite Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlite'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $error = NULL; - $conn_id = ($persistent === TRUE) - ? sqlite_popen($this->database, 0666, $error) - : sqlite_open($this->database, 0666, $error); - - isset($error) && Logger::logError($error); - - return $conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - return isset($this->data_cache['version']) - ? $this->data_cache['version'] - : $this->data_cache['version'] = sqlite_libversion(); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return $this->is_write_type($sql) - ? sqlite_exec($this->conn_id, $sql) - : sqlite_query($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->simple_query('BEGIN TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->simple_query('COMMIT'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->simple_query('ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return sqlite_escape_string($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return sqlite_changes($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return sqlite_last_insert_rowid($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT name FROM sqlite_master WHERE type='table'"; - - if ($prefix_limit !== FALSE && $this->dbprefix != '') - { - return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return bool - */ - protected function _list_columns($table = '') - { - // Not supported - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => sqlite_last_error($this->conn_id)); - $error['message'] = sqlite_error_string($error['code']); - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this function maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - sqlite_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_forge.php b/src/Database/drivers/sqlite/sqlite_forge.php deleted file mode 100644 index a4e4abc..0000000 --- a/src/Database/drivers/sqlite/sqlite_forge.php +++ /dev/null @@ -1,202 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name (ignored) - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! file_exists($this->db->database) OR ! @unlink($this->db->database)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @todo implement drop_column(), modify_column() - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_result.php b/src/Database/drivers/sqlite/sqlite_result.php deleted file mode 100644 index 8284fa1..0000000 --- a/src/Database/drivers/sqlite/sqlite_result.php +++ /dev/null @@ -1,161 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = @sqlite_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return @sqlite_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[$i] = sqlite_field_name($this->result_id, $i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = sqlite_field_name($this->result_id, $i); - $retval[$i]->type = NULL; - $retval[$i]->max_length = NULL; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return sqlite_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return sqlite_fetch_array($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return sqlite_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_utility.php b/src/Database/drivers/sqlite/sqlite_utility.php deleted file mode 100644 index af8dc80..0000000 --- a/src/Database/drivers/sqlite/sqlite_utility.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_driver.php b/src/Database/drivers/sqlite3/sqlite3_driver.php deleted file mode 100644 index e4a83dd..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_driver.php +++ /dev/null @@ -1,349 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use \Exception; - -/** - * SQLite3 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlite3'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return SQLite3 - */ - public function db_connect($persistent = FALSE) - { - if ($persistent) - { - Logger::logDebug('SQLite3 doesn\'t support persistent connections'); - } - - try - { - return ( ! $this->password) - ? new SQLite3($this->database) - : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password); - } - catch (Exception $e) - { - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - $version = SQLite3::version(); - return $this->data_cache['version'] = $version['versionString']; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @todo Implement use of SQLite3::querySingle(), if needed - * @param string $sql - * @return mixed SQLite3Result object or bool - */ - protected function _execute($sql) - { - return $this->is_write_type($sql) - ? $this->conn_id->exec($sql) - : $this->conn_id->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->conn_id->exec('BEGIN TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->conn_id->exec('END TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->conn_id->exec('ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return $this->conn_id->escapeString($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return $this->conn_id->changes(); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return $this->conn_id->lastInsertRowID(); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\'' - .(($prefix_limit !== FALSE && $this->dbprefix != '') - ? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr) - : ''); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $this->data_cache['field_names'][$table] = array(); - foreach ($result->result_array() as $row) - { - $this->data_cache['field_names'][$table][] = $row['name']; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg()); - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - $this->conn_id->close(); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_forge.php b/src/Database/drivers/sqlite3/sqlite3_forge.php deleted file mode 100644 index d8d67c8..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_forge.php +++ /dev/null @@ -1,222 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_forge extends FW_DB_forge { - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '3.3', '<')) - { - $this->_create_table_if = FALSE; - $this->_drop_table_if = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - // In SQLite, a database is dropped when we delete a file - if (file_exists($this->db->database)) - { - // We need to close the pseudo-connection first - $this->db->close(); - if ( ! @unlink($this->db->database)) - { - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @todo implement drop_column(), modify_column() - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_result.php b/src/Database/drivers/sqlite3/sqlite3_result.php deleted file mode 100644 index b78ac15..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_result.php +++ /dev/null @@ -1,191 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_result extends FW_DB_result { - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->numColumns(); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[] = $this->result_id->columnName($i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - static $data_types = array( - SQLITE3_INTEGER => 'integer', - SQLITE3_FLOAT => 'float', - SQLITE3_TEXT => 'text', - SQLITE3_BLOB => 'blob', - SQLITE3_NULL => 'null' - ); - - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $this->result_id->columnName($i); - - $type = $this->result_id->columnType($i); - $retval[$i]->type = isset($data_types[$type]) ? $data_types[$type] : $type; - - $retval[$i]->max_length = NULL; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id->finalize(); - $this->result_id = NULL; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetchArray(SQLITE3_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - // No native support for fetching rows as objects - if (($row = $this->result_id->fetchArray(SQLITE3_ASSOC)) === FALSE) - { - return FALSE; - } - elseif ($class_name === 'stdClass') - { - return (object) $row; - } - - $class_name = new $class_name(); - foreach (array_keys($row) as $key) - { - $class_name->$key = $row[$key]; - } - - return $class_name; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n (ignored) - * @return array - */ - public function data_seek($n = 0) - { - // Only resetting to the start of the result set is supported - return ($n > 0) ? FALSE : $this->result_id->reset(); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_utility.php b/src/Database/drivers/sqlite3/sqlite3_utility.php deleted file mode 100644 index 4d43081..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_utility.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Not supported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_driver.php b/src/Database/drivers/sqlsrv/sqlsrv_driver.php deleted file mode 100644 index cc5256e..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_driver.php +++ /dev/null @@ -1,538 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlsrv'; - - /** - * Scrollable flag - * - * Determines what cursor type to use when executing queries. - * - * FALSE or SQLSRV_CURSOR_FORWARD would increase performance, - * but would disable num_rows() (and possibly insert_id()) - * - * @var mixed - */ - public $scrollable; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier = TRUE; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - // This is only supported as of SQLSRV 3.0 - if ($this->scrollable === NULL) - { - $this->scrollable = defined('SQLSRV_CURSOR_CLIENT_BUFFERED') - ? SQLSRV_CURSOR_CLIENT_BUFFERED - : FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $pooling - * @return resource - */ - public function db_connect($pooling = FALSE) - { - $charset = in_array(strtolower($this->char_set), array('utf-8', 'utf8'), TRUE) - ? 'UTF-8' : SQLSRV_ENC_CHAR; - - $connection = array( - 'UID' => empty($this->username) ? '' : $this->username, - 'PWD' => empty($this->password) ? '' : $this->password, - 'Database' => $this->database, - 'ConnectionPooling' => ($pooling === TRUE) ? 1 : 0, - 'CharacterSet' => $charset, - 'Encrypt' => ($this->encrypt === TRUE) ? 1 : 0, - 'ReturnDatesAsStrings' => 1 - ); - - // If the username and password are both empty, assume this is a - // 'Windows Authentication Mode' connection. - if (empty($connection['UID']) && empty($connection['PWD'])) - { - unset($connection['UID'], $connection['PWD']); - } - - if (FALSE !== ($this->conn_id = sqlsrv_connect($this->hostname, $connection))) - { - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if ($this->_execute('USE '.$this->escape_identifiers($database))) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return ($this->scrollable === FALSE OR $this->is_write_type($sql)) - ? sqlsrv_query($this->conn_id, $sql) - : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => $this->scrollable)); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return sqlsrv_begin_transaction($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return sqlsrv_commit($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return sqlsrv_rollback($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return sqlsrv_rows_affected($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * Returns the last id created in the Identity column. - * - * @return string - */ - public function insert_id() - { - return $this->query('SELECT SCOPE_IDENTITY() AS insert_id')->row()->insert_id; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($info = sqlsrv_server_info($this->conn_id)) === FALSE) - { - return FALSE; - } - - return $this->data_cache['version'] = $info['SQLServerVersion']; - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool - * @return string $prefix_limit - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_escape_like_str, $this->_escape_like_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => '00000', 'message' => ''); - $sqlsrv_errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); - - if ( ! is_array($sqlsrv_errors)) - { - return $error; - } - - $sqlsrv_error = array_shift($sqlsrv_errors); - if (isset($sqlsrv_error['SQLSTATE'])) - { - $error['code'] = isset($sqlsrv_error['code']) ? $sqlsrv_error['SQLSTATE'].'/'.$sqlsrv_error['code'] : $sqlsrv_error['SQLSTATE']; - } - elseif (isset($sqlsrv_error['code'])) - { - $error['code'] = $sqlsrv_error['code']; - } - - if (isset($sqlsrv_error['message'])) - { - $error['message'] = $sqlsrv_error['message']; - } - - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // As of SQL Server 2012 (11.0.*) OFFSET is supported - if (version_compare($this->version(), '11', '>=')) - { - // SQL Server OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $limit = $this->qb_offset + $this->qb_limit; - - // An ORDER BY clause is required for ROW_NUMBER() to work - if ($this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - sqlsrv_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_forge.php b/src/Database/drivers/sqlsrv/sqlsrv_forge.php deleted file mode 100644 index ec5674b..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_result.php b/src/Database/drivers/sqlsrv/sqlsrv_result.php deleted file mode 100644 index c241eca..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_result.php +++ /dev/null @@ -1,190 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_result extends FW_DB_result { - - /** - * Scrollable flag - * - * @var mixed - */ - public $scrollable; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object $driver_object - * @return void - */ - public function __construct(&$driver_object) - { - parent::__construct($driver_object); - - $this->scrollable = $driver_object->scrollable; - } - - // -------------------------------------------------------------------- - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - // sqlsrv_num_rows() doesn't work with the FORWARD and DYNAMIC cursors (FALSE is the same as FORWARD) - if ( ! in_array($this->scrollable, array(FALSE, SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_DYNAMIC), TRUE)) - { - return parent::num_rows(); - } - - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = sqlsrv_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return @sqlsrv_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field) - { - $field_names[] = $field['Name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - foreach (sqlsrv_field_metadata($this->result_id) as $i => $field) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $field['Name']; - $retval[$i]->type = $field['Type']; - $retval[$i]->max_length = $field['Size']; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - sqlsrv_free_stmt($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return sqlsrv_fetch_array($this->result_id, SQLSRV_FETCH_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return sqlsrv_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_utility.php b/src/Database/drivers/sqlsrv/sqlsrv_utility.php deleted file mode 100644 index 91efcd6..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_utility.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'ALTER INDEX all ON %s REORGANIZE'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return bool - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/FuzeWorks/ComponentPathsTrait.php b/src/FuzeWorks/ComponentPathsTrait.php new file mode 100644 index 0000000..18ed6c6 --- /dev/null +++ b/src/FuzeWorks/ComponentPathsTrait.php @@ -0,0 +1,100 @@ +componentPaths = $componentPaths; + } + + /** + * Add a path where objects for this component can be found + * + * @param string $componentPath + * @param int $priority + */ + public function addComponentPath($componentPath, $priority = Priority::NORMAL) + { + if (!isset($this->componentPaths[$priority])) + $this->componentPaths[$priority] = []; + + if (!in_array($componentPath, $this->componentPaths[$priority])) + $this->componentPaths[$priority][] = $componentPath; + } + + /** + * Remove a path where objects for this component can be found + * + * @param string $componentPath + * @param int $priority + */ + public function removeComponentPath($componentPath, $priority = Priority::NORMAL) + { + if (!isset($this->componentPaths[$priority])) + return; + + if (($key = array_search($componentPath, $this->componentPaths[$priority])) !== false) + unset($this->componentPaths[$priority][$key]); + } + + /** + * Get a list of all current componentPaths + * + * @param int $priority + * @return array of paths where objects for this component can be found + */ + public function getComponentPaths($priority = Priority::NORMAL): array + { + return (isset($this->componentPaths[$priority]) ? $this->componentPaths[$priority] : []); + } +} \ No newline at end of file diff --git a/src/FuzeWorks/Config.php b/src/FuzeWorks/Config.php index d1ad958..7ced647 100644 --- a/src/FuzeWorks/Config.php +++ b/src/FuzeWorks/Config.php @@ -1,71 +1,70 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; use FuzeWorks\ConfigORM\ConfigORM; +use FuzeWorks\Event\ConfigGetEvent; use FuzeWorks\Exception\ConfigException; +use FuzeWorks\Exception\EventException; /** * Config Class. * * This class gives access to the config files. It allows you to open configurations and edit them. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @todo Implement config extensions + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Config { + use ComponentPathsTrait; /** * Array where all config files are saved while FuzeWorks runs * * @var array Array of all loaded config file ORM's */ - protected $cfg = array(); + protected $cfg = []; /** - * Paths where Helpers can be found. - * - * Libraries will only be loaded if either a directory is supplied or it is in one of the helperPaths - * - * @var array Array of paths where helpers can be found + * Array of config values that will be overridden + * + * @var array of config values */ - protected $configPaths = array(); - - public function __construct() - { - $this->configPaths[] = Core::$appDir . DS. 'Config'; - } + public static $configOverrides = []; /** * Retrieve a config file object @@ -75,30 +74,44 @@ class Config * @return ConfigORM of the config file. Allows for easy reading and editing of the file * @throws ConfigException */ - public function getConfig($configName, array $configPaths = array()): ConfigORM + public function getConfig(string $configName, array $configPaths = []): ConfigORM { - // First determine what directories to use - $directories = (empty($configPaths) ? $this->configPaths : $configPaths); - // Determine the config name $configName = strtolower($configName); - + // If it's already loaded, return the existing object if (isset($this->cfg[$configName])) { return $this->cfg[$configName]; } + // First determine what directories to use + $paths = []; + if (!empty($configPaths)) + $paths[3] = $configPaths; + else + $paths = $this->componentPaths; + // Otherwise try and load a new one - $this->cfg[$configName] = $this->loadConfigFile($configName, $directories); + $this->cfg[$configName] = $this->loadConfigFile($configName, $paths); return $this->cfg[$configName]; } - + + /** + * @param $configName + * @return ConfigORM + * @throws ConfigException + */ public function get($configName): ConfigORM { return $this->getConfig($configName); } + /** + * @param $configName + * @return ConfigORM + * @throws ConfigException + */ public function __get($configName): ConfigORM { return $this->getConfig($configName); @@ -109,7 +122,7 @@ class Config */ public function discardConfigFiles() { - $this->cfg = array(); + $this->cfg = []; } /** @@ -120,68 +133,92 @@ class Config * @return ConfigORM of the config file. Allows for easy reading and editing of the file * @throws ConfigException */ - protected function loadConfigFile($configName, array $configPaths): ConfigORM + protected function loadConfigFile(string $configName, array $configPaths): ConfigORM { - // Cycle through all directories - foreach ($configPaths as $directory) + // Fire event to intercept the loading of a config file + /** @var ConfigGetEvent $event */ + try { + $event = Events::fireEvent('configGetEvent', $configName, $configPaths); + // @codeCoverageIgnoreStart + } catch (EventException $e) { + throw new ConfigException("Could not load config. ConfigGetEvent fired exception: '" . $e->getMessage() . "''", 1); + // @codeCoverageIgnoreEnd + } + + // If cancelled, load empty config + if ($event->isCancelled()) + return new ConfigORM(); + + // Cycle through all priorities if they exist + for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) { - // If file exists, load it and break the loop - $file = $directory . DS . 'config.'.$configName.'.php'; - if (file_exists($file)) + if (!isset($event->configPaths[$i])) + continue; + + // Cycle through all directories + foreach ($event->configPaths[$i] as $configPath) { - // Load object - return new ConfigORM($file); - break; + // If file exists, load it and break the loop + $file = $configPath . DS . 'config.'.strtolower($event->configName).'.php'; + if (file_exists($file)) + { + // Load object + $configORM = (new ConfigORM())->load($file); + + // Override config values if they exist + if (isset(self::$configOverrides[$event->configName])) + { + foreach (self::$configOverrides[$event->configName] as $configKey => $configValue) + $configORM->{$configKey} = $configValue; + } + + // Return object + return $configORM; + } } } // Try fallback - $file = Core::$coreDir . DS . 'Config' . DS . 'config.' . $configName . '.php'; + $file = Core::$coreDir . DS . 'Config' . DS . 'config.' . $event->configName . '.php'; if (file_exists($file)) { // Load object - return new ConfigORM($file); + $configORM = (new ConfigORM())->load($file); + + // Override config values if they exist + if (isset(self::$configOverrides[$event->configName])) + { + foreach (self::$configOverrides[$event->configName] as $configKey => $configValue) + $configORM->{$configKey} = $configValue; + } + + // Return object + return $configORM; } - throw new ConfigException("Could not load config. File $configName not found", 1); + throw new ConfigException("Could not load config. File $event->configName not found", 1); } /** - * Add a path where config files can be found - * - * @param string $directory The directory - * @return void + * Override a config value before FuzeWorks is loaded. + * + * Allows the user to change any value in config files loaded by FuzeWorks. + * + * @param string $configName + * @param string $configKey + * @param $configValue */ - public function addConfigPath($directory) + public static function overrideConfig(string $configName, string $configKey, $configValue) { - if (!in_array($directory, $this->configPaths)) - { - $this->configPaths[] = $directory; - } - } + // Convert configName + $configName = strtolower($configName); - /** - * Remove a path where config files can be found - * - * @param string $directory The directory - * @return void - */ - public function removeConfigPath($directory) - { - if (($key = array_search($directory, $this->configPaths)) !== false) - { - unset($this->configPaths[$key]); - } - } + // If config doesn't exist yet, create it + if (!isset(self::$configOverrides[$configName])) + self::$configOverrides[$configName] = []; - /** - * Get a list of all current configPaths - * - * @return array Array of paths where config files can be found - */ - public function getConfigPaths(): array - { - return $this->configPaths; + // And set the value + self::$configOverrides[$configName][$configKey] = $configValue; } } \ No newline at end of file diff --git a/src/FuzeWorks/ConfigORM/ConfigORM.php b/src/FuzeWorks/ConfigORM/ConfigORM.php index cdf13db..8d90c6d 100644 --- a/src/FuzeWorks/ConfigORM/ConfigORM.php +++ b/src/FuzeWorks/ConfigORM/ConfigORM.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks\ConfigORM; @@ -38,9 +42,8 @@ use FuzeWorks\Exception\ConfigException; * * Handles entries in the config directory of FuzeWorks and is able to dynamically update them when requested * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @todo Implement unit tests + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class ConfigORM extends ConfigORMAbstract { @@ -52,28 +55,30 @@ class ConfigORM extends ConfigORMAbstract private $file; /** - * Sets up the class and the connection to the PHP file. + * Load the ConfigORM file. * - * @param string $filename The current filename - * - * @throws ConfigException on fatal error + * @param string $file + * @return ConfigORM + * @throws ConfigException */ - public function __construct($file = null) + public function load(string $file = ''): ConfigORM { - if (is_null($file)) + if (empty($file)) { throw new ConfigException('Could not load config file. No file provided', 1); } - elseif (file_exists($file)) + elseif (file_exists($file)) { $this->file = $file; $this->cfg = (array) include $file; $this->originalCfg = $this->cfg; - } - else + } + else { throw new ConfigException('Could not load config file. Config file does not exist', 1); } + + return $this; } /** @@ -81,7 +86,7 @@ class ConfigORM extends ConfigORMAbstract * * @throws ConfigException on fatal error */ - public function commit() + public function commit(): bool { // Write the changes if (is_writable($this->file)) { @@ -90,6 +95,6 @@ class ConfigORM extends ConfigORMAbstract return true; } - throw new ConfigException("Could not write config file. $file is not writable", 1); + throw new ConfigException("Could not write config file. $this->file is not writable", 1); } } \ No newline at end of file diff --git a/src/FuzeWorks/ConfigORM/ConfigORMAbstract.php b/src/FuzeWorks/ConfigORM/ConfigORMAbstract.php index 12a3872..c4c7070 100644 --- a/src/FuzeWorks/ConfigORM/ConfigORMAbstract.php +++ b/src/FuzeWorks/ConfigORM/ConfigORMAbstract.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks\ConfigORM; @@ -39,25 +43,24 @@ use Iterator; * This class implements the iterator, so a config file can be accessed using foreach. * A file can also be returned using toArray(), so it will be converted to an array * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @todo Implement unit tests + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ abstract class ConfigORMAbstract implements Iterator { /** * The original state of a config file. Can be reverted to using revert(). * - * @var StdObject Config file + * @var array Config file */ - protected $originalCfg; + protected $originalCfg = []; /** * The current state of a config file. * - * @var StdObject Config file + * @var array Config file */ - protected $cfg; + protected $cfg = []; /** * Revert to the original conditions of the config file. @@ -67,12 +70,33 @@ abstract class ConfigORMAbstract implements Iterator $this->cfg = $this->originalCfg; } + /** + * Clears the current config + */ + public function clear() + { + $this->cfg = []; + } + + /** + * Replaces keys and values in the config with the provided array + * + * @param array $replacementArray + */ + public function replace(array $replacementArray) + { + foreach ($replacementArray as $key => $value) + { + $this->cfg[$key] = $value; + } + } + /** * Checks if a requested key is set in the config file. * * @param string $name Parameter name - * * @return bool true on isset, false on not + * @codeCoverageIgnore */ public function __isset($name) { @@ -83,29 +107,55 @@ abstract class ConfigORMAbstract implements Iterator * Return a value from a config file. * * @param string $name Key of the requested entry - * * @return mixed Value of the requested entry + * @codeCoverageIgnore */ public function __get($name) { return $this->cfg[$name]; } + /** + * Return a value from a config file. + * + * @param string $name Key of the requested entry + * @return mixed Value of the requested entry + * @codeCoverageIgnore + */ + public function get($name) + { + return $this->cfg[$name]; + } + /** * Sets an entry in the config file. * * @param string $name Key of the entry * @param mixed $value Value of the entry + * @codeCoverageIgnore */ public function __set($name, $value) { $this->cfg[$name] = $value; } + /** + * Sets an entry in the config file. + * + * @param string $name Key of the entry + * @param mixed $value Value of the entry + * @codeCoverageIgnore + */ + public function set($name, $value) + { + $this->cfg[$name] = $value; + } + /** * Unset a value in a config file. * * @param string Key of the entry + * @codeCoverageIgnore */ public function __unset($name) { @@ -114,6 +164,7 @@ abstract class ConfigORMAbstract implements Iterator /** * Iterator method. + * @codeCoverageIgnore */ public function rewind() { @@ -122,6 +173,7 @@ abstract class ConfigORMAbstract implements Iterator /** * Iterator method. + * @codeCoverageIgnore */ public function current() { @@ -130,6 +182,7 @@ abstract class ConfigORMAbstract implements Iterator /** * Iterator method. + * @codeCoverageIgnore */ public function key() { @@ -138,6 +191,7 @@ abstract class ConfigORMAbstract implements Iterator /** * Iterator method. + * @codeCoverageIgnore */ public function next() { @@ -146,6 +200,7 @@ abstract class ConfigORMAbstract implements Iterator /** * Iterator method. + * @codeCoverageIgnore */ public function valid() { diff --git a/src/FuzeWorks/Configurator.php b/src/FuzeWorks/Configurator.php index eff42f7..9e72214 100644 --- a/src/FuzeWorks/Configurator.php +++ b/src/FuzeWorks/Configurator.php @@ -1,38 +1,42 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\Exception\ConfiguratorException; use FuzeWorks\Exception\InvalidArgumentException; -use Tracy\Debugger; /** * Class Configurator. @@ -43,86 +47,277 @@ use Tracy\Debugger; * that FuzeWorks is loaded accordingly. * * This allows for more flexible startups. - * @author Abel Hoogeveen - * @author David Grudl - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Configurator { + /** * The parameters that will be passed to FuzeWorks. * * @var array */ - protected $parameters; + protected $parameters = ['debugEnabled' => false]; + + /** + * Components that have been added to FuzeWorks + * + * @var iComponent[] + */ + protected $components = []; + + /** + * Directories that will be passed to FuzeWorks components. + * + * These are NOT the temp and log directory. + * + * @var array of directories + */ + protected $directories = []; + + /** + * Array of ComponentClass methods to be invoked once ComponentClass is loaded + * + * @var DeferredComponentClass[] + */ + protected $deferredComponentClassMethods = []; const COOKIE_SECRET = 'fuzeworks-debug'; - /** - * Constructs the Configurator class. - * - * Loads the default parameters - */ - public function __construct() - { - $this->parameters = $this->getDefaultParameters(); - } + /* ---------------- Core Directories--------------------- */ /** - * @return array + * Sets path to temporary directory. + * + * @param string $path + * @return Configurator + * @throws InvalidArgumentException */ - protected function getDefaultParameters(): array + public function setLogDirectory(string $path): Configurator { - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - $last = end($trace); - $debugMode = static::detectDebugMode(); - return [ - 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL, - 'wwwDir' => isset($last['file']) ? dirname($last['file']) : NULL, - 'debugMode' => $debugMode - ]; + if (!is_dir($path)) + throw new InvalidArgumentException("Could not set log directory. Directory does not exist", 1); + $this->parameters['logDir'] = $path; + + return $this; } /** * Sets path to temporary directory. - * @return self + * + * @param string $path + * @return Configurator + * @throws InvalidArgumentException */ - public function setLogDirectory($path): self + public function setTempDirectory(string $path): Configurator { - $this->parameters['logDir'] = $path; + if (!is_dir($path)) + throw new InvalidArgumentException("Could not set temp directory. Directory does not exist", 1); + $this->parameters['tempDir'] = $path; + return $this; } + /** + * Add a directory to FuzeWorks + * + * @param string $directory + * @param string $category Optional + * @param int $priority + * @return $this + * @throws InvalidArgumentException + */ + public function addDirectory(string $directory, string $category, $priority = Priority::NORMAL): Configurator + { + if (!file_exists($directory)) + throw new InvalidArgumentException("Could not add directory. Directory does not exist."); + + if (!isset($this->directories[$category])) + $this->directories[$category] = []; + + if (!isset($this->directories[$category][$priority])) + $this->directories[$category][$priority] = []; + + if (!in_array($directory, $this->directories[$category][$priority])) + $this->directories[$category][$priority][] = $directory; + + return $this; + } + + /* ---------------- Components -------------------------- */ + + /** + * Registers a component that will be added to the Factory when the container is built + * + * @param iComponent $component + * @return Configurator + */ + public function addComponent(iComponent $component): Configurator + { + if (isset($this->components[get_class($component)])) + return $this; + + $component->onAddComponent($this); + $this->components[get_class($component)] = $component; + return $this; + } + + /** + * Invokes a method on a componentClass after the Container has been created. + * + * @param string $componentClass + * @param string $method + * @param callable|null $callable + * @param mixed $parameters,... Parameters for the method to be invoked + * @return DeferredComponentClass + */ + public function deferComponentClassMethod(string $componentClass, string $method, callable $callable = null) + { + // Retrieve arguments + $arguments = (func_num_args() > 3 ? array_slice(func_get_args(), 3) : []); + + // Add component + if (!isset($this->deferredComponentClassMethods[$componentClass])) + $this->deferredComponentClassMethods[$componentClass] = []; + + $deferredComponentClass = new DeferredComponentClass($componentClass, $method, $arguments, $callable); + return $this->deferredComponentClassMethods[$componentClass][] = $deferredComponentClass; + } + + /** + * Alias for deferComponentClassMethods + * + * @param string $componentClass + * @param string $method + * @param callable|null $callable + * @param mixed $parameters,... Parameters for the method to be invoked + * @return DeferredComponentClass + * @codeCoverageIgnore + */ + public function call(string $componentClass, string $method, callable $callable = null) + { + return call_user_func_array([$this, 'deferComponentClassMethod'], func_get_args()); + } + + /* ---------------- Other Features ---------------------- */ + + /** + * Override a config value before FuzeWorks is loaded. + * + * Allows the user to change any value in config files loaded by FuzeWorks. + * + * @param string $configFileName + * @param string $configKey + * @param $configValue + * @return Configurator + */ + public function setConfigOverride(string $configFileName, string $configKey, $configValue): Configurator + { + Config::overrideConfig($configFileName, $configKey, $configValue); + return $this; + } + + /** + * Set the template that FuzeWorks should use to parse debug logs + * + * @codeCoverageIgnore + * + * @var string Name of the template file + */ + public static function setLoggerTemplate($templateName) + { + Logger::setLoggerTemplate($templateName); + } + /** * Sets the default timezone. - * @return self + * @param string $timezone + * @return Configurator + * @throws InvalidArgumentException */ - public function setTimeZone($timezone): self + public function setTimeZone(string $timezone): Configurator { - date_default_timezone_set($timezone); + if (!in_array($timezone, timezone_identifiers_list())) + throw new InvalidArgumentException("Could not set timezone. Invalid timezone provided.", 1); + + @date_default_timezone_set($timezone); @ini_set('date.timezone', $timezone); // @ - function may be disabled + return $this; } /** - * Adds new parameters. The %params% will be expanded. - * @return self + * Adds new parameters. Use to quickly set multiple parameters at once + * @param array $params + * @return Configurator */ - public function setParameters(array $params): self + public function setParameters(array $params): Configurator { foreach ($params as $key => $value) { $this->parameters[$key] = $value; } + + return $this; + } + + /* ---------------- Debug Mode -------------------------- */ + + /** + * Fully enable or disable debug mode using one variable + * @return Configurator + */ + public function enableDebugMode(): Configurator + { + $this->parameters['debugEnabled'] = true; + $this->parameters['debugMatch'] = (isset($this->parameters['debugMatch']) ? $this->parameters['debugMatch'] : true); + return $this; } /** - * Sets path to temporary directory. - * @return self + * Provide a string from where debug mode can be accessed. + * Can be the following type of addresses: + * @todo + * @param string|array $address + * @return Configurator + * @throws InvalidArgumentException */ - public function setTempDirectory($path): self + public function setDebugAddress($address = 'NONE'): Configurator { - $this->parameters['tempDir'] = $path; + // First we fetch the list + if (!is_string($address) && !is_array($address)) + throw new InvalidArgumentException("Can not set debug address. Address must be a string or array",1); + + // Then we test some common cases + if (is_string($address) && $address == 'NONE') + { + $this->parameters['debugMatch'] = false; + return $this; + } + elseif (is_string($address) && $address == 'ALL') + { + $this->parameters['debugMatch'] = true; + return $this; + } + + // Otherwise we run the regular detectDebugMode from Tracy + $list = is_string($address) + ? preg_split('#[,\s]+#', $address) + : (array) $address; + $addr = isset($_SERVER['REMOTE_ADDR']) + ? $_SERVER['REMOTE_ADDR'] + : php_uname('n'); + $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) + ? $_COOKIE[self::COOKIE_SECRET] + : NULL; + if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $list[] = '127.0.0.1'; + $list[] = '::1'; + } + + $this->parameters['debugMatch'] = in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE); + return $this; } @@ -131,98 +326,88 @@ class Configurator */ public function isDebugMode(): bool { - return $this->parameters['debugMode']; - } - - /** - * Set parameter %debugMode%. - * @param bool|string|array - * @return self - */ - public function setDebugMode($value): self - { - if (is_string($value) || is_array($value)) { - $value = static::detectDebugMode($value); - } elseif (!is_bool($value)) { - throw new InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value))); - } - $this->parameters['debugMode'] = $value; - return $this; - } - - /** - * Set the email to send logs to from Tracy - * @param string - */ - public function setDebugEmail($email): self - { - $this->parameters['debugEmail'] = $email; - return $this; - } - - /** - * Detects debug mode by IP address. - * @param string|array IP addresses or computer names whitelist detection - * @return bool - */ - public static function detectDebugMode($list = NULL): bool - { - $addr = isset($_SERVER['REMOTE_ADDR']) - ? $_SERVER['REMOTE_ADDR'] - : php_uname('n'); - $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) - ? $_COOKIE[self::COOKIE_SECRET] - : NULL; - $list = is_string($list) - ? preg_split('#[,\s]+#', $list) - : (array) $list; - if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $list[] = '127.0.0.1'; - $list[] = '::1'; - } - return in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE); + return $this->parameters['debugEnabled'] && $this->parameters['debugMatch']; } /** * Create the container which holds FuzeWorks. * - * Due to the static nature of FuzeWorks, this is not yet possible. - * When issue #101 is completed, this should be resolved. + * Due to the static nature of FuzeWorks, this is not yet possible. + * When issue #101 is completed, this should be resolved. * * @return Factory + * @throws \Exception */ public function createContainer(): Factory { - // First set all the directories - Core::$appDir = $this->parameters['appDir']; - Core::$wwwDir = $this->parameters['wwwDir']; + // First set all the fixed directories Core::$tempDir = $this->parameters['tempDir']; Core::$logDir = $this->parameters['logDir']; - // Then set debug mode - if ($this->parameters['debugMode']) - { - define('ENVIRONMENT', 'DEVELOPMENT'); - } - else - { - define('ENVIRONMENT', 'PRODUCTION'); - } - - // And enable Tracy Debugger - if (class_exists('Tracy\Debugger', true)) - { - Debugger::enable(!$this->parameters['debugMode'], realpath($this->parameters['logDir'])); - if (isset($this->parameters['debugEmail'])) - { - Debugger::$email = $this->parameters['debugEmail']; - } - Logger::$useTracy = true; - } + // Then prepare the debugger + $debug = ($this->parameters['debugEnabled'] && $this->parameters['debugMatch'] ? true : false); // Then load the framework - Core::init(); + $container = Core::init(); + Logger::newLevel("Creating container..."); + if ($debug == true) + { + define('ENVIRONMENT', 'DEVELOPMENT'); + Logger::enable(); + } + else + define('ENVIRONMENT', 'PRODUCTION'); - return Factory::getInstance(); + + // Load components + foreach ($this->components as $componentSuperClass => $component) + { + Logger::logInfo("Adding Component: '" . $component->getName() . "'"); + foreach ($component->getClasses() as $componentName => $componentClass) + { + if (is_object($componentClass)) + { + $container->setInstance($componentName, $componentClass); + } + else + { + if (!class_exists($componentClass)) + throw new ConfiguratorException("Could not load component '".$componentName."'. Class '".$componentClass."' does not exist.", 1); + + $container->setInstance($componentName, new $componentClass()); + } + } + + $component->onCreateContainer($container); + } + + // Invoke deferredComponentClass on FuzeWorks\Core classes + foreach ($this->deferredComponentClassMethods as $componentClass => $deferredComponentClasses) + { + if ($container->instanceIsset($componentClass)) + { + foreach ($deferredComponentClasses as $deferredComponentClass) + { + Logger::logDebug("Invoking '" . $deferredComponentClass->method . "' on component '" . $deferredComponentClass->componentClass . "'"); + /** @var DeferredComponentClass $deferredComponentClass */ + $deferredComponentClass->invoke(call_user_func_array( + array($container->{$deferredComponentClass->componentClass}, $deferredComponentClass->method), + $deferredComponentClass->arguments + )); + } + } + } + + // Add directories to Components + foreach ($this->directories as $component => $priorityArray) + { + Logger::logDebug("Adding directories for '" . $component . "'"); + if (method_exists($container->{$component}, 'setDirectories')) + $container->{$component}->setDirectories($priorityArray); + } + + $container->initFactory(); + Logger::stopLevel(); + return $container; } } \ No newline at end of file diff --git a/src/FuzeWorks/ControllerAbstract.php b/src/FuzeWorks/ControllerAbstract.php deleted file mode 100644 index e4e278c..0000000 --- a/src/FuzeWorks/ControllerAbstract.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Abstract class ControllerAbstract. - * - * Extends all controllers to use the Factory. - * Factory should in the future be replaced with a DI container - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -abstract class ControllerAbstract extends Factory -{ -} diff --git a/src/FuzeWorks/Core.php b/src/FuzeWorks/Core.php index d323c32..a7f7328 100644 --- a/src/FuzeWorks/Core.php +++ b/src/FuzeWorks/Core.php @@ -1,46 +1,52 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; -use FuzeWorks\Exception\Exception; + use FuzeWorks\Exception\CoreException; +use FuzeWorks\Exception\EventException; /** * FuzeWorks Core. * * Holds all the modules and starts the framework. Allows for starting and managing modules * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @todo Implement unit tests for autoloader() methods + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Core { @@ -49,7 +55,7 @@ class Core * * @var string Framework version */ - public static $version = '1.0.0'; + public static $version = '1.2.0'; /** * Working directory of the Framework. @@ -60,10 +66,6 @@ class Core */ public static $cwd; - public static $appDir; - - public static $wwwDir; - public static $coreDir; public static $tempDir; @@ -71,30 +73,38 @@ class Core public static $logDir; /** - * The HTTP status code of the current request + * Array of exception handlers, sorted by priority * - * @var int $http_status_code Status code + * @var array */ - public static $http_status_code = 200; + protected static $exceptionHandlers = []; + + /** + * Array of error handlers, sorted by priority + * + * @var array + */ + protected static $errorHandlers = []; + + /** + * Array of all classMaps which can be autoloaded. + * + * @var array + */ + protected static $autoloadMap = []; /** * Initializes the core. * * @throws \Exception */ - public static function init() + public static function init(): Factory { // Set the CWD for usage in the shutdown function self::$cwd = getcwd(); // Set the core dir for when the loading of classes is required self::$coreDir = dirname(__DIR__); - - // If the environment is not yet defined, use production settings - if (!defined('ENVIRONMENT')) - { - define('ENVIRONMENT', 'PRODUCTION'); - } // Defines the time the framework starts. Used for timing functions in the framework if (!defined('STARTTIME')) { @@ -105,53 +115,37 @@ class Core // Load basics ignore_user_abort(true); register_shutdown_function(array('\FuzeWorks\Core', 'shutdown')); + set_error_handler(array('\FuzeWorks\Core', 'errorHandler'), E_ALL); + set_exception_handler(array('\FuzeWorks\Core', 'exceptionHandler')); + spl_autoload_register(['\FuzeWorks\Core', 'autoloader'], true,false); - // Load core functionality - $container = new Factory(); - - // Load the config file of the FuzeWorks core - $config = $container->config->get('core'); - - // Disable events if requested to do so - if (!$config->enable_events) - { - Events::disable(); - } - - // And initialize multiple classes - $container->layout->init(); - Language::init(); - - // And load all the plugins - $container->plugins->loadHeaders(); - - // And fire the coreStartEvent - $event = Events::fireEvent('coreStartEvent'); - if ($event->isCancelled()) { - exit; - } + // Return the Factory + return new Factory(); } /** * Stop FuzeWorks and run all shutdown functions. * * Afterwards run the Logger shutdown function in order to possibly display the log + * @throws EventException */ public static function shutdown() { // Fix Apache bug where CWD is changed upon shutdown chdir(self::$cwd); + // Log the shutdown + Logger::newLevel("Shutting FuzeWorks down gracefully"); + // Fire the Shutdown event $event = Events::fireEvent('coreShutdownEvent'); - if ($event->isCancelled() === false) { - // If the output should be displayed, send the final render and parse the logger Logger::shutdownError(); - Factory::getInstance()->output->_display(); Logger::shutdown(); } + + Logger::stopLevel(); } /** @@ -173,35 +167,140 @@ class Core return $_is_php[$version]; } - public static function isCli(): bool + public static function exceptionHandler() { - return (PHP_SAPI === 'cli' OR defined('STDIN')); + for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++) + { + if (!isset(self::$exceptionHandlers[$i])) + continue; + + foreach (self::$exceptionHandlers[$i] as $handler) + call_user_func_array($handler, func_get_args()); + } + } + + public static function errorHandler() + { + for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++) + { + if (!isset(self::$errorHandlers[$i])) + continue; + + foreach (self::$errorHandlers[$i] as $handler) + call_user_func_array($handler, func_get_args()); + } } /** - * Is HTTPS? + * Add an exception handler to be called when an exception occurs * - * Determines if the application is accessed via an encrypted - * (HTTPS) connection. - * - * @return bool + * @param callable $callback + * @param int $priority */ - public static function isHttps(): bool + public static function addExceptionHandler(callable $callback, int $priority = Priority::NORMAL) { - if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') - { - return TRUE; - } - elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') - { - return TRUE; - } - elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') - { - return TRUE; - } + if (!isset(self::$exceptionHandlers[$priority])) + self::$exceptionHandlers[$priority] = []; - return FALSE; + if (!in_array($callback, self::$exceptionHandlers[$priority])) + self::$exceptionHandlers[$priority][] = $callback; + } + + /** + * Remove an exception handler from the list + * + * @param callable $callback + * @param int $priority + */ + public static function removeExceptionHandler(callable $callback, int $priority = Priority::NORMAL) + { + if (isset(self::$exceptionHandlers[$priority]) && in_array($callback, self::$exceptionHandlers[$priority])) + { + foreach (self::$exceptionHandlers[$priority] as $i => $_callback) + if ($callback == $_callback) + unset(self::$exceptionHandlers[$priority][$i]); + } + } + + /** + * Add an error handler to be called when an error occurs + * + * @param callable $callback + * @param int $priority + */ + public static function addErrorHandler(callable $callback, int $priority = Priority::NORMAL) + { + if (!isset(self::$errorHandlers[$priority])) + self::$errorHandlers[$priority] = []; + + if (!in_array($callback, self::$errorHandlers[$priority])) + self::$errorHandlers[$priority][] = $callback; + } + + /** + * Remove an error handler from the list + * + * @param callable $callback + * @param int $priority + */ + public static function removeErrorHandler(callable $callback, int $priority = Priority::NORMAL) + { + if (isset(self::$errorHandlers[$priority]) && in_array($callback, self::$errorHandlers[$priority])) + { + foreach (self::$errorHandlers[$priority] as $i => $_callback) + if ($callback == $_callback) + unset(self::$errorHandlers[$priority][$i]); + } + } + + /** + * @param string $nameSpacePrefix + * @param string $filePath + * @throws CoreException + */ + public static function addAutoloadMap(string $nameSpacePrefix, string $filePath) + { + // Remove leading slashes + $nameSpacePrefix = ltrim($nameSpacePrefix, '\\'); + + if (isset(self::$autoloadMap[$nameSpacePrefix])) + throw new CoreException("Could not add classes to autoloader. ClassMap already exists."); + + if (!file_exists($filePath) && !is_dir($filePath)) + throw new CoreException("Could not add classes to autoloader. Provided filePath does not exist."); + + self::$autoloadMap[$nameSpacePrefix] = $filePath; + } + + public static function autoloader(string $class) + { + // Remove leading slashes + $class = ltrim($class, '\\'); + + // First attempt and find if the prefix of the class is in the autoloadMap + foreach (self::$autoloadMap as $prefix => $path) + { + // If not, try next + if (strpos($class, $prefix) === false) + continue; + + // If it contains the prefix, attempt to find the file + $className = substr($class, strlen($prefix) + 1); + $filePath = $path . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; + if (file_exists($filePath) && is_file($filePath)) + require($filePath); + } + } + + /** + * Clears the autoloader to its original state. + * + * Not intended for use by developer. Only for use during testing + * @internal + */ + public static function clearAutoloader() + { + self::$autoloadMap = []; } /** @@ -249,93 +348,12 @@ class Core } /** - * Set HTTP Status Header + * Whether the current environment is a production environment * - * @param int the status code - * @param string - * @return void + * @return bool */ - public static function setStatusHeader($code = 200, $text = '') + public static function isProduction(): bool { - if (self::isCli()) - { - return; - } - - if (empty($code) OR ! is_numeric($code)) - { - throw new Exception('Status codes must be numeric', 1); - } - - if (empty($text)) - { - is_int($code) OR $code = (int) $code; - $stati = array( - 100 => 'Continue', - 101 => 'Switching Protocols', - - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 422 => 'Unprocessable Entity', - - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported' - ); - - if (isset($stati[$code])) - { - $text = $stati[$code]; - } - else - { - throw new CoreException('No status text available. Please check your status code number or supply your own message text.', 1); - } - } - - if (strpos(PHP_SAPI, 'cgi') === 0) - { - header('Status: '.$code.' '.$text, TRUE); - } - else - { - $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; - header($server_protocol.' '.$code.' '.$text, TRUE, $code); - } + return (ENVIRONMENT === 'PRODUCTION'); } } diff --git a/src/FuzeWorks/Database.php b/src/FuzeWorks/Database.php deleted file mode 100644 index e99a8dc..0000000 --- a/src/FuzeWorks/Database.php +++ /dev/null @@ -1,278 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\DatabaseException; -use FW_DB; -use FW_DB_forge; -use FW_DB_utility; - -/** - * Database loading class - * - * Loads databases, forges and utilities in a standardized manner. - * - * @author TechFuze - * @copyright (c) 2013 - 2014, TechFuze. (https://techfuze.net) - * - */ -class Database -{ - - /** - * The default database forge. - * @var FW_DB|null - */ - protected static $defaultDB = null; - - /** - * Array of all the non-default databases - * @var array FW_DB|null - */ - protected static $databases = array(); - - /** - * The default database forge. - * @var FW_DB_forge|null - */ - protected static $defaultForge = null; - - /** - * Array of all the non-default databases forges. - * @var array FW_DB_forge|null - */ - protected static $forges = array(); - - /** - * The default database utility. - * @var FW_DB_utility|null - */ - protected static $defaultUtil = null; - - /** - * Register with the TracyBridge upon startup - */ - public function __construct() - { - if (class_exists('Tracy\Debugger', true)) - { - DatabaseTracyBridge::register(); - } - } - - /** - * Retrieve a database using a DSN or the default configuration. - * - * If a string is provided like this: 'dbdriver://username:password@hostname/database', - * the string will be interpreted and converted into a database connection parameter array. - * - * If a string is provided with a name, like this: 'default' the 'default' connection from the - * configuration file will be loaded. If no string is provided the default database will be loaded. - * - * If the $newInstance is a true boolean, a new instance will be loaded instead of loading the - * default one. $newInstance will also make sure that the loaded database is not default one. - * This behaviour will be changed in the future. - * - * - * If $queryBuilder = false is provided, the database will load without a queryBuilder. - * By default the queryBuilder will load. - * - * @param string $parameters - * @param bool $newInstance - * @param bool $queryBuilder - * @return FW_DB|bool - */ - public static function get($parameters = '', $newInstance = false, $queryBuilder = null) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadDriverEvent', $parameters, $newInstance, $queryBuilder); - if ($event->isCancelled()) - { - return false; - } - - // If an instance already exists and is requested, return it - if (isset($event->database) && empty($event->parameters)) - { - return self::$defaultDB = $event->database; - } - elseif (isset($event->database) && !empty($event->parameters)) - { - return self::$databases[$event->parameters] = $event->database; - } - elseif (empty($event->parameters) && !$event->newInstance && is_object(self::$defaultDB) && ! empty(self::$defaultDB->conn_id)) - { - return $reference = self::$defaultDB; - } - elseif (!empty($event->parameters) && !$event->newInstance && isset(self::$databases[$event->parameters])) - { - return $reference = self::$databases[$event->parameters]; - } - - // If a new instance is required, load it - require_once (Core::$coreDir . DS . 'Database'.DS.'DB.php'); - - if ($event->newInstance === TRUE) - { - $database = DB($event->parameters, $event->queryBuilder); - } - elseif (empty($event->parameters) && $event->newInstance === FALSE) - { - $database = self::$defaultDB = DB($event->parameters, $event->queryBuilder); - } - else - { - $database = self::$databases[$event->parameters] = DB($event->parameters, $event->queryBuilder); - } - - // Tie it into the Tracy Bar if available - if (class_exists('\Tracy\Debugger', true)) - { - DatabaseTracyBridge::registerDatabase($database); - } - - return $database; - } - - /** - * Retrieves a database forge from the provided or default database. - * - * If no database is provided, the default database will be used. - * - * @param FW_DB|null $database - * @param bool $newInstance - * @return FW_DB_forge - */ - public static function getForge($database = null, $newInstance = false) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadForgeEvent', $database, $newInstance); - if ($event->isCancelled()) - { - return false; - } - - // First check if we're talking about the default forge and that one is already set - if (is_object($event->forge) && ($event->forge instanceof FW_DB_forge) ) - { - return $event->forge; - } - elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultForge)) - { - return $reference = self::$defaultForge; - } - elseif ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB)) - { - isset(self::$defaultDB) OR self::get('', false); - $database =& self::$defaultDB; - } - - require_once (Core::$coreDir . DS . 'Database'.DS.'DB_forge.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.$database->dbdriver.'_forge.php'); - - if ( ! empty($database->subdriver)) - { - $driver_path = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.'subdrivers'.DS.$database->dbdriver.'_'.$database->subdriver.'_forge.php'; - if (file_exists($driver_path)) - { - require_once($driver_path); - $class = 'FW_DB_'.$database->dbdriver.'_'.$database->subdriver.'_forge'; - } - else - { - throw new DatabaseException("Could not load forge. Driver file does not exist.", 1); - } - } - else - { - $class = 'FW_DB_'.$database->dbdriver.'_forge'; - } - - // Create a new instance of set the default database - if ($event->newInstance) - { - return new $class($database); - } - else - { - return self::$defaultForge = new $class($database); - } - } - - /** - * Retrieves a database utility from the provided or default database. - * - * If no database is provided, the default database will be used. - * - * @param FW_DB|null $database - * @param bool $newInstance - * @return FW_DB_utility - */ - public static function getUtil($database = null, $newInstance = false) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadUtilEvent', $database, $newInstance); - if ($event->isCancelled()) - { - return false; - } - - // First check if we're talking about the default util and that one is already set - if (is_object($event->util) && ($event->util instanceof FW_DB_utility)) - { - return $event->util; - } - elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultUtil)) - { - return $reference = self::$defaultUtil; - } - - if ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB)) - { - isset(self::$defaultDB) OR self::get('', false); - $database = & self::$defaultDB; - } - - require_once (Core::$coreDir . DS . 'Database'.DS.'DB_utility.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.$database->dbdriver.'_utility.php'); - $class = 'FW_DB_'.$database->dbdriver.'_utility'; - - if ($event->newInstance) - { - return new $class($database); - } - else - { - return self::$defaultUtil = new $class($database); - } - } -} \ No newline at end of file diff --git a/src/FuzeWorks/DatabaseTracyBridge.php b/src/FuzeWorks/DatabaseTracyBridge.php deleted file mode 100644 index ccb97e8..0000000 --- a/src/FuzeWorks/DatabaseTracyBridge.php +++ /dev/null @@ -1,142 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks; -use Tracy\IBarPanel; -use Tracy\Debugger; - -/** - * DatabaseTracyBridge Class. - * - * This class provides a bridge between FuzeWorks\Database and Tracy Debugging tool. - * - * This class registers in Tracy, and creates a Bar object which contains information about database sessions. - * It hooks into database usage and provides the information on the Tracy Bar panel. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseTracyBridge implements IBarPanel -{ - - public static $databases = array(); - protected $results = array(); - - public static function register() - { - $class = new self(); - $bar = Debugger::getBar(); - $bar->addPanel($class); - } - - public static function registerDatabase($database) - { - self::$databases[] = $database; - } - - protected function getResults(): array - { - if (!empty($this->results)) - { - return $this->results; - } - - // First prepare global variables - $results = array(); - $results['dbCount'] = 0; - $results['queryCount'] = 0; - $results['queryTimings'] = 0.0; - $results['errorsFound'] = false; - - // Go through all databases - foreach (self::$databases as $database) { - // Increase total databases - $results['dbCount']++; - - // First determine the ID - if (!empty($database->dsn)) - { - $databaseId = $database->dsn; - } - elseif (!empty($database->username) && !empty($database->database) && !empty($database->hostname)) - { - $databaseId = $database->username . '@' . $database->hostname . '/' . $database->database; - } - else - { - $databaseId = spl_object_hash($database); - } - - // Go through all queries - foreach ($database->queries as $key => $query) { - $results['queryCount']++; - $results['queryTimings'] += $database->query_times[$key]; - $results['queries'][$databaseId][$key]['query'] = $query; - $results['queries'][$databaseId][$key]['timings'] = $database->query_times[$key]; - $results['queries'][$databaseId][$key]['data'] = $database->query_data[$key]; - - // If errors are found, set this at the top of the array - if ($database->query_data[$key]['error']['code'] != 0) - { - $results['errorsFound'] = true; - } - } - } - - // Limit the amount in order to keep things readable - $results['queryCountProvided'] = 0; - foreach ($results['queries'] as $id => $database) { - $results['queries'][$id] = array_reverse(array_slice($database, -10)); - $results['queryCountProvided'] += count($results['queries'][$id]); - } - $results = array_slice($results, -10); - - return $this->results = $results; - } - - public function getTab(): string - { - $results = $this->getResults(); - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracydatabasetab.php'; - return ob_get_clean(); - } - - public function getPanel(): string - { - // Parse the panel - $results = $this->getResults(); - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracydatabasepanel.php'; - return ob_get_clean(); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/DeferredComponentClass.php b/src/FuzeWorks/DeferredComponentClass.php new file mode 100644 index 0000000..abff4c2 --- /dev/null +++ b/src/FuzeWorks/DeferredComponentClass.php @@ -0,0 +1,107 @@ +componentClass = $componentClass; + $this->method = $method; + $this->arguments = $arguments; + $this->callback = $callback; + } + + /** + * Receives the result after being invoked. Used to save the result and send back with callable if configured. + * + * @param $result + */ + public function invoke($result) + { + $this->return = $result; + $this->invoked = true; + if (is_callable($this->callback)) + call_user_func($this->callback, $result); + } + + public function isInvoked(): bool + { + return $this->invoked; + } + + public function getResult() + { + if ($this->invoked == true) + return $this->return; + else + return false; + } + + +} \ No newline at end of file diff --git a/src/FuzeWorks/Event.php b/src/FuzeWorks/Event.php index 8dc7cc3..0d73ce7 100644 --- a/src/FuzeWorks/Event.php +++ b/src/FuzeWorks/Event.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; @@ -37,8 +41,8 @@ namespace FuzeWorks; * * A simple class for events. The only current purpose is to be able to cancel events, but it can be easily extended. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Event { diff --git a/src/FuzeWorks/Event/ConfigGetEvent.php b/src/FuzeWorks/Event/ConfigGetEvent.php new file mode 100644 index 0000000..434ab81 --- /dev/null +++ b/src/FuzeWorks/Event/ConfigGetEvent.php @@ -0,0 +1,72 @@ + + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + */ +class ConfigGetEvent extends Event +{ + + /** + * The name of the config that gets retrieved + * + * @var string + */ + public $configName; + + /** + * The directories the config might be found in + * + * @var array + */ + public $configPaths; + + + public function init(string $configName, array $configPaths) + { + $this->configName = $configName; + $this->configPaths = $configPaths; + } +} diff --git a/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php b/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php deleted file mode 100644 index 2b6fc82..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php +++ /dev/null @@ -1,85 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database driver is loaded - * - * Use this to cancel the loading of a database, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadDriverEvent extends Event -{ - /** - * A possible database that can be loaded. - * - * Provide a database in this variable and it will be loaded. It shall be identified as default if - * the parameters variable is empty. If there is a string in parameters this database shall be identified as - * such. - * - * @var FW_DB|null - */ - public $database = null; - - /** - * Parameters of the database to be loaded - * - * @var string - */ - public $parameters; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - /** - * Whether to attach the queryBuilder to the database driver - * - * @var null|bool - */ - public $queryBuilder; - - public function init($parameters = '', $newInstance = false, $queryBuilder = null) - { - $this->parameters = $parameters; - $this->newInstance = $newInstance; - $this->queryBuilder = $queryBuilder; - } -} diff --git a/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php b/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php deleted file mode 100644 index ab2d8cc..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php +++ /dev/null @@ -1,77 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database forge is loaded - * - * Use this to cancel the loading of a forge, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadForgeEvent extends Event -{ - /** - * A possible forge that can be loaded. - * - * Provide a forge in this variable and it will be loaded. - * - * @var FW_DB_forge|null - */ - public $forge = null; - - /** - * Database to be used by the forge. - * - * If no database is provided, FuzeWorks\Database shall provide the default database - * - * @var FW_DB|null - */ - public $database = null; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - public function init($database = null, $newInstance = false) - { - $this->database = $database; - $this->newInstance = $newInstance; - } -} diff --git a/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php b/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php deleted file mode 100644 index bde7470..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php +++ /dev/null @@ -1,77 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database utility is loaded - * - * Use this to cancel the loading of a util, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadUtilEvent extends Event -{ - /** - * A possible util that can be loaded. - * - * Provide a util in this variable and it will be loaded. - * - * @var FW_DB_util|null - */ - public $util = null; - - /** - * Database to be used by the util. - * - * If no database is provided, FuzeWorks\Database shall provide the default database - * - * @var FW_DB_utility|null - */ - public $database = null; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - public function init($database = null, $newInstance = false) - { - $this->database = $database; - $this->newInstance = $newInstance; - } -} diff --git a/src/FuzeWorks/Event/HaltExecutionEvent.php b/src/FuzeWorks/Event/HaltExecutionEvent.php new file mode 100644 index 0000000..8c06e07 --- /dev/null +++ b/src/FuzeWorks/Event/HaltExecutionEvent.php @@ -0,0 +1,65 @@ + + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + */ +class HaltExecutionEvent extends Event +{ + /** + * @var array Log + */ + public $log; + + public function init(array $log) + { + $this->log = $log; + } + + public function getLog(): array + { + return $this->log; + } +} diff --git a/src/FuzeWorks/Event/HelperLoadEvent.php b/src/FuzeWorks/Event/HelperLoadEvent.php index a5808fb..48bf628 100644 --- a/src/FuzeWorks/Event/HelperLoadEvent.php +++ b/src/FuzeWorks/Event/HelperLoadEvent.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks\Event; @@ -39,8 +43,8 @@ use FuzeWorks\Event; * * Use this to cancel the loading of a helper, or change the helper to be loaded * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class HelperLoadEvent extends Event { @@ -55,29 +59,14 @@ class HelperLoadEvent extends Event /** * The directory of the helper that gets loaded * - * @var string + * @var array */ - public $helperFile; + public $helperPaths; - /** - * An optional extension helper name that can get loaded. - * - * @var string|null - */ - public $extendedHelperName = null; - /** - * The directory of an optional extension helper that can get loaded - * - * @var string|null - */ - public $extendedHelperFile = null; - - public function init($helperName, $helperFile, $extendedHelperName = null, $extendedHelperFile = null) + public function init(string $helperName, array $helperPaths) { $this->helperName = $helperName; - $this->helperFile = $helperFile; - $this->extendedHelperName = $extendedHelperName; - $this->extendedHelperFile = $extendedHelperFile; + $this->helperPaths = $helperPaths; } } diff --git a/src/FuzeWorks/Event/LayoutLoadEvent.php b/src/FuzeWorks/Event/LayoutLoadEvent.php deleted file mode 100644 index b6c7fcf..0000000 --- a/src/FuzeWorks/Event/LayoutLoadEvent.php +++ /dev/null @@ -1,82 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a layout is loaded. - * - * Use this to cancel the loading of a layout, or change the file or engine of a layout - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LayoutLoadEvent extends Event -{ - /** - * The directory of the layout to be loaded. - * - * @var string - */ - public $directory; - - /** - * The file of the layout to be loaded. - * - * @var string - */ - public $file; - - /** - * The engine the file will be loaded with. - * - * @var object - */ - public $engine; - - /** - * The assigned variables to the template. - * - * @var array - */ - public $assigned_variables; - - public function init($file, $directory, $engine, $assigned_variables) - { - $this->file = $file; - $this->directory = $directory; - $this->engine = $engine; - $this->assigned_variables = $assigned_variables; - } -} diff --git a/src/FuzeWorks/Event/ModelLoadEvent.php b/src/FuzeWorks/Event/ModelLoadEvent.php deleted file mode 100644 index f2819e4..0000000 --- a/src/FuzeWorks/Event/ModelLoadEvent.php +++ /dev/null @@ -1,66 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a model is loaded. - * - * Use this to cancel the loading of a model, or change the model to be loaded - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class ModelLoadEvent extends Event -{ - /** - * The directories the model can get loaded from. - * - * @var array - */ - public $directories = array(); - - /** - * The name of the model to be loaded. - * - * @var string|null - */ - public $modelName = null; - - public function init($modelName, $directories) - { - $this->modelName = $modelName; - $this->directories = $directories; - } -} diff --git a/src/FuzeWorks/Event/NotifierEvent.php b/src/FuzeWorks/Event/NotifierEvent.php index 2c9ac5a..e910eb6 100644 --- a/src/FuzeWorks/Event/NotifierEvent.php +++ b/src/FuzeWorks/Event/NotifierEvent.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks\Event; @@ -36,11 +40,10 @@ use FuzeWorks\Event; /** * Simple event which will notify components of an event, but does not contain any data. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class NotifierEvent extends Event { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Event/PluginGetEvent.php b/src/FuzeWorks/Event/PluginGetEvent.php index 76bbc2b..2b6e415 100644 --- a/src/FuzeWorks/Event/PluginGetEvent.php +++ b/src/FuzeWorks/Event/PluginGetEvent.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 1.1.4 * - * @version Version 1.1.4 + * @version Version 1.2.0 */ namespace FuzeWorks\Event; @@ -36,8 +40,8 @@ use FuzeWorks\Event; /** * Event that will get fired when a plugin is retrieved. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class PluginGetEvent extends Event { @@ -49,13 +53,6 @@ class PluginGetEvent extends Event */ public $pluginName; - /** - * Array of directories where to look at for the plugin - * - * @var array - */ - public $directories = array(); - /** * Potential plugin to return instead. If set, the plugins class will return this object * @@ -63,10 +60,9 @@ class PluginGetEvent extends Event */ public $plugin = null; - public function init($pluginName, array $directories = array()) + public function init($pluginName) { $this->pluginName = $pluginName; - $this->directories = $directories; } /** @@ -90,4 +86,3 @@ class PluginGetEvent extends Event } } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Event/RouterLoadCallableEvent.php b/src/FuzeWorks/Event/RouterLoadCallableEvent.php deleted file mode 100644 index f079b52..0000000 --- a/src/FuzeWorks/Event/RouterLoadCallableEvent.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Class routerLoadCallableEvent. - * - * Called when a callable is about to be loaded - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class routerLoadCallableEvent extends Event -{ - /** - * @var callable The callable - */ - public $callable; - - /** - * @var array The matches with the routing path - */ - public $matches = array(); - - /** - * The route which was matched. - * - * @var null|string - */ - public $route = null; - - public function init($callable, $matches, $route) - { - $this->callable = $callable; - $this->matches = $matches; - $this->route = $route; - } -} diff --git a/src/FuzeWorks/Event/RouterLoadControllerEvent.php b/src/FuzeWorks/Event/RouterLoadControllerEvent.php deleted file mode 100644 index ce209a4..0000000 --- a/src/FuzeWorks/Event/RouterLoadControllerEvent.php +++ /dev/null @@ -1,100 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets fired when a controller is loaded. - * - * Use this to cancel the loading of a controller, or change the details of what is loaded. - * - * Currently only used by Router::defaultCallable(); - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class RouterLoadControllerEvent extends Event -{ - /** - * The directory where the controller is located - * - * @var string - */ - public $directory; - - /** - * The file in which the controller is found - * - * @var string - */ - public $file; - - /** - * The class of the controller - * - * @var string - */ - public $className; - - /** - * The name of the controller - * - * @var string - */ - public $controller; - - /** - * The function that will be loaded in the controller - * - * @var string - */ - public $function; - - /** - * The parameters that will be provided to the function in the controller - * - * @var string|null - */ - public $parameters; - - public function init($file, $directory, $className, $controller, $function, $parameters) - { - $this->file = $file; - $this->directory = $directory; - $this->className = $className; - $this->controller = $controller; - $this->function = $function; - $this->parameters = $parameters; - } -} diff --git a/src/FuzeWorks/Event/RouterRouteEvent.php b/src/FuzeWorks/Event/RouterRouteEvent.php deleted file mode 100644 index 8a7c62e..0000000 --- a/src/FuzeWorks/Event/RouterRouteEvent.php +++ /dev/null @@ -1,89 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Class routerRouteEvent. - * - * Fired after the router has extracted the path, and is about to find out what route matches the path. - * - * This Event is usefull for adding routes. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class routerRouteEvent extends Event -{ - /** - * @var array The routing table - */ - public $routes; - - /** - * @var bool Whether the callable will be loaded directly after or not - */ - public $performLoading; - - /** - * Whether a cached page should be ignored or not - * - * @var bool true if cache should not be used - */ - public $cacheOverride = false; - - /** - * The current path input to FuzeWorks. - * - * @var null|string - */ - public $path; - - public function init($routes, $performLoading, $path) - { - $this->routes = $routes; - $this->performLoading = $performLoading; - $this->path = $path; - } - - /** - * Whether a cached page should be ignored or not - * - * @param bool $overrideCache true if cache should not be used - */ - public function overrideCache($bool = true) - { - $this->cacheOverride = $bool; - } -} diff --git a/src/FuzeWorks/EventPriority.php b/src/FuzeWorks/EventPriority.php deleted file mode 100644 index db841d3..0000000 --- a/src/FuzeWorks/EventPriority.php +++ /dev/null @@ -1,108 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Class EventPriority. - * - * The EventPriority is an "enum" which gives priorities an integer value, the higher the integer value, the lower the - * priority. The available priorities are, from highest to lowest: - * - * EventPriority::MONITOR - * EventPriority::HIGHEST - * EventPriority::HIGH - * EventPriority::NORMAL - * EventPriority::LOW - * EventPriority::LOWEST - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -abstract class EventPriority -{ - const LOWEST = 5; - const LOW = 4; - const NORMAL = 3; - const HIGH = 2; - const HIGHEST = 1; - const MONITOR = 0; - - /** - * Returns the string of the priority based on the integer. - * - * @param $intPriorty - * - * @return bool|string A bool when the integer isn't a priority. If the integer is a priority, the name is returned - */ - public static function getPriority($intPriorty) - { - switch ($intPriorty) { - case 5: - return 'EventPriority::LOWEST'; - case 4: - return 'EventPriority::LOW'; - case 3: - return 'EventPriority::NORMAL'; - case 2: - return 'EventPriority::HIGH'; - case 1: - return 'EventPriority::HIGHEST'; - case 0: - return 'EventPriority::MONITOR'; - default: - return false; - } - } - - /** - * Returns the highest priority - * This function is needed for the firing of events in the right order,. - * - * @return int - */ - public static function getHighestPriority() - { - return self::MONITOR; - } - - /** - * Returns the lowest priority - * This function is needed for the firing of events in the right order,. - * - * @return int - */ - public static function getLowestPriority() - { - return self::LOWEST; - } -} diff --git a/src/FuzeWorks/Events.php b/src/FuzeWorks/Events.php index 7f50036..492c396 100644 --- a/src/FuzeWorks/Events.php +++ b/src/FuzeWorks/Events.php @@ -1,36 +1,41 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\Event\NotifierEvent; use FuzeWorks\Exception\EventException; /** @@ -42,7 +47,7 @@ use FuzeWorks\Exception\EventException; * If we want to add the current time at the end of each page title, we need to hook to the corresponding event. Those events are found in the 'events' directory in the system directory. * The event that will be fired when the title is changing is called layoutSetTitleEvent. So if we want our module to hook to that event, we add the following to the constructor: * - * Events::addListener(array($this, "onLayoutSetTitleEvent"), "layoutSetTitleEvent", EventPriority::NORMAL); + * Events::addListener(array($this, "onLayoutSetTitleEvent"), "layoutSetTitleEvent", Priority::NORMAL); * * This will add the function "onLayoutSetTitleEvent" of our current class ($this) to the list of listeners with priority NORMAL. So we need to add * a method called onLayoutSetTitleEvent($event) it is very important to add the pointer-reference (&) or return the event, otherwise it doesn't change the event variables. @@ -51,8 +56,8 @@ use FuzeWorks\Exception\EventException; * * $event->title = date('H:i:s ').$event->title; * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Events { @@ -73,27 +78,22 @@ class Events /** * Adds a function as listener. * - * @param mixed $callback The callback when the events get fired, see {@link http://php.net/manual/en/language.types.callable.php PHP.net} - * @param string $eventName The name of the event - * @param int $priority The priority, even though integers are valid, please use EventPriority (for example EventPriority::Lowest) - * @param mixed $parameters,... Parameters for the listener + * @param callable $callback The callback when the events get fired, see {@link http://php.net/manual/en/language.types.callable.php PHP.net} + * @param string $eventName The name of the event + * @param int $priority The priority, even though integers are valid, please use Priority (for example Priority::Lowest) + * @param mixed $parameters,... Parameters for the listener * - * @see EventPriority + * @see Priority * * @throws EventException */ - public static function addListener($callback, $eventName, $priority = EventPriority::NORMAL) + public static function addListener(callable $callback, string $eventName, int $priority = Priority::NORMAL) { // Perform multiple checks - if (EventPriority::getPriority($priority) == false) { + if (Priority::getPriority($priority) == false) { throw new EventException('Can not add listener: Unknown priority '.$priority, 1); } - if (!is_callable($callback)) - { - throw new EventException("Can not add listener: Callback is not callable", 1); - } - if (empty($eventName)) { throw new EventException("Can not add listener: No eventname provided", 1); @@ -123,15 +123,15 @@ class Events * * @param mixed callback The callback when the events get fired, see {@link http://php.net/manual/en/language.types.callable.php PHP.net} * @param string $eventName The name of the event - * @param int $priority The priority, even though integers are valid, please use EventPriority (for example EventPriority::Lowest) + * @param int $priority The priority, even though integers are valid, please use Priority (for example Priority::Lowest) * - * @see EventPriority + * @see Priority * * @throws EventException */ - public static function removeListener($callback, $eventName, $priority = EventPriority::NORMAL) + public static function removeListener(callable $callback, string $eventName, $priority = Priority::NORMAL) { - if (EventPriority::getPriority($priority) == false) { + if (Priority::getPriority($priority) == false) { throw new EventException('Unknown priority '.$priority); } @@ -153,12 +153,11 @@ class Events * * The Event gets created, passed around and then returned to the issuer. * - * @param mixed $input Object for direct event, string for system event or notifierEvent - * @param mixed $parameters,... Parameters for the event - * @todo Implement Application Events - * @todo Implement Directory input for Events from other locations (like Modules) + * @param mixed $input Object for direct event, string for system event or notifierEvent + * @param mixed $parameters,... Parameters for the event * * @return Event The Event + * @throws EventException */ public static function fireEvent($input): Event { @@ -192,8 +191,7 @@ class Events // Try a notifier event elseif (func_num_args() == 1) { - $class = "\FuzeWorks\Event\NotifierEvent"; - $event = new $class(); + $event = new NotifierEvent(); } // Or throw an exception on failure @@ -207,11 +205,6 @@ class Events throw new EventException('Event could not be loaded. Invalid variable provided.', 1); } - if (self::$enabled) - { - Logger::newLevel("Firing Event: '".$eventName."'"); - } - if (func_num_args() > 1) { call_user_func_array(array($event, 'init'), array_slice(func_get_args(), 1)); } @@ -221,16 +214,17 @@ class Events return $event; } - Logger::log('Checking for Listeners'); - //There are listeners for this event if (isset(self::$listeners[$eventName])) { + // Event with listeners found. Log it. + Logger::newLevel("Firing Event: '".$eventName."'. Found listeners: "); + //Loop from the highest priority to the lowest - for ($priority = EventPriority::getHighestPriority(); $priority <= EventPriority::getLowestPriority(); ++$priority) { + for ($priority = Priority::getHighestPriority(); $priority <= Priority::getLowestPriority(); ++$priority) { //Check for listeners in this priority if (isset(self::$listeners[$eventName][$priority])) { $listeners = self::$listeners[$eventName][$priority]; - Logger::newLevel('Found listeners with priority '.EventPriority::getPriority($priority)); + Logger::newLevel('Found listeners with priority '.Priority::getPriority($priority)); //Fire the event to each listener foreach ($listeners as $callbackArray) { // @codeCoverageIgnoreStart @@ -244,6 +238,7 @@ class Events } // @codeCoverageIgnoreEnd + // Merge arguments and call listener $args = array_merge(array($event), $callbackArray[1]); call_user_func_array($callback, $args); Logger::stopLevel(); @@ -252,9 +247,9 @@ class Events Logger::stopLevel(); } } - } - Logger::stopLevel(); + Logger::stopLevel(); + } return $event; } diff --git a/src/FuzeWorks/Exception/ConfigException.php b/src/FuzeWorks/Exception/ConfigException.php index 43845c9..36b0cb3 100644 --- a/src/FuzeWorks/Exception/ConfigException.php +++ b/src/FuzeWorks/Exception/ConfigException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class ConfigException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class ConfigException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/ConfiguratorException.php b/src/FuzeWorks/Exception/ConfiguratorException.php new file mode 100644 index 0000000..72025ee --- /dev/null +++ b/src/FuzeWorks/Exception/ConfiguratorException.php @@ -0,0 +1,48 @@ + + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + */ +class ConfiguratorException extends Exception +{ +} + diff --git a/src/FuzeWorks/Exception/CoreException.php b/src/FuzeWorks/Exception/CoreException.php index 9f14586..1492f28 100644 --- a/src/FuzeWorks/Exception/CoreException.php +++ b/src/FuzeWorks/Exception/CoreException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class CoreException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class CoreException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/DatabaseException.php b/src/FuzeWorks/Exception/DatabaseException.php deleted file mode 100644 index 31e1cf9..0000000 --- a/src/FuzeWorks/Exception/DatabaseException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class DatabaseException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class DatabaseException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/EventException.php b/src/FuzeWorks/Exception/EventException.php index 7e508ff..8ef99fd 100644 --- a/src/FuzeWorks/Exception/EventException.php +++ b/src/FuzeWorks/Exception/EventException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class EventException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class EventException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/Exception.php b/src/FuzeWorks/Exception/Exception.php index 94ab814..f2aff91 100644 --- a/src/FuzeWorks/Exception/Exception.php +++ b/src/FuzeWorks/Exception/Exception.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,8 +39,8 @@ namespace FuzeWorks\Exception; /** * Class Exception. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Exception extends \Exception { diff --git a/src/FuzeWorks/Exception/FactoryException.php b/src/FuzeWorks/Exception/FactoryException.php index d377cf2..7756d7e 100644 --- a/src/FuzeWorks/Exception/FactoryException.php +++ b/src/FuzeWorks/Exception/FactoryException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class FactoryException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class FactoryException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/HelperException.php b/src/FuzeWorks/Exception/HelperException.php index 1e7c74c..7480c4c 100644 --- a/src/FuzeWorks/Exception/HelperException.php +++ b/src/FuzeWorks/Exception/HelperException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class HelperException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class HelperException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/InvalidArgumentException.php b/src/FuzeWorks/Exception/InvalidArgumentException.php index c7c8632..8fff516 100644 --- a/src/FuzeWorks/Exception/InvalidArgumentException.php +++ b/src/FuzeWorks/Exception/InvalidArgumentException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class InvalidArgumentException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class InvalidArgumentException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LanguageException.php b/src/FuzeWorks/Exception/LanguageException.php deleted file mode 100644 index 2c5be7a..0000000 --- a/src/FuzeWorks/Exception/LanguageException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class LanguageException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LanguageException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LayoutException.php b/src/FuzeWorks/Exception/LayoutException.php deleted file mode 100644 index 3bfaec0..0000000 --- a/src/FuzeWorks/Exception/LayoutException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class LayoutException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LayoutException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LibraryException.php b/src/FuzeWorks/Exception/LibraryException.php index 48c8839..77d25a8 100644 --- a/src/FuzeWorks/Exception/LibraryException.php +++ b/src/FuzeWorks/Exception/LibraryException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class LibraryException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class LibraryException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LoggerException.php b/src/FuzeWorks/Exception/LoggerException.php index b353320..18715ef 100644 --- a/src/FuzeWorks/Exception/LoggerException.php +++ b/src/FuzeWorks/Exception/LoggerException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class LoggerException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class LoggerException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/ModelException.php b/src/FuzeWorks/Exception/ModelException.php deleted file mode 100644 index c58aae2..0000000 --- a/src/FuzeWorks/Exception/ModelException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class ModelException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class ModelException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/PluginException.php b/src/FuzeWorks/Exception/PluginException.php index 62d902d..1b366c0 100644 --- a/src/FuzeWorks/Exception/PluginException.php +++ b/src/FuzeWorks/Exception/PluginException.php @@ -1,33 +1,37 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks - * @since Version 1.1.4 + * @since Version 0.0.1 * - * @version Version 1.1.4 + * @version Version 1.2.0 */ namespace FuzeWorks\Exception; @@ -35,11 +39,10 @@ namespace FuzeWorks\Exception; /** * Class PluginException. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class PluginException extends Exception { } -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/RouterException.php b/src/FuzeWorks/Exception/RouterException.php deleted file mode 100644 index 28c743b..0000000 --- a/src/FuzeWorks/Exception/RouterException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class RouterException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class RouterException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/SecurityException.php b/src/FuzeWorks/Exception/SecurityException.php deleted file mode 100644 index 87473f8..0000000 --- a/src/FuzeWorks/Exception/SecurityException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class SecurityException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class SecurityException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/UriException.php b/src/FuzeWorks/Exception/UriException.php deleted file mode 100644 index 8097b0b..0000000 --- a/src/FuzeWorks/Exception/UriException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class UriException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class UriException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Factory.php b/src/FuzeWorks/Factory.php index a7b0db0..37e1892 100644 --- a/src/FuzeWorks/Factory.php +++ b/src/FuzeWorks/Factory.php @@ -1,36 +1,43 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\Exception\ConfigException; +use FuzeWorks\Exception\CoreException; +use FuzeWorks\Exception\EventException; use FuzeWorks\Exception\FactoryException; /** @@ -51,8 +58,8 @@ use FuzeWorks\Exception\FactoryException; * * The Factory class is also extendible. This allows classes that extend Factory to access all it's properties. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Factory { @@ -64,12 +71,12 @@ class Factory */ private static $sharedFactoryInstance; - /** - * Whether to clone all Factory instances upon calling Factory::getInstance() - * - * @var bool Clone all Factory instances. - */ - protected static $cloneInstances = false; + /** + * Whether the Factory has been initialized or not + * + * @var bool $initialized + */ + private $initialized = false; /** * Config Object @@ -89,18 +96,6 @@ class Factory */ public $events; - /** - * Models Object - * @var Models - */ - public $models; - - /** - * Layout Object - * @var Layout - */ - public $layout; - /** * Libraries Object * @var Libraries @@ -113,64 +108,17 @@ class Factory */ public $helpers; - /** - * Database Object - * @var Database - */ - public $database; - - /** - * Language Object - * @var Language - */ - public $language; - - /** - * Utf8 Object - * @var Utf8 - */ - public $utf8; - - /** - * URI Object - * @var URI - */ - public $uri; - - /** - * Security Object - * @var Security - */ - public $security; - - /** - * Input Object - * @var Input - */ - public $input; - - /** - * Output Object - * @var Output - */ - public $output; - - /** - * Router Object - * @var Router - */ - public $router; - /** * Plugins Object * @var Plugins */ public $plugins; - /** - * Factory instance constructor. Should only really be called once - * @return void - */ + /** + * Factory instance constructor. Should only really be called once + * @throws ConfigException + * @throws FactoryException + */ public function __construct() { // If there is no sharedFactoryInstance, prepare it @@ -181,21 +129,11 @@ class Factory $this->config = new Config(); $this->logger = new Logger(); $this->events = new Events(); - $this->models = new Models(); - $this->layout = new Layout(); $this->libraries = new Libraries(); $this->helpers = new Helpers(); - $this->database = new Database(); - $this->language = new Language(); - $this->utf8 = new Utf8(); - $this->uri = new URI(); - $this->output = new Output(); - $this->security = new Security(); - $this->input = new Input(); - $this->router = new Router(); $this->plugins = new Plugins(); - return true; + return; } // @codeCoverageIgnoreEnd @@ -206,53 +144,85 @@ class Factory $this->{$key} = $value; } - return true; + return; } - /** - * Get a new instance of the Factory class. - * - * @param bool $cloneInstance Whether to get a cloned instance (true) or exactly the same instance (false) - * @return Factory Instance - */ - public static function getInstance($cloneInstance = false): Factory - { - if ($cloneInstance === true || self::$cloneInstances === true) - { - return clone self::$sharedFactoryInstance; - } + /** + * Finalizes the Factory and sends out a coreStartEvent + * + * @return Factory + * @throws CoreException + */ + public function initFactory(): Factory + { + // If already initialized, cancel + if ($this->initialized) + return $this; - return self::$sharedFactoryInstance; + // Load the config file of the FuzeWorks core + try { + $cfg = $this->config->get('core'); + } catch (ConfigException $e) { + throw new CoreException("Could not initiate Factory. Config 'core' could not be found."); + } + + // Disable events if requested to do so + if (!$cfg->get('enable_events')) + Events::disable(); + + // Initialize all components + foreach ($this as $component) + { + if (method_exists($component, 'init')) + $component->init(); + } + + // Initialize all plugins + $this->plugins->loadHeadersFromPluginPaths(); + + // Log actions + Logger::logInfo("FuzeWorks initialized. Firing coreStartEvent."); + + // And fire the coreStartEvent + try { + Events::fireEvent('coreStartEvent'); + } catch (EventException $e) { + throw new CoreException("Could not initiate Factory. coreStartEvent threw exception: ".$e->getMessage()); + } + + return $this; + } + + /** + * Get an instance of a componentClass. + * + * @param string|null $instanceName + * @return mixed + * @throws FactoryException + */ + public static function getInstance(string $instanceName = null) + { + if (is_null($instanceName)) + return self::$sharedFactoryInstance; + + // Determine the instance name + $instanceName = strtolower($instanceName); + + if (!isset(self::$sharedFactoryInstance->{$instanceName})) + throw new FactoryException("Could not get instance. Instance was not found."); + + return self::$sharedFactoryInstance->{$instanceName}; } - /** - * Enable cloning all Factory instances upon calling Factory::getInstance() - * - * @return void - */ - public static function enableCloneInstances() - { - self::$cloneInstances = true; - } - - /** - * Disable cloning all Factory instances upon calling Factory::getInstance() - * - * @return void - */ - public static function disableCloneInstances() - { - self::$cloneInstances = false; - } - - /** - * Create a new instance of one of the loaded classes. - * It reloads the class. It does NOT clone it. - * - * @param string $className The name of the loaded class, WITHOUT the namespace - * @param string $namespace Optional namespace. Defaults to 'FuzeWorks\' - * @return Factory Instance - */ + /** + * Create a new instance of one of the loaded classes. + * It reloads the class. It does NOT clone it. + * + * @param string $className The name of the loaded class, WITHOUT the namespace + * @param string $namespace Optional namespace. Defaults to 'FuzeWorks\' + * @return Factory Instance + * @throws FactoryException + */ public function newInstance($className, $namespace = 'FuzeWorks\\'): self { // Determine the class to load @@ -278,42 +248,47 @@ class Factory return $this; } - /** - * Clone an instance of one of the loaded classes. - * It clones the class. It does NOT re-create it. - * - * @param string $className The name of the loaded class, WITHOUT the namespace - * @return Factory Instance - */ - public function cloneInstance($className): self + /** + * Clone an instance of one of the loaded classes. + * It clones the class. It does NOT re-create it. + * + * If the $onlyReturn = true is provided, the cloned instance will only be returned, and not set to the factory. + * + * @param string $className The name of the loaded class, WITHOUT the namespace + * @param bool $onlyReturn + * @return mixed + * @throws FactoryException + */ + public static function cloneInstance(string $className, bool $onlyReturn = false) { // Determine the class to load $instanceName = strtolower($className); - if (!isset($this->{$instanceName})) - { + if (!isset(self::$sharedFactoryInstance->{$instanceName})) throw new FactoryException("Could not clone instance of '".$instanceName."'. Instance was not found.", 1); - } + + if ($onlyReturn) + return clone self::$sharedFactoryInstance->{$instanceName}; // Clone the instance - $this->{$instanceName} = clone $this->{$instanceName}; + self::$sharedFactoryInstance->{$instanceName} = clone self::$sharedFactoryInstance->{$instanceName}; // Return itself - return $this; + return self::$sharedFactoryInstance->{$instanceName}; } /** * Set an instance of one of the loaded classes with your own $object. * Replace the existing class with one of your own. * - * @param string $className The name of the loaded class, WITHOUT the namespace + * @param string $objectName The name of the loaded class, WITHOUT the namespace * @param mixed $object Object to replace the class with * @return Factory Instance */ - public function setInstance($className, $object): self + public function setInstance($objectName, $object): self { // Determine the instance name - $instanceName = strtolower($className); + $instanceName = strtolower($objectName); // Unset and set unset($this->{$instanceName}); @@ -323,12 +298,13 @@ class Factory return $this; } - /** - * Remove an instance of one of the loaded classes. - * - * @param string $className The name of the loaded class, WITHOUT the namespace - * @return Factory Factory Instance - */ + /** + * Remove an instance of one of the loaded classes. + * + * @param string $className The name of the loaded class, WITHOUT the namespace + * @return Factory Factory Instance + * @throws FactoryException + */ public function removeInstance($className): self { // Determine the instance name @@ -345,4 +321,15 @@ class Factory // Return itself return $this; } + + /** + * Returns true if component is part of this Factory. + * + * @param $componentName + * @return bool + */ + public function instanceIsset($componentName) + { + return isset($this->{$componentName}); + } } diff --git a/src/FuzeWorks/GitTracyBridge.php b/src/FuzeWorks/GitTracyBridge.php deleted file mode 100644 index c42834b..0000000 --- a/src/FuzeWorks/GitTracyBridge.php +++ /dev/null @@ -1,257 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.3 - * - * @version Version 1.0.3 - */ - -namespace FuzeWorks; -use Tracy\IBarPanel; -use Tracy\Debugger; - -/** - * GitTracyBridge Class. - * - * This class provides adds a panel to the Tracy Bar showing the current git branch - * - * This class registers in Tracy, and creates a Bar object which contains the Git version. - * @author Copyright (c) 2015 Jakub Vyvážil - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class GitTracyBridge implements IBarPanel { - - /** - * Register the bar - */ - public static function register() - { - $class = new self(); - $bar = Debugger::getBar(); - $bar->addPanel($class); - } - - /** - * Renders HTML code for custom tab. - * - * @return string - */ - public function getTab(): string - { - $style = ''; - if ($this->getBranchName() === 'master' || $this->getBranchName() === 'staging') { - $style = 'background:#dd4742;color:white;padding:3px 4px 4px'; - } - $icon = ''; - $label = ''.$this->getBranchName().''; - - return $icon.$label; - } - - /** - * Renders HTML code for custom panel. - * - * @return string - */ - public function getPanel(): string - { - if ($this->isUnderVersionControl()) { - $title = '

GIT

'; - $warning = ''; - $cntTable = ''; - - if ($this->getBranchName() === 'master' || $this->getBranchName() === 'staging') { - $warning = '

You are working in '.$this->getBranchName().' branch

'; - } - - // commit message - if ($this->getLastCommitMessage() !== null) { - $cntTable .= 'Last commit '.$this->getLastCommitMessage().' '; - } - - // heads - if ($this->getHeads() !== null) { - $cntTable .= 'Branches '.$this->getHeads().' '; - } - - // remotes - if ($this->getRemotes() !== null) { - $cntTable .= 'Remotes '.$this->getRemotes().' '; - } - - // tags - if ($this->getTags() !== null && !empty($this->getTags())) { - $cntTable .= 'Tags '.$this->getTags().' '; - } - - $content = '
'. - $cntTable. - '
'; - - return $title.$warning.$content; - } - - return ""; - } - - protected function getBranchName(): string - { - $dir = $this->getDirectory(); - - $head = $dir.'/.git/HEAD'; - if ($dir && is_readable($head)) { - $branch = file_get_contents($head); - if (strpos($branch, 'ref:') === 0) { - $parts = explode('/', $branch); - - return substr($parts[2], 0, -1); - } - - return '('.substr($branch, 0, 7).'…)'; - } - - return 'not versioned'; - } - - protected function getLastCommitMessage() - { - $dir = $this->getDirectory(); - - $fileMessage = $dir.'/.git/COMMIT_EDITMSG'; - - if ($dir && is_readable($fileMessage)) { - $message = file_get_contents($fileMessage); - - return $message; - } - - return null; - } - - protected function getHeads() - { - $dir = $this->getDirectory(); - - $files = scandir($dir.'/.git/refs/heads'); - $message = ''; - - if ($dir && is_array($files)) { - foreach ($files as $file) { - if ($file !== '.' && $file !== '..') { - if ($file === $this->getBranchName()) { - $message .= ''.$file.' '; - } else { - $message .= $file.'
'; - } - } - } - - return $message; - } - - return null; - } - - protected function getRemotes() - { - $dir = $this->getDirectory(); - - try { - $files = scandir($dir.'/.git/refs/remotes'); - } catch (\ErrorException $e) { - return null; - } - - $message = ''; - - if ($dir && is_array($files)) { - foreach ($files as $file) { - if ($file !== '.' && $file !== '..') { - $message .= $file.' '; - } - } - - return $message; - } - - return null; - } - - protected function getTags() - { - $dir = $this->getDirectory(); - - $files = scandir($dir.'/.git/refs/tags'); - $message = ''; - - if ($dir && is_array($files)) { - foreach ($files as $file) { - if ($file !== '.' && $file !== '..') { - $message .= $file.' '; - } - } - - return $message; - } - - return null; - } - - private function getDirectory(): string - { - $scriptPath = $_SERVER['SCRIPT_FILENAME']; - - $dir = realpath(dirname($scriptPath)); - while ($dir !== false && !is_dir($dir.'/.git')) { - flush(); - $currentDir = $dir; - $dir .= '/..'; - $dir = realpath($dir); - - // Stop recursion to parent on root directory - if ($dir === $currentDir) { - break; - } - } - - return $dir; - } - - private function isUnderVersionControl(): bool - { - $dir = $this->getDirectory(); - $head = $dir.'/.git/HEAD'; - - if ($dir && is_readable($head)) { - return true; - } - - return false; - } - -} \ No newline at end of file diff --git a/src/FuzeWorks/Helpers.php b/src/FuzeWorks/Helpers.php index b1bca68..82ef361 100644 --- a/src/FuzeWorks/Helpers.php +++ b/src/FuzeWorks/Helpers.php @@ -1,36 +1,42 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\Event\HelperLoadEvent; +use FuzeWorks\Exception\EventException; use FuzeWorks\Exception\HelperException; /** @@ -49,53 +55,35 @@ use FuzeWorks\Exception\HelperException; * FuzeWorks does not load Helper Files by default, so the first step in using a Helper is to load it. Once loaded, * it becomes globally available to everything. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Helpers { + use ComponentPathsTrait; /** * Array of loadedHelpers, so that they won't be reloaded * * @var array Array of loaded helperNames */ - protected $helpers = array(); - - /** - * Paths where Helpers can be found. - * - * Libraries will only be loaded if either a directory is supplied or it is in one of the helperPaths - * - * @var array Array of paths where helpers can be found - */ - protected $helperPaths = array(); - - public function __construct() - { - $this->helperPaths = [ - Core::$appDir . DS . 'Helpers', - Core::$coreDir . DS . 'Helpers' - ]; - } + protected $helpers = []; /** * Load a helper. - * + * * Supply the name and the helper will be loaded from the supplied directory, * or from one of the helperPaths (which you can add). - * - * @param string $helperName Name of the helper - * @param string|null $directory Directory to load the helper from, will ignore $helperPaths - * @return bool Whether the helper was succesfully loaded (true if yes) + * + * @param string $helperName Name of the helper + * @param array $helperPaths + * @return bool Whether the helper was successfully loaded (true if yes) + * @throws HelperException */ - public function load($helperName, $directory = null): bool + public function load(string $helperName, array $helperPaths = []): bool { - // First determine the name of the helper - $helperName = strtolower(str_replace(array('_helper', '.php'), '', $helperName).'_helper'); - // Determine what directories should be checked - $directories = (is_null($directory) ? $this->helperPaths : array($directory)); + $helperPaths = (empty($helperPaths) ? $this->componentPaths : [3 => $helperPaths]); // Check it is already loaded if (isset($this->helpers[$helperName])) @@ -104,62 +92,51 @@ class Helpers return false; } - // First check if there is an 'extension' class - $extendedHelper = Factory::getInstance()->config->get('main')->application_prefix . $helperName; - $extendedHelperLoaded = false; - foreach ($directories as $helperPath) - { - $file = $helperPath . DS . $extendedHelper . '.php'; - if (file_exists($file)) - { - $extendedHelperLoaded = true; - $extendedHelperFile = $file; - } + /** @var HelperLoadEvent $event */ + try { + $event = Events::fireEvent('helperLoadEvent', $helperName, $helperPaths); + + // @codeCoverageIgnoreStart + } catch (EventException $e) { + throw new HelperException("Could not load helper. helperLoadEvent failed: '" . $e->getMessage() . "''"); + // @codeCoverageIgnoreEnd } - // If an extension is loaded there needs to be a base helper - if ($extendedHelperLoaded) + // If cancelled by event, abort loading helper + if ($event->isCancelled()) { - $baseHelper = Core::$coreDir . DS . 'Helpers' . DS . $helperName.'.php'; - if (!file_exists($baseHelper)) - { - throw new HelperException("Could not load helper. Base Helper not found while Extension loaded", 1); - } - - // Fire the associated event - $event = Events::fireEvent('helperLoadEvent', $helperName, $baseHelper, $extendedHelper, $extendedHelperFile); - if ($event->isCancelled()) - { - Logger::log("Not loading helper. Aborted by event"); - return false; - } - - include_once($event->extendedHelperFile); - include_once($event->helperFile); - $this->helpers[$event->helperName] = true; - Logger::log("Loading base helper '".$event->helperName."' and extended helper '".$event->extendedHelperName."'"); - return true; + Logger::log("Not loading helper. Aborted by event"); + return false; } - // If no extension exists, try loading a regular helper - foreach ($directories as $helperPath) + // Iterate over helperPaths and attempt to load if helper exists + for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) { - $file = $helperPath . DS . $helperName . '.php'; - if (file_exists($file)) - { + if (!isset($event->helperPaths[$i])) + continue; - // Fire the associated event - $event = Events::fireEvent('helperLoadEvent', $helperName, $file); - if ($event->isCancelled()) + foreach ($event->helperPaths[$i] as $helperPath) + { + $file = $helperPath . DS . $event->helperName . '.php'; + $subfile = $helperPath . DS . $event->helperName . DS . $event->helperName . '.php'; + if (file_exists($file)) { - Logger::log("Not loading helper. Aborted by event"); - return false; + // Load and register + include_once($file); + $this->helpers[$event->helperName] = true; + Logger::log("Loaded helper '".$event->helperName."'"); + return true; } - include_once($event->helperFile); - $this->helpers[$event->helperName] = true; - Logger::log("Loading helper '".$event->helperName."'"); - return true; + // If php file not in main directory, check subdirectories + elseif (file_exists($subfile)) + { + // Load and register + include_once($subfile); + $this->helpers[$event->helperName] = true; + Logger::log("Loaded helper '".$event->helperName."''"); + return true; + } } } @@ -169,51 +146,14 @@ class Helpers /** * Alias for load * @see load() for more details - * - * @param string $helperName Name of the helper - * @param string|null $directory Directory to load the helper from, will ignore $helperPaths - * @return bool Whether the helper was succesfully loaded (true if yes) + * + * @param string $helperName Name of the helper + * @param array $helperPaths + * @return bool Whether the helper was successfully loaded (true if yes) + * @throws HelperException */ - public function get($helperName, $directory = null): bool + public function get($helperName, array $helperPaths = []): bool { - return $this->load($helperName, $directory); - } - - /** - * Add a path where helpers can be found - * - * @param string $directory The directory - * @return void - */ - public function addHelperPath($directory) - { - if (!in_array($directory, $this->helperPaths)) - { - $this->helperPaths[] = $directory; - } - } - - /** - * Remove a path where helpers can be found - * - * @param string $directory The directory - * @return void - */ - public function removeHelperPath($directory) - { - if (($key = array_search($directory, $this->helperPaths)) !== false) - { - unset($this->helperPaths[$key]); - } - } - - /** - * Get a list of all current helperPaths - * - * @return array Array of paths where helpers can be found - */ - public function getHelperPaths(): array - { - return $this->helperPaths; + return $this->load($helperName, $helperPaths); } } \ No newline at end of file diff --git a/src/FuzeWorks/Input.php b/src/FuzeWorks/Input.php deleted file mode 100644 index d366a1b..0000000 --- a/src/FuzeWorks/Input.php +++ /dev/null @@ -1,873 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Input Class - * - * Pre-processes global input data for security - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Input { - - /** - * IP address of the current user - * - * @var string - */ - protected $ip_address = FALSE; - - /** - * Allow GET array flag - * - * If set to FALSE, then $_GET will be set to an empty array. - * - * @var bool - */ - protected $_allow_get_array = TRUE; - - /** - * Standardize new lines flag - * - * If set to TRUE, then newlines are standardized. - * - * @var bool - */ - protected $_standardize_newlines; - - /** - * Enable XSS flag - * - * Determines whether the XSS filter is always active when - * GET, POST or COOKIE data is encountered. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_xss = FALSE; - - /** - * Enable CSRF flag - * - * Enables a CSRF cookie token to be set. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_csrf = FALSE; - - /** - * List of all HTTP request headers - * - * @var array - */ - protected $headers = array(); - - /** - * Raw input stream data - * - * Holds a cache of php://input contents - * - * @var string - */ - protected $_raw_input_stream; - - /** - * Parsed input stream data - * - * Parsed from php://input at runtime - * - * @see Input::input_stream() - * @var array - */ - protected $_input_stream; - - /** - * Factory object, allows this class to communicate with everything in FuzeWorks - * - * @var Factory - */ - protected $factory; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Determines whether to globally enable the XSS processing - * and whether to allow the $_GET array. - * - * @return void - */ - public function __construct() - { - // First load the factory so contact can be made with everything in FuzeWorks - $this->factory = Factory::getInstance(); - - $this->_allow_get_array = ($this->factory->config->get('routing')->allow_get_array === TRUE); - $this->_enable_xss = ($this->factory->config->get('security')->global_xss_filtering === TRUE); - $this->_enable_csrf = ($this->factory->config->get('security')->csrf_protection === TRUE); - $this->_standardize_newlines = (bool) $this->factory->config->get('security')->standardize_newlines; - - // Sanitize global arrays - $this->_sanitize_globals(); - - // CSRF Protection check - if ($this->_enable_csrf === TRUE && ! Core::isCli()) - { - $this->factory->security->csrf_verify(); - } - } - - // -------------------------------------------------------------------- - - /** - * Fetch from array - * - * Internal method used to retrieve values from global arrays. - * - * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc. - * @param mixed $index Index for item to be fetched from $array - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL) - { - is_bool($xss_clean) OR $xss_clean = $this->_enable_xss; - - // If $index is NULL, it means that the whole $array is requested - isset($index) OR $index = array_keys($array); - - // allow fetching multiple keys at once - if (is_array($index)) - { - $output = array(); - foreach ($index as $key) - { - $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean); - } - - return $output; - } - - if (isset($array[$index])) - { - $value = $array[$index]; - } - elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation - { - $value = $array; - for ($i = 0; $i < $count; $i++) - { - $key = trim($matches[0][$i], '[]'); - if ($key === '') // Empty notation will return the value as array - { - break; - } - - if (isset($value[$key])) - { - $value = $value[$key]; - } - else - { - return NULL; - } - } - } - else - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->factory->security->xss_clean($value) - : $value; - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the GET array - * - * @param mixed $index Index for item to be fetched from $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_GET, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the POST array - * - * @param mixed $index Index for item to be fetched from $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_POST, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from POST data with fallback to GET - * - * @param string $index Index for item to be fetched from $_POST or $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post_get($index, $xss_clean = NULL) - { - return isset($_POST[$index]) - ? $this->post($index, $xss_clean) - : $this->get($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from GET data with fallback to POST - * - * @param string $index Index for item to be fetched from $_GET or $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get_post($index, $xss_clean = NULL) - { - return isset($_GET[$index]) - ? $this->get($index, $xss_clean) - : $this->post($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the COOKIE array - * - * @param mixed $index Index for item to be fetched from $_COOKIE - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function cookie($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the SERVER array - * - * @param mixed $index Index for item to be fetched from $_SERVER - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function server($index, $xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Fetch an item from the php://input stream - * - * Useful when you need to access PUT, DELETE or PATCH request data. - * - * @param string $index Index for item to be fetched - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function input_stream($index = NULL, $xss_clean = NULL) - { - // Prior to PHP 5.6, the input stream can only be read once, - // so we'll need to check if we have already done that first. - if ( ! is_array($this->_input_stream)) - { - // $this->raw_input_stream will trigger __get(). - parse_str($this->raw_input_stream, $this->_input_stream); - is_array($this->_input_stream) OR $this->_input_stream = array(); - } - - return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Set cookie - * - * Accepts an arbitrary number of parameters (up to 7) or an associative - * array in the first parameter containing all the values. - * - * @param string|mixed[] $name Cookie name or an array containing parameters - * @param string $value Cookie value - * @param int $expire Cookie expiration time in seconds - * @param string $domain Cookie domain (e.g.: '.yourdomain.com') - * @param string $path Cookie path (default: '/') - * @param string $prefix Cookie name prefix - * @param bool $secure Whether to only transfer cookies via SSL - * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) - * @return void - */ - public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) - { - if (is_array($name)) - { - // always leave 'name' in last place, as the loop will break otherwise, due to $$item - foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item) - { - if (isset($name[$item])) - { - $$item = $name[$item]; - } - } - } - - // Get the variables - $cfg = $this->factory->config->get('main'); - - if ($prefix === '' && $cfg->cookie_prefix !== '') - { - $prefix = $cfg->cookie_prefix; - } - - if ($domain == '' && $cfg->cookie_domain != '') - { - $domain = $cfg->cookie_domain; - } - - if ($path === '/' && $cfg->cookie_path !== '/') - { - $path = $cfg->cookie_path; - } - - if ($secure === FALSE && $cfg->cookie_secure === TRUE) - { - $secure = $cfg->cookie_secure; - } - - if ($httponly === FALSE && $cfg->cookie_httponly !== FALSE) - { - $httponly = $cfg->cookie_httponly; - } - - if ( ! is_numeric($expire)) - { - $expire = time() - 86500; - } - else - { - $expire = ($expire > 0) ? time() + $expire : 0; - } - - setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the IP Address - * - * Determines and validates the visitor's IP address. - * - * @return string IP address - */ - public function ip_address(): string - { - if ($this->ip_address !== FALSE) - { - return $this->ip_address; - } - - $proxy_ips = $this->factory->config->get('security')->proxy_ips; - if ( ! empty($proxy_ips) && ! is_array($proxy_ips)) - { - $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips)); - } - - $this->ip_address = $this->server('REMOTE_ADDR'); - - if ($proxy_ips) - { - foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header) - { - if (($spoof = $this->server($header)) !== NULL) - { - // Some proxies typically list the whole chain of IP - // addresses through which the client has reached us. - // e.g. client_ip, proxy_ip1, proxy_ip2, etc. - sscanf($spoof, '%[^,]', $spoof); - - if ( ! $this->valid_ip($spoof)) - { - $spoof = NULL; - } - else - { - break; - } - } - } - - if ($spoof) - { - for ($i = 0, $c = count($proxy_ips); $i < $c; $i++) - { - // Check if we have an IP address or a subnet - if (strpos($proxy_ips[$i], '/') === FALSE) - { - // An IP address (and not a subnet) is specified. - // We can compare right away. - if ($proxy_ips[$i] === $this->ip_address) - { - $this->ip_address = $spoof; - break; - } - - continue; - } - - // We have a subnet ... now the heavy lifting begins - isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.'; - - // If the proxy entry doesn't match the IP protocol - skip it - if (strpos($proxy_ips[$i], $separator) === FALSE) - { - continue; - } - - // Convert the REMOTE_ADDR IP address to binary, if needed - if ( ! isset($ip, $sprintf)) - { - if ($separator === ':') - { - // Make sure we're have the "full" IPv6 format - $ip = explode(':', - str_replace('::', - str_repeat(':', 9 - substr_count($this->ip_address, ':')), - $this->ip_address - ) - ); - - for ($j = 0; $j < 8; $j++) - { - $ip[$j] = intval($ip[$j], 16); - } - - $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b'; - } - else - { - $ip = explode('.', $this->ip_address); - $sprintf = '%08b%08b%08b%08b'; - } - - $ip = vsprintf($sprintf, $ip); - } - - // Split the netmask length off the network address - sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen); - - // Again, an IPv6 address is most likely in a compressed form - if ($separator === ':') - { - $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($i = 0; $i < 8; $i++) - { - $netaddr[$i] = intval($netaddr[$i], 16); - } - } - else - { - $netaddr = explode('.', $netaddr); - } - - // Convert to binary and finally compare - if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) - { - $this->ip_address = $spoof; - break; - } - } - } - } - - if ( ! $this->valid_ip($this->ip_address)) - { - return $this->ip_address = '0.0.0.0'; - } - - return $this->ip_address; - } - - // -------------------------------------------------------------------- - - /** - * Validate IP Address - * - * @param string $ip IP address - * @param string $which IP protocol: 'ipv4' or 'ipv6' - * @return bool - */ - public function valid_ip($ip, $which = ''): bool - { - switch (strtolower($which)) - { - case 'ipv4': - $which = FILTER_FLAG_IPV4; - break; - case 'ipv6': - $which = FILTER_FLAG_IPV6; - break; - default: - $which = NULL; - break; - } - - return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which); - } - - // -------------------------------------------------------------------- - - /** - * Fetch User Agent string - * - * @return string|null User Agent string or NULL if it doesn't exist - */ - public function user_agent($xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Globals - * - * Internal method serving for the following purposes: - * - * - Unsets $_GET data, if query strings are not enabled - * - Cleans POST, COOKIE and SERVER data - * - Standardizes newline characters to PHP_EOL - * - * @return void - */ - protected function _sanitize_globals() - { - // Is $_GET data allowed? If not we'll set the $_GET to an empty array - if ($this->_allow_get_array === FALSE) - { - $_GET = array(); - } - elseif (is_array($_GET)) - { - foreach ($_GET as $key => $val) - { - $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_POST Data - if (is_array($_POST)) - { - foreach ($_POST as $key => $val) - { - $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_COOKIE Data - if (is_array($_COOKIE)) - { - // Also get rid of specially treated cookies that might be set by a server - // or silly application, that are of no use to a CI application anyway - // but that when present will trip our 'Disallowed Key Characters' alarm - // http://www.ietf.org/rfc/rfc2109.txt - // note that the key names below are single quoted strings, and are not PHP variables - unset( - $_COOKIE['$Version'], - $_COOKIE['$Path'], - $_COOKIE['$Domain'] - ); - - foreach ($_COOKIE as $key => $val) - { - if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) - { - $_COOKIE[$cookie_key] = $this->_clean_input_data($val); - } - else - { - unset($_COOKIE[$key]); - } - } - } - - // Sanitize PHP_SELF - $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); - - Logger::logDebug('Global POST, GET and COOKIE data sanitized'); - } - - // -------------------------------------------------------------------- - - /** - * Clean Input Data - * - * Internal method that aids in escaping data and - * standardizing newline characters to PHP_EOL. - * - * @param string|string[] $str Input string(s) - * @return string|array - */ - protected function _clean_input_data($str) - { - if (is_array($str)) - { - $new_array = array(); - foreach (array_keys($str) as $key) - { - $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]); - } - return $new_array; - } - - /* We strip slashes if magic quotes is on to keep things consistent - - NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. - */ - if ( ! Core::isPHP('5.4') && get_magic_quotes_gpc()) - { - $str = stripslashes($str); - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - $str = $this->factory->utf8->clean_string($str); - } - - // Remove control characters - $str = UTF8::remove_invisible_characters($str, FALSE); - - // Standardize newlines if needed - if ($this->_standardize_newlines === TRUE) - { - return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Clean Keys - * - * Internal method that helps to prevent malicious users - * from trying to exploit keys we make sure that keys are - * only named with alpha-numeric text and a few other items. - * - * @param string $str Input string - * @param bool $fatal Whether to terminate script exection - * or to return FALSE if an invalid - * key is encountered - * @return string|bool - */ - protected function _clean_input_keys($str, $fatal = TRUE) - { - if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) - { - if ($fatal === TRUE) - { - return FALSE; - } - else - { - Core::setStatusHeader(503); - echo 'Disallowed Key Characters.'; - exit(7); // EXIT_USER_INPUT - } - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - return $this->factory->utf8->clean_string($str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Request Headers - * - * @param bool $xss_clean Whether to apply XSS filtering - * @return array - */ - public function request_headers($xss_clean = FALSE): array - { - // If header is already defined, return it immediately - if ( ! empty($this->headers)) - { - return $this->headers; - } - - // In Apache, you can simply call apache_request_headers() - if (function_exists('apache_request_headers')) - { - return $this->headers = apache_request_headers(); - } - - $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); - - foreach ($_SERVER as $key => $val) - { - if (sscanf($key, 'HTTP_%s', $header) === 1) - { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); - - $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); - } - } - - return $this->headers; - } - - // -------------------------------------------------------------------- - - /** - * Get Request Header - * - * Returns the value of a single member of the headers class member - * - * @param string $index Header name - * @param bool $xss_clean Whether to apply XSS filtering - * @return string|null The requested header on success or NULL on failure - */ - public function get_request_header($index, $xss_clean = FALSE) - { - static $headers; - - if ( ! isset($headers)) - { - empty($this->headers) && $this->request_headers(); - foreach ($this->headers as $key => $value) - { - $headers[strtolower($key)] = $value; - } - } - - $index = strtolower($index); - - if ( ! isset($headers[$index])) - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->factory->security->xss_clean($headers[$index]) - : $headers[$index]; - } - - // -------------------------------------------------------------------- - - /** - * Is AJAX request? - * - * Test to see if a request contains the HTTP_X_REQUESTED_WITH header. - * - * @return bool - */ - public function is_ajax_request(): bool - { - return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); - } - - // -------------------------------------------------------------------- - - /** - * Get Request Method - * - * Return the request method - * - * @param bool $upper Whether to return in upper or lower case - * (default: FALSE) - * @return string - */ - public function method($upper = FALSE): string - { - return ($upper) - ? strtoupper($this->server('REQUEST_METHOD')) - : strtolower($this->server('REQUEST_METHOD')); - } - - // ------------------------------------------------------------------------ - - /** - * Magic __get() - * - * Allows read access to protected properties - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - if ($name === 'raw_input_stream') - { - isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input'); - return $this->_raw_input_stream; - } - elseif ($name === 'ip_address') - { - return $this->ip_address; - } - } - -} diff --git a/src/FuzeWorks/Language.php b/src/FuzeWorks/Language.php deleted file mode 100644 index 94db4dc..0000000 --- a/src/FuzeWorks/Language.php +++ /dev/null @@ -1,231 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\LanguageException; - -/** - * Language Class. - * - * The Language Class provides functions to retrieve language files and lines of text - * for purposes of internationalization. - * - * In your FuzeWorks Core folder, you will find a Language sub-directory containing a set of language files for the english idiom. - * The files in this directory (Core/Language/english/) define the regular messages, error messages, and other generally output terms - * or expressions, for the different parts of the FuzeWorks. - * - * You can create or incorporate your own language files, as needed, in order to provide application-specific error and other messages, - * or to provide translations of the core messages into other languages. These translations or additional messages would go inside your Application/Language/ directory, - * with separate sub-directories for each idiom (for instance, ‘french’ or ‘german’). - * - * FuzeWorks comes with a set of language files for the “english” idiom. Additional approved translations for different idioms may be found in the FuzeWorks Archives. - * Each archive deals with a single idiom. - * - * When FuzeWorks loads language files, it will load the one in Core/Language/ first and will then look for an override in your Application/Language/ directory. - * - * - * @author TechFuze - * @copyright (c) 2013 - 2014, TechFuze. (https://techfuze.net) - */ -class Language -{ - - /** - * Paths where the class can find translations - * @var array - */ - protected static $languagePaths = array(); - - /** - * The current language array - * @var array - */ - protected static $language = array(); - - /** - * Array list of all the loaded languages - * @var array - */ - protected static $is_loaded = array(); - - public static function init() - { - self::$languagePaths[] = Core::$appDir . DS . 'Language'; - } - - /** - * Retrieve a language file and return the language array - * - * @param string $langfile - * @param string $idiom - * @param boolean $add_suffix - * @param string $alt_path - * @return array - * @throws LanguageException - */ - public static function get($langfile, $idiom = '', $add_suffix = TRUE, $alt_path = ''): array - { - // First we determine the file that should be loaded - $langfile = str_replace('.php', '', $langfile); - - if ($add_suffix === TRUE) - { - $langfile = preg_replace('/_lang$/', '', $langfile).'_lang'; - } - - $langfile .= '.php'; - - // Then we determine the idiom - if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom)) - { - $config = Factory::getInstance()->config->get('main'); - $idiom = empty($config->language) ? 'english' : $config->language; - } - - // Is it already loaded? Return the entire language array - if (isset(self::$is_loaded[$langfile]) && self::$is_loaded[$langfile] === $idiom) - { - return self::$language; - } - - // Prepare the language variable - $lang = array(); - - // Load the base file, so any others found can override it - $basepath = Core::$coreDir . DS. 'Language'.DS.$idiom.DS.$langfile; - if (($found = file_exists($basepath)) === TRUE) - { - $lang = array_merge($lang, (array) include($basepath)); - } - - // Do we have an alternative path to look in? - if ($alt_path !== '') - { - $alt_path .= 'Language'.DS.$idiom.DS.$langfile; - if (file_exists($alt_path)) - { - $lang = array_merge($lang, (array) include($alt_path)); - $found = TRUE; - } - } - else - { - foreach (self::$languagePaths as $languagePath) - { - $languagePath .= DS.$idiom.DS.$langfile; - if ($basepath !== $languagePath && file_exists($languagePath)) - { - $lang = array_merge($lang, (array) include($languagePath)); - $found = TRUE; - break; - } - } - } - - // If nothing is found, kill it - if ($found !== TRUE) - { - throw new LanguageException('Unable to load the requested language file: language/'.$idiom.'/'.$langfile, 1); - } - - // If only empty content is found, return the language array - if ( empty($lang) ) - { - Logger::logError('Language file contains no data: language/'.$idiom.'/'.$langfile); - - return self::$language; - } - - // Save the data and return it - self::$is_loaded[$langfile] = $idiom; - self::$language = array_merge(self::$language, $lang); - - Logger::log('Language file loaded: language/'.$idiom.'/'.$langfile); - return self::$language; - } - - /** - * Load a single line from the language array - * - * @param string $line - * @param boolean $log_errors - * @return string - */ - public static function line($line, $log_errors = TRUE): string - { - $value = isset(self::$language[$line]) ? self::$language[$line] : FALSE; - - // Because killer robots like unicorns! - if ($value === FALSE && $log_errors === TRUE) - { - Logger::logError('Could not find the language line "'.$line.'"'); - } - - return $value; - } - - /** - * Add a language path to the class - * - * @param string $directory - */ - public static function addLanguagePath($directory): string - { - if (!in_array($directory, self::$languagePaths)) - { - self::$languagePaths[] = $directory; - } - } - - /** - * Remove a languagePath from the class - * - * @param string $directory - */ - public static function removeLanguagePath($directory): string - { - if (($key = array_search($directory, self::$languagePaths)) !== false) - { - unset(self::$languagePaths[$key]); - } - } - - /** - * Retrieve an array of the languagePaths - * - * @return array - */ - public static function getLanguagePaths(): array - { - return self::$languagePaths; - } -} diff --git a/src/FuzeWorks/Layout.php b/src/FuzeWorks/Layout.php deleted file mode 100644 index b8d1aa0..0000000 --- a/src/FuzeWorks/Layout.php +++ /dev/null @@ -1,529 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks; - -use FuzeWorks\TemplateEngine\{JsonEngine,PHPEngine,SmartyEngine,LatteEngine,TemplateEngine}; -use FuzeWorks\Exception\LayoutException; - -/** - * Layout and Template Manager for FuzeWorks. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class Layout -{ - /** - * The file to be loaded by the layout manager. - * - * @var null|string - */ - public $file = null; - - /** - * The directory of the file to be loaded by the layout manager. - * - * @var string - */ - public $directory; - - /** - * All assigned currently assigned to the template. - * - * @var array Associative Assigned Variable Array - */ - private $assigned_variables = array(); - - /** - * All engines that can be used for templates. - * - * @var array of engines - */ - private $engines = array(); - - /** - * All file extensions that can be used and are bound to a template engine. - * - * @var array of names of engines - */ - private $file_extensions = array(); - - /** - * whether the template engines are already called. - * - * @var bool True if loaded - */ - private $engines_loaded = false; - - /** - * The currently selected template engine. - * - * @var string name of engine - */ - private $current_engine; - - public function init() - { - $this->directory = Core::$appDir . DS .'Layout'; - } - - /** - * Retrieve a template file using a string and a directory and immediatly parse it to the output class. - * - * What template file gets loaded depends on the template engine that is being used. - * PHP for example uses .php files. Providing this function with 'home/dashboard' will load the home/layout.dashboard.php file. - * You can also provide no particular engine, and the manager will decide what template to load. - * Remember that doing so will result in a LayoutException when multiple compatible files are found. - * - * @param string $file File to load - * @param string $directory Directory to load it from - * @param bool $directOutput Whether to directly output the result with an echo or send it to the output class. True if echo - * - * @throws LayoutException On error - */ - public function display($file, $directory = null, $directOutput = false) - { - $output = Factory::getInstance()->output; - $directory = (is_null($directory) ? $this->directory : $directory); - - if ($directOutput === true) - { - echo $this->get($file, $directory); - } - else - { - $output->append_output($this->get($file, $directory)); - } - - return; - } - - /** - * Retrieve a template file using a string and a directory. - * - * What template file gets loaded depends on the template engine that is being used. - * PHP for example uses .php files. Providing this function with 'home/dashboard' will load the home/layout.dashboard.php file. - * You can also provide no particular engine, and the manager will decide what template to load. - * Remember that doing so will result in a LayoutException when multiple compatible files are found. - * - * @param string $file File to load - * @param string $directory Directory to load it from - * - * @return string The output of the template - * - * @throws LayoutException On error - */ - public function get($file, $directory = null): string - { - $directory = (is_null($directory) ? $this->directory : $directory); - Logger::newLevel("Loading template file '".$file."' in '".$directory."'"); - - // First load the template engines - $this->loadTemplateEngines(); - - // First retrieve the filepath - if (is_null($this->current_engine)) { - $this->setFileFromString($file, $directory, array_keys($this->file_extensions)); - } else { - $this->setFileFromString($file, $directory, $this->current_engine->getFileExtensions()); - } - - // Then assign some basic variables for the template - $main_config = Factory::getInstance()->config->get('main'); - $contact_config = Factory::getInstance()->config->get('contact'); - $this->assigned_variables['wwwDir'] = $main_config->base_url; - $this->assigned_variables['siteURL'] = $main_config->base_url; - $this->assigned_variables['serverName'] = $main_config->server_name; - $this->assigned_variables['adminMail'] = $main_config->administrator_mail; - $this->assigned_variables['contact'] = $contact_config->toArray(); - $this->assigned_variables['csrfTokenName'] = Factory::getInstance()->security->get_csrf_token_name(); - $this->assigned_variables['csrfHash'] = Factory::getInstance()->security->get_csrf_hash(); - - // Select an engine if one is not already selected - if (is_null($this->current_engine)) { - $this->current_engine = $this->getEngineFromExtension($this->getExtensionFromFile($this->file)); - } - - $this->current_engine->setDirectory($this->directory); - - // And run an Event to see what other parts have to say about it - $event = Events::fireEvent('layoutLoadEvent', $this->file, $this->directory, $this->current_engine, $this->assigned_variables); - - // The event has been cancelled - if ($event->isCancelled()) { - return false; - } - - // And refetch the data from the event - $this->current_engine = $event->engine; - $this->assigned_variables = $event->assigned_variables; - - Logger::stopLevel(); - - // And finally run it - if (file_exists($event->file)) { - return $this->current_engine->get($event->file, $this->assigned_variables); - } - - throw new LayoutException('The requested file was not found', 1); - } - - /** - * Retrieve a Template Engine from a File Extension. - * - * @param string $extension File extention to look for - * - * @return TemplateEngine - */ - public function getEngineFromExtension($extension): TemplateEngine - { - if (isset($this->file_extensions[strtolower($extension)])) { - return $this->engines[ $this->file_extensions[strtolower($extension)]]; - } - - throw new LayoutException('Could not get Template Engine. No engine has corresponding file extension', 1); - } - - /** - * Retrieve the extension from a file string. - * - * @param string $fileString The path to the file - * - * @return string Extension of the file - */ - public function getExtensionFromFile($fileString): string - { - return substr($fileString, strrpos($fileString, '.') + 1); - } - - /** - * Converts a layout string to a file using the directory and the used extensions. - * - * It will detect whether the file exists and choose a file according to the provided extensions - * - * @param string $string The string used by a controller. eg: 'dashboard/home' - * @param string $directory The directory to search in for the template - * @param array $extensions Extensions to use for this template. Eg array('php', 'tpl') etc. - * - * @return string Filepath of the template - * @throws LayoutException On error - */ - public function getFileFromString($string, $directory, $extensions = array()): string - { - $directory = preg_replace('#/+#', '/', (!is_null($directory) ? $directory : $this->directory).DS); - - if (strpbrk($directory, "\\/?%*:|\"<>") === TRUE || strpbrk($string, "\\/?%*:|\"<>") === TRUE) - { - throw new LayoutException('Could not get file. Invalid file string', 1); - } - - if (!file_exists($directory)) { - throw new LayoutException('Could not get file. Directory does not exist', 1); - } - - // Set the file name and location - $layoutSelector = explode('/', $string); - if (count($layoutSelector) == 1) { - $layoutSelector = 'layout.'.$layoutSelector[0]; - } else { - // Get last file - $file = end($layoutSelector); - - // Reset to start - reset($layoutSelector); - - // Remove last value - array_pop($layoutSelector); - - $layoutSelector[] = 'layout.'.$file; - - // And create the final value - $layoutSelector = implode(DS, $layoutSelector); - } - - // Then try and select a file - $fileSelected = false; - $selectedFile = null; - foreach ($extensions as $extension) { - $file = $directory.$layoutSelector.'.'.strtolower($extension); - $file = preg_replace('#/+#', '/', $file); - if (file_exists($file) && !$fileSelected) { - $selectedFile = $file; - $fileSelected = true; - Logger::log("Found matching file: '".$file."'"); - } elseif (file_exists($file) && $fileSelected) { - throw new LayoutException('Could not select template. Multiple valid extensions detected. Can not choose.', 1); - } - } - - // And choose what to output - if (!$fileSelected) { - throw new LayoutException('Could not select template. No matching file found.'); - } - - return $selectedFile; - } - - /** - * Converts a layout string to a file using the directory and the used extensions. - * It also sets the file variable of this class. - * - * It will detect whether the file exists and choose a file according to the provided extensions - * - * @param string $string The string used by a controller. eg: 'dashboard/home' - * @param string $directory The directory to search in for the template - * @param array $extensions Extensions to use for this template. Eg array('php', 'tpl') etc. - * - * @return string Filepath of the template - * @throws LayoutException On error - */ - public function setFileFromString($string, $directory, $extensions = array()) - { - $this->file = $this->getFileFromString($string, $directory, $extensions); - $this->directory = preg_replace('#/+#', '/', (!is_null($directory) ? $directory : $this->directory).DS); - } - - /** - * Get the current file to be loaded. - * - * @return null|string Path to the file - */ - public function getFile() - { - return $this->file; - } - - /** - * Set the file to be loaded. - * - * @param string $file Path to the file - */ - public function setFile($file): string - { - $this->file = $file; - } - - /** - * Get the directory of the file to be loaded. - * - * @return null|string Path to the directory - */ - public function getDirectory() - { - return $this->directory; - } - - /** - * Set the directory of the file to be loaded. - * - * @param string $directory Path to the directory - */ - public function setDirectory($directory) - { - $this->directory = $directory; - } - - /** - * Assign a variable for the template. - * - * @param string $key Key of the variable - * @param mixed $value Value of the variable - */ - public function assign($key, $value) - { - $this->assigned_variables[$key] = $value; - } - - /** - * Set the title of the template. - * - * @param string $title title of the template - */ - public function setTitle($title) - { - $this->assigned_variables['title'] = $title; - } - - /** - * Get the title of the template. - * - * @return string|bool title of the template - */ - public function getTitle() - { - if (!isset($this->assigned_variables['title'])) - { - return false; - } - return $this->assigned_variables['title']; - } - - /** - * Set the engine for the next layout. - * - * @param string $name Name of the template engine - * - * @return bool true on success - * @throws LayoutException on error - */ - public function setEngine($name): bool - { - $this->loadTemplateEngines(); - if (isset($this->engines[$name])) { - $this->current_engine = $this->engines[$name]; - Logger::log('Set the Template Engine to '.$name); - - return true; - } - throw new LayoutException('Could not set engine. Engine does not exist', 1); - } - - /** - * Get a loaded template engine. - * - * @param string $name Name of the template engine - * - * @return TemplateEngine - */ - public function getEngine($name): TemplateEngine - { - $this->loadTemplateEngines(); - if (isset($this->engines[$name])) { - return $this->engines[$name]; - } - throw new LayoutException('Could not return engine. Engine does not exist', 1); - } - - /** - * Register a new template engine. - * - * @param object $engineClass Object that implements the \FuzeWorks\TemplateEngine - * @param string $engineName Name of the template engine - * @param array $engineFileExtensions File extensions this template engine should be used for - * - * @return bool true on success - * @throws LayoutException - */ - public function registerEngine($engineClass, $engineName, $engineFileExtensions = array()): bool - { - // First check if the engine already exists - if (isset($this->engines[$engineName])) { - throw new LayoutException("Could not register engine. Engine '".$engineName."' already registered", 1); - } - - // Then check if the object is correct - if ($engineClass instanceof TemplateEngine) { - // Install it - $this->engines[$engineName] = $engineClass; - - // Then define for what file extensions this Template Engine will work - if (!is_array($engineFileExtensions)) { - throw new LayoutException('Could not register engine. File extensions must be an array', 1); - } - - // Then install them - foreach ($engineFileExtensions as $extension) { - if (isset($this->file_extensions[strtolower($extension)])) { - throw new LayoutException('Could not register engine. File extension already bound to engine', 1); - } - - // And add it - $this->file_extensions[strtolower($extension)] = $engineName; - } - - // And log it - Logger::log('Registered Template Engine: '.$engineName); - - return true; - } - - throw new LayoutException("Could not register engine. Engine must implement \FuzeWorks\TemplateEngine", 1); - } - - /** - * Load the template engines by sending a layoutLoadEngineEvent. - */ - public function loadTemplateEngines() - { - if (!$this->engines_loaded) { - Events::fireEvent('layoutLoadEngineEvent'); - - // Load the engines provided in this file - $this->registerEngine(new PHPEngine(), 'PHP', array('php')); - $this->registerEngine(new JsonEngine(), 'JSON', array('json')); - $this->registerEngine(new SmartyEngine(), 'Smarty', array('tpl')); - $this->registerEngine(new LatteEngine(), 'Latte', array('latte')); - $this->engines_loaded = true; - } - } - - /** - * Calls a function in the current Template engine. - * - * @param string $name Name of the function to be called - * @param mixed $params Parameters to be used - * - * @return mixed Function output - */ - public static function __callStatic($name, $params) - { - // First load the template engines - $this->loadTemplateEngines(); - - if (!is_null($this->current_engine)) { - // Call user func array here - return call_user_func_array(array($this->current_engine, $name), $params); - } - throw new LayoutException('Could not access Engine. Engine not loaded', 1); - } - - /** - * Resets the layout manager to its default state. - */ - public function reset() - { - if (!is_null($this->current_engine)) { - $this->current_engine->reset(); - } - - // Unload the engines - $this->engines = array(); - $this->engines_loaded = false; - $this->file_extensions = array(); - - $this->current_engine = null; - $this->assigned_variables = array(); - $this->directory = Core::$appDir . DS . 'Layout'; - Logger::log('Reset the layout manager to its default state'); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/Libraries.php b/src/FuzeWorks/Libraries.php index d2da8c4..07ab638 100644 --- a/src/FuzeWorks/Libraries.php +++ b/src/FuzeWorks/Libraries.php @@ -1,462 +1,230 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; -use FuzeWorks\Exception\LibraryException; -use FuzeWorks\Exception\ConfigException; -/** - * Libraries Class. - * - * FuzeWorks allows the user to use the built-in libraries as-is, and use it's functionality to get jobs done. - * - * If a user wants to make their own libraries, they have, in general, 3 options: - * 1. Create a completely new library - * 2. Extend an existing library - * 3. Replace an existing library - * - * The first option is done by adding a new library to the Application/Libraries folder. If the library name is 'Example' then the - * file should be 'Application/Libraries/Example.php' and the classname should be Example. Code can be added and it can be - * loaded through Libraries->get('example');. - * - * The second option allows the user to extend an existing core library. All functionality will be inherited in that situation. Let's take - * the 'Zip' library as an example. The user needs to create a file in Application/Libraries. The name of the file and the class depend on - * the configuration of FuzeWorks. The extended class needs to get a prefix, which is defined in config.main.php. By default, this is 'MY_'. - * The user needs to create the file 'Application/Libraries/MY_Zip.php' with the classname MY_Zip. It can be loaded through Libraries->get('zip');. - * - * The third option allows the user to replace a system library with their own. Doing so could potentially break systems, so be careful. - * If, for example we want to replace the Zip library, we need to create the file 'Application/Libraries/Zip.php' with the classname FW_Zip. - * 'FW_' is the prefix for all FuzeWorks core libraries. And that's it. It can be loaded through Libraries->get('zip');. - * - * @todo Implement events - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ +use FuzeWorks\Exception\ConfigException; +use FuzeWorks\Exception\CoreException; +use FuzeWorks\Exception\LibraryException; +use ReflectionClass; +use ReflectionException; + class Libraries { - - /** - * Factory object for interaction with FuzeWorks - * - * @var Factory - */ - protected $factory; - - /** - * Array of all the paths where libraries can be found - * - * @var array Library paths - */ - protected $libraryPaths = array(); - - /** - * Array of all the loaded library objects - * - * @var array All the loaded library objects, so they can be returned when reloading - */ - protected $libraries = array(); - - /** - * Attach the Factory to this class - */ - public function __construct() - { - $this->factory = Factory::getInstance(); - $this->libraryPaths[] = Core::$coreDir . DS . 'Libraries'; - $this->libraryPaths[] = Core::$appDir . DS . 'Libraries'; - } - - /** - * Library Loader - * - * Loads, instantiates and returns libraries. - * - * @param string $library Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param array $directory Optional list of directories where the library can be found. Overrides default list - * @param bool $newInstance Whether to return a new instance of the library or the same one - * @return object - * @throws LibraryException - */ - public function get($libraryName, array $parameters = null, array $directory = null, $newInstance = false) - { - if (empty($libraryName)) - { - throw new LibraryException("Could not load library. No name provided", 1); - } - - return $this->loadLibrary($libraryName, $parameters, $directory, $newInstance); - } - - /** - * Driver Library Loader - * - * Loads, instantiates and returns driver libraries. - * - * @param string $library Driver Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param array $directory Optional list of directories where the library can be found. Overrides default list - * @param bool $newInstance Whether to return a new instance of the library or the same one - * @return object - * @throws LibraryException - */ - public function getDriver($libraryName, array $parameters = null, array $directory = null, $newInstance = false) - { - if (empty($libraryName)) - { - throw new LibraryException("Could not load driver. No name provided", 1); - } - - // Load the driver class if it is not yet loaded - if ( ! class_exists('FuzeWorks\FW_Driver_Library', false)) - { - require_once(Core::$coreDir . DS . 'Libraries'.DS.'Driver.php'); - } - - // And then load and return the library - return $this->loadLibrary($libraryName, $parameters, $directory, $newInstance); - } - - /** - * Internal Library Loader - * - * Determines what type of library needs to be loaded - * - * @param string $library Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param array $directory Optional list of directories where the library can be found. Overrides default list - * @param bool $newInstance Whether to return a new instance of the library or the same one - * @return object - * @throws LibraryException - */ - protected function loadLibrary($libraryName, $parameters = null, array $directory = null, $newInstance = false) - { - // First get the directories where the library can be located - $directories = (is_null($directory) ? $this->libraryPaths : $directory); - - // Now figure out the className and subdir - $class = trim($libraryName, '/'); - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Is the library a core library, then load a core library - if (file_exists(Core::$coreDir . DS . 'Libraries'.DS.$subdir.$class.'.php')) - { - // Load base library - return $this->loadCoreLibrary($class, $subdir, $parameters, $directories, $newInstance); - } - - // Otherwise try and load an Application Library - return $this->loadAppLibrary($class, $subdir, $parameters, $directories, $newInstance); - } - - /** - * Core Library Loader - * - * Loads, instantiates and returns a core library. - * - * @param string $class Classname - * @param string $subdir Sub directory in which the final class can be found - * @param array $params Optional parameters to pass to the library class constructor - * @param array $directory Optional list of directories where the library can be found. Overrides default list - * @param bool $newInstance Whether to return a new instance of the library or the same one - * @return object - * @throws LibraryException - */ - protected function loadCoreLibrary($class, $subdir, array $parameters = null, array $directories, $newInstance = false) - { - // First check if the input is correct - if (!is_array($directories)) - { - throw new LibraryException("Could not load module. \$directory variable was not an array", 1); - } - - // Retrieve the subclass prefix - $corePrefix = '\FuzeWorks\Library\FW_'; - $appPrefix = '\Application\Library\\' . $this->factory->config->get('main')->application_prefix; - $prefix = $corePrefix; - - // Perform a check to see if the library is already loaded - if (class_exists($prefix.$class, false)) - { - // Then check if an application extension also exists - if (class_exists($appPrefix.$class, false)) - { - $prefix = $appPrefix; - } - - if (!isset($this->libraries[$prefix.$class])) - { - return $this->initLibrary($prefix.$class, $parameters); - } - - // If required to do so, return the existing instance or load a new one - if ($newInstance) - { - $this->factory->logger->log("Library '".$prefix.$class."' already loaded. Returning existing instance"); - return $this->libraries[$prefix.$class]; - } - - $this->factory->logger->log("Library '".$prefix.$class."' already loaded. Returning new instance"); - return $this->initLibrary($prefix.$class, $parameters); - } - - // Remove the core directory from the checklist - if (in_array(Core::$coreDir . DS . 'Libraries', $directories)) - { - array_shift($directories); - } - - // First check the directories for the core library (the FW_ class) - foreach ($directories as $directory) - { - $file = $directory . DS . $subdir . $class . '.php'; - - // Load if it exists - if (file_exists($file)) - { - // First base; if an app library is found with FW_, load that one. There can be no extensions - include_once($file); - if (class_exists($prefix.$class, false)) - { - return $this->initLibrary($prefix.$class, $parameters); - } - else - { - // Otherwise log a message - $this->factory->logger->logWarning("File ".$file." exists but does not declare $prefix$class"); - } - } - } - - // Second base; if no base class is found in the app folder, load it from the core folder - include_once(Core::$coreDir . DS . 'Libraries'.DS.$subdir.$class.'.php'); - - // Now let's check for extensions - $subclass = $this->factory->config->getConfig('main')->application_prefix . $class; - foreach ($directories as $directory) - { - $file = $directory . DS . $subdir . $subclass . '.php'; - - // Load if it exists - if (file_exists($file)) - { - include_once($file); - if (class_exists($appPrefix.$class, false)) - { - return $this->initLibrary($appPrefix.$class, $parameters); - } - else - { - $this->factory->logger->logWarning("File ".$file." exists but does not declare $prefix$class"); - } - } - } - - // Third and last base; just load the FW_ core class - if (class_exists('\FuzeWorks\Library\FW_'.$class, false)) - { - return $this->initLibrary('\FuzeWorks\Library\FW_'.$class, $parameters); - } - - throw new LibraryException("Could not load library. File ".'Core'.DS.'Libraries'.DS.$subdir.$class.'.php'." exists but does not declare \FuzeWorks\Library\FW_$class", 1); - } - - /** - * Application Library Loader - * - * Loads, instantiates and returns an application library. - * Could possibly extend a core library if requested. - * - * @param string $class Classname - * @param string $subdir Sub directory in which the final class can be found - * @param array $params Optional parameters to pass to the library class constructor - * @param array $directory Optional list of directories where the library can be found. Overrides default list - * @param bool $newInstance Whether to return a new instance of the library or the same one - * @return object - * @throws LibraryException - */ - protected function loadAppLibrary($class, $subdir, array $parameters = null, array $directories, $newInstance = false) - { - // First check if the input is correct - if (!is_array($directories)) - { - throw new LibraryException("Could not load library. \$directory variable was not an array", 1); - } - - // Search for the file - foreach ($directories as $directory) - { - // Skip the core directory - if ($directory === Core::$coreDir . DS . 'Libraries') - { - continue; - } - - // Determine the file - $file = $directory . DS . $subdir . $class . '.php'; - $className = '\Application\Library\\'.$class; - - // Check if the file was already loaded - if (class_exists($className, false)) - { - // Return existing instance - if (!isset($this->libraries[$className])) - { - return $this->initLibrary($className, $parameters); - } - - // If required to do so, return the existing instance or load a new one - if ($newInstance) - { - $this->factory->logger->log("Library '".$className."' already loaded. Returning existing instance"); - return $this->libraries[$prefix.$class]; - } - - $this->factory->logger->log("Library '".$className."' already loaded. Returning new instance"); - return $this->initLibrary($className, $parameters); - } - - // Otherwise load the file first - if (file_exists($file)) - { - include_once($file); - return $this->initLibrary($className, $parameters); - } - } - - // Maybe it's in a subdirectory with the same name as the class - if ($subdir === '') - { - return $this->loadLibrary($class."/".$class, $parameters, $directories, $newInstance); - } - - throw new LibraryException("Could not load library. Library was not found", 1); - } - - /** - * Library Initializer - * - * Instantiates and returns a library. - * Determines whether to use the parameters array or a config file - * - * @param string $class Classname - * @param array $params Optional parameters to pass to the library class constructor - * @return object - * @throws LibraryException - */ - protected function initLibrary($class, array $parameters = null) - { - // First check to see if the library is already loaded - if (!class_exists($class, false)) - { - throw new LibraryException("Could not initiate library. Class not found", 1); - } - - // Determine what parameters to use - if (is_null($parameters) || empty($parameters)) - { - try { - $parameters = $this->factory->config->getConfig(strtolower($class))->toArray(); - } catch (ConfigException $e) { - // No problem, just use an empty array instead - $parameters = array(); - } - } - - // Check if the adress is already reserved, if it is, we can presume that a new instance is requested. - // Otherwise this code would not be reached - if (isset($this->libraries[$class])) - { - $classObject = new $class($parameters); - $this->factory->logger->log("Loaded new Library instance of: ".$class); - return $classObject; - } - else - { - // Now load the class - $this->libraries[$class] = new $class($parameters); - $this->factory->logger->log("Loaded Library: ".$class); - return $this->libraries[$class]; - } - } + use ComponentPathsTrait; /** - * Add a path where libraries can be found - * - * @param string $directory The directory - * @return void + * Array of loaded library objects + * + * @var array Library objects */ - public function addLibraryPath($directory) - { - if (!in_array($directory, $this->libraryPaths)) - { - $this->libraryPaths[] = $directory; - } - } + protected $libraryObjects = []; /** - * Remove a path where libraries can be found - * - * @param string $directory The directory - * @return void - */ - public function removeLibraryPath($directory) - { - if (($key = array_search($directory, $this->libraryPaths)) !== false) - { - unset($this->libraryPaths[$key]); - } - } - - /** - * Get a list of all current libraryPaths - * - * @return array Array of paths where libraries can be found + * Array of libraries with their classnames, so they can be easily loaded + * + * @var array Library classes */ - public function getLibraryPaths(): array - { - return $this->libraryPaths; - } + protected $libraryClasses = []; + + /** + * FuzeWorks Factory object. For internal use. + * + * @var Factory + */ + protected $factory; + + /** + * Libraries constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + $this->factory = Factory::getInstance(); + } + + /** + * Add a library to FuzeWorks by adding an object. + * + * @param string $libraryName + * @param object $libraryObject + */ + public function addLibraryObject(string $libraryName, $libraryObject) + { + $this->libraryObjects[strtolower($libraryName)] = $libraryObject; + } + + /** + * Add a library to FuzeWorks by adding its class name. + * + * @param string $libraryName + * @param string $libraryClass + * @throws LibraryException + */ + public function addLibraryClass(string $libraryName, string $libraryClass) + { + if (!class_exists($libraryClass, false)) + throw new LibraryException("Could not add library class. '" . $libraryClass . "' could not be loaded.", 1); + + $this->libraryClasses[strtolower($libraryName)] = $libraryClass; + } + + /** + * Retrieve a library. + * + * Loads a library from one of the following sources in the following order: + * - From the loaded libraries + * - From the known libraryClasses + * - From the provided alternate library directory + * - From the earlier provided libraryPaths + * + * @param string $libraryName + * @param array $parameters + * @param array $libraryPaths + * @return object + * @throws LibraryException + */ + public function get(string $libraryName, array $parameters = [], array $libraryPaths = []) + { + // Test for empty string + if (empty($libraryName)) + { + throw new LibraryException("Could not load library. No name provided", 1); + } + + // Test if the library already exists + $libraryNameLowerCase = strtolower($libraryName); + $libraryClassname = '\Application\Library\\' . ucfirst($libraryName); + $libraryFilename = ucfirst($libraryName); + if (isset($this->libraryObjects[$libraryNameLowerCase])) + return $this->libraryObjects[$libraryNameLowerCase]; + + // Library not found. First test if the libraryClass exists + if (isset($this->libraryClasses[$libraryNameLowerCase])) + return $this->initLibrary($libraryName, $this->libraryClasses[$libraryNameLowerCase], $parameters); + + // Try and load from the alternate directory if provided + $libraryPaths = (empty($libraryPaths) ? $this->componentPaths : [3 => $libraryPaths]); + + // Try and find the library in the libraryPaths + for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) + { + if (!isset($libraryPaths[$i])) + continue; + + foreach ($libraryPaths[$i] as $path) + { + // First look if a .php file exists in the libraryPath + $classFile = $path . DS . $libraryFilename . '.php'; + if (file_exists($classFile)) + { + require_once($classFile); + return $this->initLibrary($libraryName, $libraryClassname); + } + + $classFile = $path . DS . $libraryFilename . DS . $libraryFilename . '.php'; + if (file_exists($classFile)) + { + require_once($classFile); + return $this->initLibrary($libraryName, $libraryClassname); + } + } + } + + // Throw exception if not found + throw new LibraryException("Could not load library. Library not found.", 1); + } + + /** + * Library Initializer + * + * Instantiates and returns a library. + * Determines whether to use the parameters array or a config file + * + * @param string $libraryName + * @param string $libraryClass + * @param array $parameters + * @throws LibraryException + * @return object + */ + protected function initLibrary(string $libraryName, string $libraryClass, array $parameters = []) + { + // First check to see if the library is already loaded + if (!class_exists($libraryClass, true)) + throw new LibraryException("Could not initiate library. Class not found", 1); + + // Determine what parameters to use + if (empty($parameters)) + { + try { + $parameters = $this->factory->config->getConfig(strtolower($libraryName))->toArray(); + } catch (ConfigException $e) { + // No problem, just use an empty array instead + $parameters = array(); + } + } + + // Load the class object + /** @var iLibrary $classObject */ + $classObject = new $libraryClass($parameters); + + // If not instance of iLibrary, refuse the library + if (!$classObject instanceof iLibrary) + throw new LibraryException("Could not initiate library. Library is not instance of iLibrary."); + + // Add the library files to the autoloader + try { + $headerReflection = new ReflectionClass(get_class($classObject)); + $filePath = dirname($headerReflection->getFileName()) . (!is_null($classObject->getSourceDirectory()) ? DS . $classObject->getSourceDirectory() : '' ); + $prefix = $classObject->getClassesPrefix(); + if (!is_null($filePath) && !is_null($prefix)) + Core::addAutoloadMap($prefix, $filePath); + } catch (ReflectionException $e) { + throw new LibraryException("Could not initiate library. ReflectionClass threw exception."); + } catch (CoreException $e) { + throw new LibraryException("Could not initiate library. Failed to add to autoloader."); + } + + // @todo Check if the address is already reserved, if it is, we can presume that a new instance is requested. + // Otherwise this code would not be reached + + // Now load the class + $this->libraryObjects[strtolower($libraryName)] = $classObject; + $this->factory->logger->log("Loaded Library: ".$libraryName); + return $this->libraryObjects[strtolower($libraryName)]; + } } \ No newline at end of file diff --git a/src/FuzeWorks/Logger.php b/src/FuzeWorks/Logger.php index 20a447a..9b03349 100644 --- a/src/FuzeWorks/Logger.php +++ b/src/FuzeWorks/Logger.php @@ -1,40 +1,44 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.1 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\Exception\ConfigException; +use FuzeWorks\Exception\EventException; use FuzeWorks\Exception\Exception; -use FuzeWorks\Exception\LayoutException; /** * Logger Class. @@ -43,8 +47,8 @@ use FuzeWorks\Exception\LayoutException; * All fatal errors get catched by this class and get displayed if configured to do so. * Also provides utilities to benchmark the application. * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Logger { @@ -53,7 +57,7 @@ class Logger { * * @var array */ - public static $Logs = array(); + public static $logs = []; /** * whether to output the log after FuzeWorks has run. @@ -63,18 +67,32 @@ class Logger { private static $print_to_screen = false; /** - * whether to output the log to a file after FuzeWorks has run. + * Whether the Logger has been enabled or not * * @var bool */ - private static $log_to_file = false; + private static $isEnabled = false; + + /** + * whether to output the log of the last entire request to a file after FuzeWorks has run. + * + * @var bool + */ + private static $log_last_request = false; + + /** + * Whether to output the log of all errors to a file after FuzeWorks has run + * + * @var bool + */ + private static $log_errors_to_file = false; /** * The template to use when parsing the debug log * * @var string Template name */ - private static $logger_template = 'logger_default'; + private static $logger_template = 'logger_cli'; /** * whether to output the log after FuzeWorks has run, regardless of conditions. @@ -88,42 +106,102 @@ class Logger { * * @var array */ - public static $markPoints = array(); - - /** - * Whether to use the Tracy debugger instead of FuzeWorks Logger - * - * @var bool - */ - public static $useTracy = false; + public static $markPoints = []; /** * Initiates the Logger. * * Registers the error and exception handler, when required to do so by configuration + * @throws ConfigException */ public function __construct() { + // Get the config file + $cfg_error = Factory::getInstance()->config->getConfig('error'); + // Register the error handler, Untestable // @codeCoverageIgnoreStart - if (Factory::getInstance()->config->get('error')->error_reporting == true && self::$useTracy === false) { - set_error_handler(array('\FuzeWorks\Logger', 'errorHandler'), E_ALL); - set_Exception_handler(array('\FuzeWorks\Logger', 'exceptionHandler')); + if ($cfg_error->get('fuzeworks_error_reporting') == true) + { + self::enableHandlers(); } // @codeCoverageIgnoreEnd - error_reporting(false); + // Set PHP error reporting + if ($cfg_error->get('php_error_reporting')) + error_reporting(true); + else + error_reporting(false); - self::$debug = (ENVIRONMENT === 'DEVELOPMENT'); - self::$log_to_file = Factory::getInstance()->config->get('error')->log_to_file; - self::$logger_template = Factory::getInstance()->config->get('error')->logger_template; + // Set the environment variables + self::$log_last_request = $cfg_error->get('log_last_request_to_file'); + self::$log_errors_to_file = $cfg_error->get('log_errors_to_file'); self::newLevel('Logger Initiated'); + } - if (self::$useTracy) - { - LoggerTracyBridge::register(); - GitTracyBridge::register(); - } + /** + * Enable error to screen logging. + */ + public static function enable() + { + self::$isEnabled = true; + } + + /** + * Disable error to screen logging. + */ + public static function disable() + { + self::$isEnabled = false; + } + + /** + * Returns whether screen logging is enabled. + */ + public static function isEnabled(): bool + { + return self::$isEnabled; + } + + /** + * Enable outputting the debugger after the request has been processed + */ + public static function enableScreenLog() + { + if (!Core::isProduction()) + self::$print_to_screen = true; + } + + /** + * Disable outputting the debugger after the request has been processed + */ + public static function disableScreenLog() + { + self::$print_to_screen = false; + } + + /** + * Enable FuzeWorks error handling + * + * Registers errorHandler() and exceptionHandler() as the respective handlers for PHP + * @codeCoverageIgnore + */ + public static function enableHandlers() + { + Core::addErrorHandler(['\FuzeWorks\Logger', 'errorHandler'], Priority::NORMAL); + Core::addExceptionHandler(['\FuzeWorks\Logger', 'exceptionHandler'], Priority::NORMAL); + } + + /** + * Disable FuzeWorks error handling + * + * Unregisters errorHandler() and exceptionHandler() as the respective handlers for PHP + * @codeCoverageIgnore + */ + public static function disableHandlers() + { + Core::removeErrorHandler(['\FuzeWorks\Logger', 'errorHandler'], Priority::NORMAL); + Core::removeExceptionHandler(['\FuzeWorks\Logger', 'exceptionHandler'], Priority::NORMAL); } /** @@ -132,6 +210,7 @@ class Logger { * @codeCoverageIgnore * * Logs data to screen when requested to do so + * @throws EventException */ public static function shutdown() { @@ -143,10 +222,11 @@ class Logger { self::logToScreen(); } - if (self::$log_to_file == true) - { - self::logToFile(); - } + if (self::$log_last_request == true) + self::logLastRequest(); + + if (self::$log_errors_to_file == true) + self::logErrorsToFile(); } /** @@ -158,27 +238,20 @@ class Logger { */ public static function shutdownError() { - // Load last error if thrown - $errfile = 'Unknown file'; - $errstr = 'shutdown'; - $errno = E_CORE_ERROR; - $errline = 0; - $error = error_get_last(); if ($error !== null) { - $errno = $error['type']; - $errfile = $error['file']; - $errline = $error['line']; - $errstr = $error['message']; - - // Log it! - $thisType = self::getType($errno); - Factory::getInstance()->output->set_output(''); - self::errorHandler($errno, $errstr, $errfile, $errline); + // Log it! + $thisType = self::getType($error['type']); + $LOG = array('type' => (!is_null($thisType) ? $thisType : 'ERROR'), + 'message' => $error['message'], + 'logFile' => $error['file'], + 'logLine' => $error['line'], + 'runtime' => round(self::getRelativeTime(), 4),); + self::$logs[] = $LOG; if ($thisType == 'ERROR') { - self::http_error('500'); + self::haltExecution($LOG); } } } @@ -192,7 +265,7 @@ class Logger { * @param int Line. The line on which the error occured. * @param array context. Some of the error's relevant variables */ - public static function errorHandler($type = E_USER_NOTICE, $error = 'Undefined Error', $errFile = null, $errLine = null, $context = null) + public static function errorHandler($type = E_USER_NOTICE, $error = 'Undefined Error', $errFile = null, $errLine = null) { // Check type $thisType = self::getType($type); @@ -200,9 +273,8 @@ class Logger { 'message' => (!is_null($error) ? $error : ''), 'logFile' => (!is_null($errFile) ? $errFile : ''), 'logLine' => (!is_null($errLine) ? $errLine : ''), - 'context' => (!is_null($context) ? $context : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -211,19 +283,21 @@ class Logger { * Please note that most of the user-defined exceptions will be caught in the router, and handled with the error-controller. * * @param Exception $exception The occured exception. + * @param bool $haltExecution. Defaults to true */ - public static function exceptionHandler($exception) + public static function exceptionHandler($exception, bool $haltExecution = true) { - $message = $exception->getMessage(); - $code = $exception->getCode(); - $file = $exception->getFile(); - $line = $exception->getLine(); - $context = $exception->getTraceAsString(); + $LOG = array('type' => 'EXCEPTION', + 'message' => $exception->getMessage(), + 'logFile' => $exception->getFile(), + 'logLine' => $exception->getLine(), + 'context' => $exception->getTraceAsString(), + 'runtime' => round(self::getRelativeTime(), 4),); + self::$logs[] = $LOG; - self::logError('Exception thrown: ' . $message . ' | ' . $code, null, $file, $line); - // And return a 500 because this error was fatal - self::http_error('500'); + if ($haltExecution) + self::haltExecution($LOG); } /** @@ -241,16 +315,17 @@ class Logger { /** * Output the entire log to the screen. Used for debugging problems with your code. * @codeCoverageIgnore + * @throws EventException */ public static function logToScreen() { // Send a screenLogEvent, allows for new screen log designs $event = Events::fireEvent('screenLogEvent'); if ($event->isCancelled()) { - return false; + return; } - $logs = self::$Logs; + $logs = self::$logs; require(dirname(__DIR__) . DS . 'Layout' . DS . 'layout.' . self::$logger_template . '.php'); } @@ -258,23 +333,41 @@ class Logger { * Output the entire log to a file. Used for debugging problems with your code. * @codeCoverageIgnore */ - public static function logToFile() + public static function logLastRequest() { ob_start(function () {}); - $logs = self::$Logs; - require(dirname(__DIR__) . DS . 'Layout' . DS . 'layout.logger_cli.php'); + $logs = self::$logs; + require(dirname(__DIR__) . DS . 'Layout' . DS . 'layout.logger_file.php'); $contents = ob_get_clean(); - $file = Core::$logDir . DS . 'Logs' . DS . 'log_latest.php'; - if (is_writable($file)) + $file = Core::$logDir . DS . 'fwlog_request.log'; + if (is_writable(dirname($file))) + file_put_contents($file, $contents); + } + + /** + * Output all errors to a file. Used for tracking all errors in FuzeWorks and associated code + * @codeCoverageIgnore + */ + public static function logErrorsToFile() + { + ob_start(function() {}); + $logs = []; + foreach (self::$logs as $log) { - file_put_contents($file, ' '', 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -299,10 +392,10 @@ class Logger { * * @param string $msg The information to be logged * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ - public static function log($msg, $mod = null, $file = 0, $line = 0) + public static function log($msg, $mod = null, $file = null, $line = null) { self::logInfo($msg, $mod, $file, $line); } @@ -312,10 +405,10 @@ class Logger { * * @param string $msg The information to be logged * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ - public static function logInfo($msg, $mod = null, $file = 0, $line = 0) + public static function logInfo($msg, $mod = null, $file = null, $line = null) { $LOG = array('type' => 'INFO', 'message' => (!is_null($msg) ? $msg : ''), @@ -324,7 +417,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -332,10 +425,10 @@ class Logger { * * @param string $msg The information to be logged * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ - public static function logDebug($msg, $mod = null, $file = 0, $line = 0) + public static function logDebug($msg, $mod = null, $file = null, $line = null) { $LOG = array('type' => 'DEBUG', 'message' => (!is_null($msg) ? $msg : ''), @@ -344,7 +437,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -352,10 +445,10 @@ class Logger { * * @param string $msg The information to be logged * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ - public static function logError($msg, $mod = null, $file = 0, $line = 0) + public static function logError($msg, $mod = null, $file = null, $line = null) { $LOG = array('type' => 'ERROR', 'message' => (!is_null($msg) ? $msg : ''), @@ -364,7 +457,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -372,10 +465,10 @@ class Logger { * * @param string $msg The information to be logged * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ - public static function logWarning($msg, $mod = null, $file = 0, $line = 0) + public static function logWarning($msg, $mod = null, $file = null, $line = null) { $LOG = array('type' => 'WARNING', 'message' => (!is_null($msg) ? $msg : ''), @@ -384,7 +477,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -392,8 +485,8 @@ class Logger { * * @param string $msg The name of the new level * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ public static function newLevel($msg, $mod = null, $file = null, $line = null) { @@ -404,7 +497,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /** @@ -412,8 +505,8 @@ class Logger { * * @param string $msg The name of the new level * @param string $mod The name of the module - * @param string $file The file where the log occured - * @param int $line The line where the log occured + * @param string $file The file where the log occurred + * @param int $line The line where the log occurred */ public static function stopLevel($msg = null, $mod = null, $file = null, $line = null) { @@ -424,7 +517,7 @@ class Logger { 'context' => (!is_null($mod) ? $mod : ''), 'runtime' => round(self::getRelativeTime(), 4),); - self::$Logs[] = $LOG; + self::$logs[] = $LOG; } /* =========================================OTHER METHODS============================================================== */ @@ -433,7 +526,7 @@ class Logger { * Returns a string representation of an error * Turns a PHP error-constant (or integer) into a string representation. * - * @param int $type PHP-constant errortype (e.g. E_NOTICE). + * @param int $type PHP-constant errorType (e.g. E_NOTICE). * * @return string String representation */ @@ -476,102 +569,25 @@ class Logger { } /** - * Calls an HTTP error, sends it as a header, and loads a template if required to do so. + * Halts the Execution of FuzeWorks * - * @param int $errno HTTP error code - * @param string $message Message describing the reason for the HTTP error - * @param bool $layout true to layout error on website + * Will die a message if not intercepted by haltExecutionEvent. + * @param array $log + * @codeCoverageIgnore */ - public static function http_error($errno = 500, $message = '', $layout = true): bool + public static function haltExecution(array $log) { - $http_codes = array( - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates', - 509 => 'Bandwidth Limit Exceeded', - 510 => 'Not Extended', - 511 => 'Network Authentication Required', - ); - - self::logError('HTTP-error ' . $errno . ' called'); - self::log('Sending header HTTP/1.1 ' . $errno . ' ' . $http_codes[$errno]); - header('HTTP/1.1 ' . $errno . ' ' . $http_codes[$errno]); - - // Set the status code - Core::$http_status_code = $errno; - - // Do we want the error-layout with it? - if ($layout == false) { - return false; - } - - // Load the layout - $layout = 'errors/' . $errno; - self::log('Loading layout ' . $layout); - - // Try and load the layout, if impossible, load HTTP code instead. - $factory = Factory::getInstance(); + self::logError("Halting execution..."); try { - $factory->layout->reset(); - $factory->layout->assign('httpErrorMessage', $message); - $factory->layout->display($layout); - } catch (LayoutException $exception) { - // No error page could be found, just echo the result - $factory->output->set_output("

$errno

" . $http_codes[$errno] . '

' . $message . '

'); + $event = Events::fireEvent("haltExecutionEvent", $log); + } catch (EventException $e) { + self::logError("Can't fire haltExecutionEvent: '".$e->getMessage()."'"); + die(PHP_EOL . "FuzeWorks execution halted. See error log for more information"); } - - return true; - } + if ($event->isCancelled() == true) + return; - /** - * Enable error to screen logging. - */ - public static function enable() - { - self::$print_to_screen = true; - } - - /** - * Disable error to screen logging. - */ - public static function disable() - { - self::$print_to_screen = false; - } - - /** - * Returns whether screen logging is enabled. - */ - public static function isEnabled(): bool - { - return self::$print_to_screen; + die(PHP_EOL . "FuzeWorks execution halted. See error log for more information"); } /** @@ -579,9 +595,9 @@ class Logger { * * Used for debugging timings in FuzeWorks * - * @return int Time passed since FuzeWorks init + * @return float Time passed since FuzeWorks init */ - private static function getRelativeTime(): int + private static function getRelativeTime(): float { $startTime = STARTTIME; $time = microtime(true) - $startTime; diff --git a/src/FuzeWorks/LoggerTracyBridge.php b/src/FuzeWorks/LoggerTracyBridge.php deleted file mode 100644 index cfd57cf..0000000 --- a/src/FuzeWorks/LoggerTracyBridge.php +++ /dev/null @@ -1,108 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks; -use Tracy\IBarPanel; -use Tracy\Debugger; - -/** - * LoggerTracyBridge Class. - * - * This class provides a bridge between FuzeWorks\Logger and Tracy Debugging tool. - * - * This class registers in Tracy, and creates a Bar object which contains the log. - * Afterwards it blocks a screen log so that the content is not shown on the screen as well. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LoggerTracyBridge implements IBarPanel { - - /** - * Register the bar and register the event which will block the screen log - */ - public static function register() - { - $class = new self(); - Events::addListener(array($class, 'screenLogEventListener'), 'screenLogEvent', EventPriority::NORMAL); - $bar = Debugger::getBar(); - $bar->addPanel($class); - } - - /** - * Listener that blocks the screen log - * - * @param Event - * @return Event - */ - public function screenLogEventListener($event): Event - { - $event->setCancelled(true); - return $event; - } - - public function getTab(): string - { - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracyloggertab.php'; - return ob_get_clean(); - } - - public function getPanel(): string - { - // If an error is thrown, log it - $errfile = 'Unknown file'; - $errstr = 'shutdown'; - $errno = E_CORE_ERROR; - $errline = 0; - - $error = error_get_last(); - if ($error !== null) { - $errno = $error['type']; - $errfile = $error['file']; - $errline = $error['line']; - $errstr = $error['message']; - - // Log it! - Logger::errorHandler($errno, $errstr, $errfile, $errline); - } - - // Reverse the logs - $logs = array_reverse(Logger::$Logs, true); - - // Parse the panel - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracyloggerpanel.php'; - return ob_get_clean(); - } - -} \ No newline at end of file diff --git a/src/FuzeWorks/ModelAbstract.php b/src/FuzeWorks/ModelAbstract.php deleted file mode 100644 index 5bd43fb..0000000 --- a/src/FuzeWorks/ModelAbstract.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Abstract class ModelAbstract. - * - * Extends all models to use the Factory. - * Factory should in the future be replaced with a DI container - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -abstract class ModelAbstract extends Factory -{ -} \ No newline at end of file diff --git a/src/FuzeWorks/Models.php b/src/FuzeWorks/Models.php deleted file mode 100644 index 87fb938..0000000 --- a/src/FuzeWorks/Models.php +++ /dev/null @@ -1,200 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\ModelException; - -/** - * Models Class. - * - * Simple loader class for MVC Models. - * Typically loads models from Application/Models unless otherwise specified. - * - * If a model is not found, it will load a DatabaseModel type which will - * analyze the database and can directly be used. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class Models -{ - - /** - * Paths where Models can be found. - * - * Models will only be loaded if either a directory is supplied or it is in one of the modelPaths - * - * @var array Array of paths where models can be found - */ - protected $modelPaths = array(); - - public function __construct() - { - $this->modelPaths[] = Core::$appDir . DS . 'Models'; - } - - /** - * Get a model. - * - * Supply the name and the model will be loaded from the supplied directory, - * or from one of the modelPaths (which you can add). - * - * @param string $modelName Name of the model - * @param string|null $directory Directory to load the model from, will ignore $modelPaths - * @return ModelAbstract|bool The Model object - */ - public function get($modelName, $directory = null) - { - if (empty($modelName)) - { - throw new ModelException("Could not load model. No name provided", 1); - } - - // First get the directories where the model can be located - $directories = (is_null($directory) ? $this->modelPaths : array($directory)); - - // Fire a model load event - $event = Events::fireEvent('modelLoadEvent', $modelName, $directories); - $directories = $event->directories; - $modelName = $event->modelName; - - // If the event is cancelled, stop loading - if ($event->isCancelled()) - { - return false; - } - - // And attempt to load the model - return $this->loadModel($modelName, $directories); - } - - /** - * Load and return a model. - * - * Supply the name and the model will be loaded from one of the supplied directories - * - * @param string $modelName Name of the model - * @param array $directories Directories to try and load the model from - * @return ModelAbstract The Model object - */ - protected function loadModel($modelName, $directories): ModelAbstract - { - if (empty($directories)) - { - throw new ModelException("Could not load model. No directories provided", 1); - } - - // Now figure out the className and subdir - $class = trim($modelName, '/'); - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Search for the model file - foreach ($directories as $directory) { - - // Determine the file - $file = $directory . DS . $subdir . "model." . strtolower($class) . '.php'; - $className = '\Application\Model\\'.$class; - - // If the class already exists, return a new instance directly - if (class_exists($className, false)) - { - return new $className(); - } - - // If it doesn't, try and load the file - if (file_exists($file)) - { - include_once($file); - return new $className(); - } - } - - // Maybe it's in a subdirectory with the same name as the class - if ($subdir === '') - { - return $this->loadModel($class."/".$class, $directories); - } - - throw new ModelException("Could not load model. Model was not found", 1); - } - - /** - * Add a path where models can be found - * - * @param string $directory The directory - * @return void - */ - public function addModelPath($directory) - { - if (!in_array($directory, $this->ModelPaths)) - { - $this->modelPaths[] = $directory; - } - } - - /** - * Remove a path where models can be found - * - * @param string $directory The directory - * @return void - */ - public function removeModelPath($directory) - { - if (($key = array_search($directory, $this->modelPaths)) !== false) - { - unset($this->modelPaths[$key]); - } - } - - /** - * Get a list of all current ModelPaths - * - * @return array Array of paths where models can be found - */ - public function getModelPaths(): array - { - return $this->modelPaths; - } -} \ No newline at end of file diff --git a/src/FuzeWorks/Output.php b/src/FuzeWorks/Output.php deleted file mode 100644 index ded2bd3..0000000 --- a/src/FuzeWorks/Output.php +++ /dev/null @@ -1,791 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Output Class - * - * Responsible for sending final output to the browser. - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Output { - - /** - * Final output string - * - * @var string - */ - public $final_output; - - /** - * Cache expiration time - * - * @var int - */ - public $cache_expiration = 0; - - /** - * List of server headers - * - * @var array - */ - public $headers = array(); - - /** - * List of mime types - * - * @var array - */ - public $mimes = array(); - - /** - * Mime-type for the current page - * - * @var string - */ - protected $mime_type = 'text/html'; - - /** - * Enable Profiler flag - * - * @var bool - */ - public $enable_profiler = FALSE; - - /** - * php.ini zlib.output_compression flag - * - * @var bool - */ - protected $_zlib_oc = FALSE; - - /** - * CI output compression flag - * - * @var bool - */ - protected $_compress_output = FALSE; - - /** - * List of profiler sections - * - * @var array - */ - protected $_profiler_sections = array(); - - /** - * Parse markers flag - * - * Whether or not to parse variables like {elapsed_time} and {memory_usage}. - * - * @var bool - */ - public $parse_exec_vars = TRUE; - - /** - * Factory Object - * @var Factory - */ - protected $factory; - protected $config; - protected $uri; - protected $router; - - /** - * Class constructor - * - * Determines whether zLib output compression will be used. - * - * @return void - */ - public function __construct() - { - $this->factory = Factory::getInstance(); - $this->config = $this->factory->config; - $this->uri = $this->factory->uri; - - $this->_zlib_oc = (bool) ini_get('zlib.output_compression'); - $this->_compress_output = ( - $this->_zlib_oc === FALSE - && $this->config->main->compress_output === TRUE - && extension_loaded('zlib') - ); - - // Get mime types for later - $this->mimes = $this->config->mimes->toArray(); - } - - // -------------------------------------------------------------------- - - /** - * Get Output - * - * Returns the current output string. - * - * @return string - */ - public function get_output(): string - { - return $this->final_output; - } - - // -------------------------------------------------------------------- - - /** - * Set Output - * - * Sets the output string. - * - * @param string $output Output data - * @return self - */ - public function set_output($output): self - { - $this->final_output = $output; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Append Output - * - * Appends data onto the output string. - * - * @param string $output Data to append - * @return self - */ - public function append_output($output): self - { - $this->final_output .= $output; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Header - * - * Lets you set a server header which will be sent with the final output. - * - * Note: If a file is cached, headers will not be sent. - * @todo We need to figure out how to permit headers to be cached. - * - * @param string $header Header - * @param bool $replace Whether to replace the old header value, if already set - * @return self - */ - public function set_header($header, $replace = TRUE): self - { - // If zlib.output_compression is enabled it will compress the output, - // but it will not modify the content-length header to compensate for - // the reduction, causing the browser to hang waiting for more data. - // We'll just skip content-length in those cases. - if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0) - { - return $this; - } - - $this->headers[] = array($header, $replace); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Content-Type Header - * - * @param string $mime_type Extension of the file we're outputting - * @param string $charset Character set (default: NULL) - * @return self - */ - public function set_content_type($mime_type, $charset = NULL): self - { - if (strpos($mime_type, '/') === FALSE) - { - $extension = ltrim($mime_type, '.'); - - // Is this extension supported? - if (isset($this->mimes[$extension])) - { - $mime_type =& $this->mimes[$extension]; - - if (is_array($mime_type)) - { - $mime_type = current($mime_type); - } - } - } - - $this->mime_type = $mime_type; - - if (empty($charset)) - { - $charset = Config::get('main')->charset; - } - - $header = 'Content-Type: '.$mime_type - .(empty($charset) ? '' : '; charset='.$charset); - - $this->headers[] = array($header, TRUE); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Current Content-Type Header - * - * @return string 'text/html', if not already set - */ - public function get_content_type(): string - { - for ($i = 0, $c = count($this->headers); $i < $c; $i++) - { - if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1) - { - return $content_type; - } - } - - return 'text/html'; - } - - // -------------------------------------------------------------------- - - /** - * Get Header - * - * @param string $header_name - * @return string|null - */ - public function get_header($header) - { - // Combine headers already sent with our batched headers - $headers = array_merge( - // We only need [x][0] from our multi-dimensional array - array_map('array_shift', $this->headers), - headers_list() - ); - - if (empty($headers) OR empty($header)) - { - return NULL; - } - - for ($i = 0, $c = count($headers); $i < $c; $i++) - { - if (strncasecmp($header, $headers[$i], $l = strlen($header)) === 0) - { - return trim(substr($headers[$i], $l+1)); - } - } - - return NULL; - } - - // -------------------------------------------------------------------- - - /** - * Set HTTP Status Header - * - * As of version 1.7.2, this is an alias for common function - * set_status_header(). - * - * @param int $code Status code (default: 200) - * @param string $text Optional message - * @return self - */ - public function set_status_header($code = 200, $text = ''): self - { - Core::setStatusHeader($code, $text); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Enable/disable Profiler - * - * @param bool $val TRUE to enable or FALSE to disable - * @return self - */ - public function enable_profiler($val = TRUE): self - { - $this->enable_profiler = is_bool($val) ? $val : TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Profiler Sections - * - * Allows override of default/config settings for - * Profiler section display. - * - * @param array $sections Profiler sections - * @return self - */ - public function set_profiler_sections($sections): self - { - if (isset($sections['query_toggle_count'])) - { - $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count']; - unset($sections['query_toggle_count']); - } - - foreach ($sections as $section => $enable) - { - $this->_profiler_sections[$section] = ($enable !== FALSE); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Cache - * - * @param int $time Cache expiration time in minutes - * @return self - */ - public function cache($time): self - { - $this->cache_expiration = is_numeric($time) ? $time : 0; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Display Output - * - * Processes and sends finalized output data to the browser along - * with any server headers and profile data. It also stops benchmark - * timers so the page rendering speed and memory usage can be shown. - * - * Note: All "layout" data is automatically put into $this->final_output - * by controller class. - * - * @uses Output::$final_output - * @param string $output Output data override - * @return void - */ - public function _display($output = '') - { - $router = $this->factory->router; - // Grab the super object if we can. - if ($router->getCallable() === null) - { - $use_cache = true; - } - else - { - $use_cache = false; - } - - // -------------------------------------------------------------------- - - // Set the output data - if ($output === '') - { - $output =& $this->final_output; - } - - // -------------------------------------------------------------------- - - // Do we need to write a cache file? Only if the controller does not have its - // own _output() method and we are not dealing with a cache file, which we - // can determine by the existence of the $CI object above - if ($this->cache_expiration > 0 && $use_cache === false) - { - $this->_write_cache($output); - } - - // -------------------------------------------------------------------- - - if ($this->parse_exec_vars === TRUE) - { - $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB'; - $output = str_replace(array('{memory_usage}'), array($memory), $output); - } - - // -------------------------------------------------------------------- - - // Is compression requested? - if ($use_cache === false // This means that we're not serving a cache file, if we were, it would already be compressed - && $this->_compress_output === TRUE - && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) - { - ob_start('ob_gzhandler'); - } - - // -------------------------------------------------------------------- - - // Are there any server headers to send? - if (count($this->headers) > 0) - { - foreach ($this->headers as $header) - { - @header($header[0], $header[1]); - } - } - - // -------------------------------------------------------------------- - - if ( $use_cache === true) - { - if ($this->_compress_output === TRUE) - { - if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) - { - header('Content-Encoding: gzip'); - header('Content-Length: '.strlen($output)); - } - else - { - // User agent doesn't support gzip compression, - // so we'll have to decompress our cache - $output = gzinflate(substr($output, 10, -8)); - } - } - - echo $output; - Logger::log('Final output sent to browser'); - return; - } - - // -------------------------------------------------------------------- - - // Do we need to generate profile data? - // If so, load the Profile class and run it. - if ($this->enable_profiler === TRUE) - { - Logger::logWarning("Profiler not yet implemented"); - return; - - $CI->load->library('profiler'); - if ( ! empty($this->_profiler_sections)) - { - $CI->profiler->set_sections($this->_profiler_sections); - } - - // If the output data contains closing and tags - // we will remove them and add them back after we insert the profile data - $output = preg_replace('|.*?|is', '', $output, -1, $count).$CI->profiler->run(); - if ($count > 0) - { - $output .= ''; - } - } - - echo $output; - - Logger::log('Output sent to browser'); - } - - // -------------------------------------------------------------------- - - /** - * Write Cache - * - * @param string $output Output data to cache - * @return void - */ - public function _write_cache($output) - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - // First try and see if the directory exists - if ( ! is_dir($cache_path)) - { - // Then try and create the directory - if (!mkdir($cache_path, 0777, false)) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Cannot create directory'); - return; - } - } - - if (! Core::isReallyWritable($cache_path)) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Directory not writeable'); - return; - } - - $uri = $this->config->main->base_url - .$this->config->main->index_page - .$this->uri->uri_string(); - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - - $cache_path .= md5($uri); - - if ( ! $fp = @fopen($cache_path, 'w+b')) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Directory not writeable'); - return; - } - - if (flock($fp, LOCK_EX)) - { - // If output compression is enabled, compress the cache - // itself, so that we don't have to do that each time - // we're serving it - if ($this->_compress_output === TRUE) - { - $output = gzencode($output); - - if ($this->get_header('content-type') === NULL) - { - $this->set_content_type($this->mime_type); - } - } - - $expire = time() + ($this->cache_expiration * 60); - - // Put together our serialized info. - $cache_info = serialize(array( - 'expire' => $expire, - 'headers' => $this->headers - )); - - $output = $cache_info.'ENDCI--->'.$output; - - for ($written = 0, $length = strlen($output); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($output, $written))) === FALSE) - { - break; - } - } - - flock($fp, LOCK_UN); - } - else - { - Logger::logError('Unable to secure a file lock for file at: '.$cache_path); - return; - } - - fclose($fp); - - if (is_int($result)) - { - chmod($cache_path, 0640); - Logger::logDebug('Cache file written: '.$cache_path); - - // Send HTTP cache-control headers to browser to match file cache settings. - $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); - } - else - { - @unlink($cache_path); - Logger::logError('Unable to write the complete cache content at: '.$cache_path); - } - } - - // -------------------------------------------------------------------- - - /** - * Update/serve cached output - * - * @uses Config - * @uses URI - * - * @return bool TRUE on success or FALSE on failure - */ - public function _display_cache(): bool - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - // Build the file path. The file name is an MD5 hash of the full URI - $main = $this->config->main; - $uri = $main->base_url.$main->index_page.$this->uri->uri_string; - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - - $filepath = $cache_path.md5($uri); - - if ( ! file_exists($filepath) OR ! $fp = @fopen($filepath, 'rb')) - { - Logger::logDebug("No cache file for $uri found"); - return FALSE; - } - - flock($fp, LOCK_SH); - - $cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : ''; - - flock($fp, LOCK_UN); - fclose($fp); - - // Look for embedded serialized file info. - if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match)) - { - return FALSE; - } - - $cache_info = unserialize($match[1]); - $expire = $cache_info['expire']; - - $last_modified = filemtime($filepath); - - // Has the file expired? - if ($_SERVER['REQUEST_TIME'] >= $expire && Core::isReallyWritable($cache_path)) - { - // If so we'll delete it. - @unlink($filepath); - Logger::logDebug('Cache file has expired. File deleted.'); - return FALSE; - } - else - { - // Or else send the HTTP cache control headers. - $this->set_cache_header($last_modified, $expire); - } - - // Add headers from cache file. - foreach ($cache_info['headers'] as $header) - { - $this->set_header($header[0], $header[1]); - } - - // Display the cache - $this->_display(substr($cache, strlen($match[0]))); - Logger::logDebug('Cache file is current. Sending it to browser.'); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Delete cache - * - * @param string $uri URI string - * @return bool - */ - public function delete_cache($uri = ''): bool - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - if ( ! is_dir($cache_path)) - { - Logger::logError('Unable to find cache path: '.$cache_path); - return FALSE; - } - - if (empty($uri)) - { - $uri = $this->uri->uri_string(); - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - } - - $cache_path .= md5($this->config->mainbase_url.$this->config->main->index_page.ltrim($uri, '/')); - - if ( ! @unlink($cache_path)) - { - Logger::logError('Unable to delete cache file for '.$uri); - return FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Header - * - * Set the HTTP headers to match the server-side file cache settings - * in order to reduce bandwidth. - * - * @param int $last_modified Timestamp of when the page was last modified - * @param int $expiration Timestamp of when should the requested page expire from cache - * @return void - */ - public function set_cache_header($last_modified, $expiration) - { - $max_age = $expiration - $_SERVER['REQUEST_TIME']; - - if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) - { - $this->set_status_header(304); - exit; - } - else - { - header('Pragma: public'); - header('Cache-Control: max-age='.$max_age.', public'); - header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); - header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); - } - } - -} diff --git a/src/FuzeWorks/PluginInterface.php b/src/FuzeWorks/PluginInterface.php deleted file mode 100644 index b04b80d..0000000 --- a/src/FuzeWorks/PluginInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.4 - * - * @version Version 1.1.4 - */ - -namespace FuzeWorks; - - -interface PluginInterface -{ - public function init(); -} \ No newline at end of file diff --git a/src/FuzeWorks/Plugins.php b/src/FuzeWorks/Plugins.php index 6790823..5799d54 100644 --- a/src/FuzeWorks/Plugins.php +++ b/src/FuzeWorks/Plugins.php @@ -1,37 +1,47 @@ . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + * @license https://opensource.org/licenses/MIT MIT License * * @link http://techfuze.net/fuzeworks * @since Version 1.1.4 * - * @version Version 1.1.4 + * @version Version 1.2.0 */ namespace FuzeWorks; +use FuzeWorks\ConfigORM\ConfigORM; +use FuzeWorks\Event\PluginGetEvent; +use FuzeWorks\Exception\CoreException; +use FuzeWorks\Exception\FactoryException; use FuzeWorks\Exception\PluginException; +use ReflectionClass; +use ReflectionException; /** * Plugins Class. @@ -44,23 +54,17 @@ use FuzeWorks\Exception\PluginException; * * To create the plugin, create a directory (with the name of the plugin) in the Plugin folder, inside the Application environment. Next you should add a header.php file in this directory. * This file needs to be in the FuzeWorks\Plugins namespace, and be named *PluginName*Header. For example: TestHeader. - * It is recommended that this header file implements the FuzeWorks\PluginInterface. All headers must have the init() method. This method will run upon starting FuzeWorks. + * It is required that this header file implements the FuzeWorks\iPluginHeader. All headers must have the init() method. This method will run upon starting FuzeWorks. * * Next a plugin class should be created. This file should be named the same as the folder, and be in the Application\Plugin namespace. An alternative classname can be set in the header, by creating a public $className variable. This plugin can be called using the $plugins->get() method. * - * @todo Implement events - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) + * @todo Add methods to enable and disable plugins + * @author TechFuze + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) */ class Plugins { - - /** - * Array of all the paths where plugins can be found - * - * @var array Plugin paths - */ - protected $pluginPaths = array(); + use ComponentPathsTrait; /** * Array of loaded Plugins, so that they won't be reloaded @@ -86,203 +90,184 @@ class Plugins protected $cfg; /** - * Called upon creation of the plugins class. - * - * @param string $directory The directory - * @return void + * Called upon initialization of the Container + * + * @throws FactoryException + * @codeCoverageIgnore */ - public function __construct() + public function init() { - $this->pluginPaths[] = Core::$appDir . DS . 'Plugins'; - $this->cfg = Factory::getInstance()->config->plugins; + $this->cfg = Factory::getInstance()->config->getConfig('plugins'); } /** * Load the header files of all plugins. */ - public function loadHeaders() + public function loadHeadersFromPluginPaths() { // Cycle through all pluginPaths - $this->headers = array(); - foreach ($this->pluginPaths as $pluginPath) { - - // If directory does not exist, skip it - if (!file_exists($pluginPath) || !is_dir($pluginPath)) - { - continue; - } + for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) + { + if (!isset($this->componentPaths[$i])) + continue; - // Fetch the contents of the path - $pluginPathContents = array_diff(scandir($pluginPath), array('..', '.')); - - // Now go through each entry in the plugin folder - foreach ($pluginPathContents as $pluginFolder) { - if (!is_dir($pluginPath . DS . $pluginFolder)) - { - continue; - } + foreach ($this->componentPaths[$i] as $pluginPath) { - // If a header file exists, use it - $file = $pluginPath . DS . $pluginFolder . DS . 'header.php'; - $pluginName = ucfirst($pluginFolder); - $className = '\FuzeWorks\Plugins\\'.$pluginName.'Header'; - if (file_exists($file)) - { - // And load it - if (in_array($pluginName, $this->cfg->disabled_plugins)) - { - $this->headers[$pluginName] = 'disabled'; - } - else - { - require_once($file); - $header = new $className(); - $this->headers[$pluginName] = $header; - $this->headers[$pluginName]->init(); - Factory::getInstance()->logger->log('Loaded Plugin Header: \'' . $pluginName . '\''); - } + // If directory does not exist, skip it + if (!file_exists($pluginPath) || !is_dir($pluginPath)) + continue; - } + // Fetch the contents of the path + $pluginPathContents = array_diff(scandir($pluginPath), array('..', '.')); - // If it doesn't exist, skip it - continue; - } + // Now go through each entry in the plugin folder + foreach ($pluginPathContents as $pluginFolder) { + // @codeCoverageIgnoreStart + if (!is_dir($pluginPath . DS . $pluginFolder)) + continue; + // @codeCoverageIgnoreEnd - } + // If a header file exists, use it + $file = $pluginPath . DS . $pluginFolder . DS . 'header.php'; + $pluginFolder = ucfirst($pluginFolder); + $className = '\Application\Plugin\\'.$pluginFolder.'Header'; + if (file_exists($file)) + { + // Load the header file + require_once($file); + $header = new $className(); + if (!$header instanceof iPluginHeader) + continue; + + // Load the header + $this->loadHeader($header); + } + + // If it doesn't exist, skip it + continue; + } + + } + } } /** - * Get a plugin. - * - * @param string $pluginName Name of the plugin - * @param array $parameters Parameters to send to the __construct() method - * @param array $directory Directory to search for plugins in - * @return object Plugin + * Load a header object. + * + * The provided header will be loaded into the header registry and initialized. + * + * @param iPluginHeader $header + * @return bool */ - public function get($pluginName, array $parameters = null, array $directory = null) - { - if (empty($pluginName)) - { - throw new PluginException("Could not load plugin. No name provided", 1); - } + protected function loadHeader(iPluginHeader $header): bool + { + // Fetch the name + $pluginName = ucfirst($header->getName()); - // First get the directories where the plugin can be located - $directories = (is_null($directory) ? $this->pluginPaths : $directory); + // Check if the plugin is disabled + if (in_array($pluginName, $this->cfg->get('disabled_plugins'))) + { + $this->headers[$pluginName] = 'disabled'; + return false; + } + + // Initialize it + $h = $this->headers[$pluginName] = $header; + $h->init(); + + // And log it + Logger::log('Loaded Plugin Header: \'' . $pluginName . '\''); + return true; + } + + /** + * Add a Plugin to FuzeWorks + * + * The provided plugin header will be loaded into the registry and initialized + * + * @param iPluginHeader $header + * @return bool + */ + public function addPlugin(iPluginHeader $header): bool + { + return $this->loadHeader($header); + } + + /** + * Get a plugin. + * + * @param string $pluginName Name of the plugin + * @param array $parameters Parameters to send to the __construct() method + * @return mixed Plugin on success, bool on cancellation + * @throws Exception\EventException + * @throws PluginException + * @throws ReflectionException + */ + public function get($pluginName, array $parameters = null) + { + if (empty($pluginName)) + throw new PluginException("Could not load plugin. No name provided", 1); // Determine the name of the plugin - $pluginFolder = $pluginName; $pluginName = ucfirst($pluginName); // Fire pluginGetEvent, and cancel or return custom plugin if required - $event = Events::fireEvent('pluginGetEvent', $pluginName, $directories); + /** @var PluginGetEvent $event */ + $event = Events::fireEvent('pluginGetEvent', $pluginName); if ($event->isCancelled()) - { return false; - } elseif ($event->getPlugin() != null) - { return $event->getPlugin(); - } // Otherwise just set the variables $pluginName = $event->pluginName; - $directories = $event->directories; // Check if the plugin is already loaded and return directly if (isset($this->plugins[$pluginName])) - { return $this->plugins[$pluginName]; - } // Check if the plugin header exists if (!isset($this->headers[$pluginName])) - { throw new PluginException("Could not load plugin. Plugin header does not exist", 1); - } // If disabled, don't bother - if (in_array($pluginName, $this->cfg->disabled_plugins)) - { + if (in_array($pluginName, $this->cfg->get('disabled_plugins'))) throw new PluginException("Could not load plugin. Plugin is disabled", 1); - } // Determine what file to load + /** @var iPluginHeader $header */ $header = $this->headers[$pluginName]; + + // Add to autoloader + $headerReflection = new ReflectionClass( get_class($header) ); + $prefix = $header->getClassesPrefix(); + $filePath = dirname($headerReflection->getFileName()) . (!empty($header->getSourceDirectory()) ? DS . $header->getSourceDirectory() : ''); + $pluginClass = $header->getPluginClass(); + if (!is_null($prefix) && !is_null($filePath)) + { + try { + Core::addAutoloadMap($prefix, $filePath); + } catch (CoreException $e) { + throw new PluginException("Could not load plugin. Autoloader invalid: '".$e->getMessage()."'"); + } + } + + // If a 'getPlugin' method is found in the header, call that instead if (method_exists($header, 'getPlugin')) { $this->plugins[$pluginName] = $header->getPlugin(); - Factory::getInstance()->logger->log('Loaded Plugin: \'' . $pluginName . '\''); + Logger::log('Loaded Plugin: \'' . $pluginName . '\''); return $this->plugins[$pluginName]; } - $classFile = (isset($header->classFile) ? $header->classFile : $pluginName.".php"); - $className = (isset($header->className) ? $header->className : '\Application\Plugin\\'.$pluginName); - - // Find the correct file - $pluginFile = ''; - foreach ($directories as $pluginPath) { - $file = $pluginPath . DS . $pluginFolder . DS . $classFile; - if (file_exists($file)) - { - $pluginFile = $file; - break; - } - } - - // If not found, throw exception - if (empty($pluginFile)) - { - throw new PluginException("Could not load plugin. Class file does not exist", 1); - } - // Attempt to load the plugin - require_once($pluginFile); - if (!class_exists($className, false)) - { + if (!class_exists($pluginClass, true)) throw new PluginException("Could not load plugin. Class does not exist", 1); - } - $this->plugins[$pluginName] = new $className($parameters); - Factory::getInstance()->logger->log('Loaded Plugin: \'' . $pluginName . '\''); + + $this->plugins[$pluginName] = new $pluginClass($parameters); + Logger::log('Loaded Plugin: \'' . $pluginName . '\''); // And return it return $this->plugins[$pluginName]; } - - /** - * Add a path where plugins can be found - * - * @param string $directory The directory - * @return void - */ - public function addPluginPath($directory) - { - if (!in_array($directory, $this->pluginPaths)) - { - $this->pluginPaths[] = $directory; - } - } - - /** - * Remove a path where plugins can be found - * - * @param string $directory The directory - * @return void - */ - public function removePluginPath($directory) - { - if (($key = array_search($directory, $this->pluginPaths)) !== false) - { - unset($this->pluginPaths[$key]); - } - } - - /** - * Get a list of all current pluginPaths - * - * @return array Array of paths where plugins can be found - */ - public function getPluginPaths(): array - { - return $this->pluginPaths; - } } \ No newline at end of file diff --git a/src/FuzeWorks/Priority.php b/src/FuzeWorks/Priority.php new file mode 100644 index 0000000..26a0610 --- /dev/null +++ b/src/FuzeWorks/Priority.php @@ -0,0 +1,112 @@ + + * @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net) + */ +abstract class Priority +{ + const LOWEST = 5; + const LOW = 4; + const NORMAL = 3; + const HIGH = 2; + const HIGHEST = 1; + const MONITOR = 0; + + /** + * Returns the string of the priority based on the integer. + * + * @param $intPriorty + * + * @return bool|string A bool when the integer isn't a priority. If the integer is a priority, the name is returned + */ + public static function getPriority($intPriorty) + { + switch ($intPriorty) { + case 5: + return 'Priority::LOWEST'; + case 4: + return 'Priority::LOW'; + case 3: + return 'Priority::NORMAL'; + case 2: + return 'Priority::HIGH'; + case 1: + return 'Priority::HIGHEST'; + case 0: + return 'Priority::MONITOR'; + default: + return false; + } + } + + /** + * Returns the highest priority + * This function is needed for executing in the right order,. + * + * @return int + */ + public static function getHighestPriority() + { + return self::MONITOR; + } + + /** + * Returns the lowest priority + * This function is needed for executing in the right order,. + * + * @return int + */ + public static function getLowestPriority() + { + return self::LOWEST; + } +} diff --git a/src/FuzeWorks/Router.php b/src/FuzeWorks/Router.php deleted file mode 100644 index dc32428..0000000 --- a/src/FuzeWorks/Router.php +++ /dev/null @@ -1,588 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Class Router. - * - * This class handles the framework's routing. The router determines which system should be loaded and called. - * The overall structure of the routing is as follows: - * - * The routes-array will hold a list of RegEx-strings. When the route-method is called, the framework will try - * to match the current path found in the URI class against all the RegEx's. When a RegEx matches, - * it will try and load what the route is related to. This can be a callable or a translator. A translator will - * convert the values of a route into a callable. In the end a callable will always be loaded. - * - * Every module can register routes and add their own callables. By default, two callables are available: - * The defaultCallable and the moduleCallable of which the last one is found in the Modules class. - * - * The defaultCallable is a traditional MVC controller loader. Loading an URL when no route matches works as follows: - * - * Let's say the visitor requests /A/B/C - * - * A would be the 'controller' (default: standard) - * B would be the function to be called in the 'controller' (default: index) - * C would be the first parameter - * - * All controllers are to be placed in the /Application/Controller - directory. - * - * This is the default behaviour by adding routes to the config.routes.php. It is also possible to load Modules using routes. - * To load a Module using a route, add the route to the moduleInfo.php in a routes array. - * When this route is matched, a moduleCallable gets loaded which loads the module and loads either a controller file, or a routing function. - * - * But because of this RegEx-table, modules can easily listen on completely different paths. You can, for example, make - * a module that only triggers when /admin///.. is accessed. Or even complexer structure are - * available, e.g: /webshop/product-/view/. - * - * BE AWARE: - * - * Callables are NO controllers!! By default, the 'defaultCallable' will load the correct controller from - * the default controller directory. When you make custom routes, the callable will need to call your own - * controllers. This means that the one callable you provide with your RegEx will be called for EVERYTHING - * the RegEx matches. Only the regex matches will be provided to the callable, - * if no names groups are available; you will need to extract them yourself from the path. - * - * After the core has been loaded, the URI class will generate the URI which is currently being used. - * The index file will then call the route-method, which will call the right controller and it's associated method. - * - * @see Router::route - * @see Router::addRoute - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * - * @todo Implement Query Strings - */ -class Router -{ - /** - * @var array Routes - */ - protected $routes = array(); - - /** - * @var null|mixed The callable - */ - protected $callable = null; - - /** - * @var null|array The extracted matches from the regex - */ - protected $matches = null; - - /** - * Directory from which to load the controllers - * - * @var string Controller directory - */ - protected $controller_directory; - - /** - * The Config class used to get configurations - * - * @var Config FuzeWorks config class - */ - protected $config; - - /** - * The Uri class used to get paths - * - * @var Uri FuzeWorks uri class - */ - protected $uri; - - /** - * The Logger class used to log information - * - * @var Logger FuzeWorks logger class - */ - protected $logger; - - /** - * The Events class used to fire events - * - * @var Events FuzeWorks events class - */ - protected $events; - - /** - * The Output class used to parse cache data - * - * @var Output FuzeWorks output class - */ - protected $output; - - /** - * Constructor of the Router - * - * Loads all required classes and adds all the routes to the routingTable - * - * @return void - */ - public function __construct() - { - // Load related classes - $factory = Factory::getInstance(); - $this->config = $factory->config; - $this->uri = $factory->uri; - $this->logger = $factory->logger; - $this->events = $factory->events; - $this->output = $factory->output; - $this->controller_directory = Core::$appDir . DS . 'Controller'; - - // Start parsing the routing - $this->parseRouting(); - } - - /** - * Route Parser - * - * This method parses all the routes in the routes table config file - * and adds them to the Router. It converts some routes which use wildcards - * - * @return void - */ - protected function parseRouting() - { - // Get routing routes - $routes = $this->config->routes; - $routing = $this->config->routing; - - // If no query strings are used, we will add all routes in the config.routes.php file. - // We modify these routes to be an array of a regex string and a callable - $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli'; - - foreach ($routes as $route => $value) - { - // Check if the route format is using HTTP verbs - if (is_int($route)) - { - $route = $value; - $value = array($this, 'defaultCallable'); - } - elseif (is_array($value)) - { - $value = array_change_key_case($value, CASE_LOWER); - if (isset($value[$http_verb])) - { - $value = $value[$http_verb]; - } - else - { - continue; - } - } - - // Convert wildcards to Regex - $route = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $route); - - $this->addRoute($route, $value, false); - } - } - - /** - * Returns the directory from which all controllers shall be loaded - * - * @return string - */ - public function getControllerDirectory(): string - { - return $this->controller_directory; - } - - /** - * Sets the directory from which all controllers shall be loaded - * - * @param string Controller directory - */ - public function setControllerDirectory($directory) - { - $this->controller_directory = $directory; - } - - /** - * Returns an array with all the routes. - * - * @return array - */ - public function getRoutes(): array - { - return $this->routes; - } - - /** - * Returns the currently loaded or selected callable. - * - * @return null|callable - */ - public function getCallable() - { - return $this->callable; - } - - /** - * Returns all the matches with the RegEx route. - * - * @return null|array - */ - public function getMatches() - { - return $this->matches; - } - - /** - * Add a route to the Router's routing table - * - * The route consists of 2 parts: the route and data. - * - * The route is a regex string which will later be matched upon Router::route(). - * - * The data can be multiple things. First it can be a string, which will later be processed and turned into - * a callable. If the string is like 'controller/method' then the contoller 'Controller' will be loaded and the - * method 'method' will be called. The data can also be a callable. That callable will be called with all the regex - * that match the route. The callable is expected to return a string just like above. You can also provide an array. - * If you have an array like this: array('callable' => array('Class', 'method')) then your callable shall be used - * instead of the defaultCallabele. - * - * @param string $route This is a RegEx of the route, Every capture group will be a match, passed on to a callable - * @param mixed $data Can be multiple things. See description above - * @param bool $prepend Whether or not to insert at the beginning of the routing table - * @return void - */ - public function addRoute($route, $callable, $prepend = true) - { - if ($prepend) { - $this->routes = array($route => $callable) + $this->routes; - } else { - $this->routes[$route] = $callable; - } - - $this->logger->log('Route added at '.($prepend ? 'top' : 'bottom').': "'.$route.'"'); - } - - /** - * Removes a route from the array based on the given route. - * - * @param $route string The route to remove - */ - public function removeRoute($route) - { - unset($this->routes[$route]); - - $this->logger->log('Route removed: '.$route); - } - - /** - * Extracts the routing path from the URL using the routing table. - * - * Determines what should be loaded and what data matches the route regex. - * - * @param bool $performLoading Immediate process the route after it has been determined - */ - public function route($performLoading = true): bool - { - // Turn the segment array into a URI string - $uri = implode('/', $this->uri->segments); - - // Fire the event to notify our modules - $event = Events::fireEvent('routerRouteEvent', $this->routes, $performLoading, $uri); - - // The event has been cancelled - if ($event->isCancelled()) - { - return false; - } - - // Assign everything to the object to make it accessible, but let modules check it first - $routes = $event->routes; - $performLoading = $event->performLoading; - - // If a cached page should be loaded, do so and stop loading a routed page - if ($performLoading === true && $event->cacheOverride === false && $this->output->_display_cache() === true) - { - return true; - } - - // Check the custom routes - foreach ($routes as $route => $value) - { - // Match the path against the routes - if (preg_match('#^'.$route.'$#', $event->path, $matches)) - { - $this->logger->log('Route matched: '.$route); - // Save the matches - $this->matches = $matches; - - // Are we using callbacks or another method? - if ( is_array($value)) - { - // Maybe there is a real callable which should be called in the future - if ( isset($value['callable']) ) - { - $this->callable = $value['callable']; - } - - // If the callable is satisfied, break away - if (!$performLoading || $this->loadCallable($matches, $route)) - { - return true; - } - - // Otherwise try other routes - continue; - } - elseif ( is_callable($value) ) - { - // Prepare the callable - array_shift($matches); - - // Retrieve the path that should be loaded - $value = call_user_func_array($value, $matches); - } - elseif (strpos($value, '$') !== FALSE && strpos($route, '(') !== FALSE) - { - $value = preg_replace('#^'.$route.'$#', $value, $event->path); - } - - if ($performLoading === true) - { - // Now run the defaultRouter for when something is not a callable - $this->routeDefault(explode('/', $value), $route); - return true; - } - - return false; - } - } - - // If we got this far it means we didn't encounter a - // matching route so we'll set the site default route - $this->matches = array(); - if ($performLoading === true) - { - $this->routeDefault(array_values($this->uri->segments), '.*$'); - return true; - } - - return false; - } - - /** - * Converts a routing string into parameters for the defaultCallable. - * - * @param array $segments Segments of the controller,method,parameters to open - * @param string @route The route which was matched - * @return void - */ - protected function routeDefault($segments = array(), $route) - { - // If we don't have any segments left - try the default controller; - // WARNING: Directories get shifted out of the segments array! - if (empty($segments)) - { - $segments[0] = $this->config->routing->default_controller; - } - - if ($this->config->routing->translate_uri_dashes === true) - { - $segments[0] = str_replace('-', '_', $segments[0]); - if (isset($segments[1])) - { - $segments[1] = str_replace('-', '_', $segments[1]); - } - } - - // Prepare the values for loading - $controller = $segments[0]; - $function = (isset($segments[1]) ? $segments[1] : $this->config->routing->default_function); - - // And prepare the Router URI - array_unshift($segments, null); - unset($segments[0]); - $this->uri->rsegments = $segments; - - // Now create a matches array - $matches = array( - 'controller' => $controller, - 'function' => $function, - 'parameters' => array_slice($this->uri->rsegments, 2) - ); - - // And finally load the callable - $this->callable = array('\FuzeWorks\Router', 'defaultCallable'); - $this->loadCallable($matches, $route); - } - - /** - * Load the callable to which the route matched. - * - * First it checks if it is possible to call the callable. If not, the default callable gets selected and a controller, function and parameters get selected. - * - * Then the arguments get prepared and finally the callable is called. - * - * @param array Preg matches with the routing path - * @param string The route that matched - * - * @return bool Whether or not the callable was satisfied - */ - public function loadCallable($matches = array(), $route): bool - { - $this->logger->newLevel('Loading callable'); - - // Fire the event to notify our modules - $event = Events::fireEvent('routerLoadCallableEvent', $this->callable, $matches, $route); - - // The event has been cancelled - if ($event->isCancelled()) { - return false; - } - - // Prepare the arguments and add the route - $args = $event->matches; - $args['route'] = $event->route; - - if (!is_callable($event->callable)) { - if (isset($event->callable['controller'])) { - // Reset the arguments and fetch from custom callable - $args = array(); - $args['controller'] = isset($event->callable['controller']) ? $event->callable['controller'] : (isset($matches['controller']) ? $matches['controller'] : null); - $args['function'] = isset($event->callable['function']) ? $event->callable['function'] : (isset($matches['function']) ? $matches['function'] : null); - $args['parameters'] = isset($event->callable['parameters']) ? $event->callable['parameters'] : (isset($matches['parameters']) ? explode('/', $matches['parameters']) : null); - - $this->callable = array('\FuzeWorks\Router', 'defaultCallable'); - } else { - $this->logger->log('The given callable is not callable!', E_ERROR); - $this->logger->http_error(500); - $this->logger->stopLevel(); - - return true; - } - } else { - $this->callable = $event->callable; - } - - // And log the input to the logger - $this->logger->newLevel('Calling callable'); - foreach ($args as $key => $value) { - $this->logger->log($key.': '.var_export($value, true).''); - } - $this->logger->stopLevel(); - - $skip = call_user_func_array($this->callable, array($args)) === true; - - if (!$skip) { - $this->logger->log('Callable not satisfied, skipping to next callable'); - } - - $this->logger->stopLevel(); - - return $skip; - } - - /** - * The default callable. - * - * This callable will do the 'old skool' routing. It will load the controllers from the controller-directory - * in the application-directory. - */ - public function defaultCallable($arguments = array()): bool - { - $this->logger->log('Default callable called!'); - - $controller = $arguments['controller']; - $function = $arguments['function']; - $parameters = empty($arguments['parameters']) ? null : $arguments['parameters']; - - // Construct file paths and classes - $class = '\Application\Controller\\'.ucfirst($controller); - $directory = $this->controller_directory; - $file = $directory . DS . strtolower('controller.'.$controller.'.php'); - - $event = Events::fireEvent('routerLoadControllerEvent', - $file, - $directory, - $class, - $controller, - $function, - $parameters - ); - - // Cancel if requested to do so - if ($event->isCancelled()) { - return false; - } - - // Check if the file exists - if (file_exists($event->file)) { - if (!class_exists($event->className)) { - $this->logger->log('Loading controller '.$event->className.' from file: '.$event->file); - require $event->file; - } - - // Get the path the controller should know about - $path = implode('/', $this->uri->rsegments); - - // And create the controller - $this->callable = new $event->className($path); - - // If the controller does not want a function to be loaded, provide a halt parameter. - if (isset($this->callable->halt)) { - return false; - } - - // Check if method exists or if there is a caller function - if (method_exists($this->callable, $event->function) || method_exists($this->callable, '__call')) { - // Run the routerCallMethodEvent - $methodEvent = Events::fireEvent('routerCallMethodEvent'); - if ($methodEvent->isCancelled()) - { - return false; - } - - // Execute the function on the controller - $this->output->append_output($this->callable->{$event->function}($event->parameters)); - return true; - } else { - // Function could not be found - $this->logger->log('Could not find function '.$event->function.' on controller '.$event->className); - $this->logger->http_error(404); - } - } else { - // Controller could not be found - $this->logger->log('Could not find controller '.$event->className); - $this->logger->http_error(404); - } - - return false; - } -} diff --git a/src/FuzeWorks/Security.php b/src/FuzeWorks/Security.php deleted file mode 100644 index d3b9e17..0000000 --- a/src/FuzeWorks/Security.php +++ /dev/null @@ -1,1054 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\ConfigORM\ConfigORM; -use FuzeWorks\Exception\{SecurityException,Exception}; - -/** - * Security Class - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Security { - - /** - * List of sanitize filename strings - * - * @var array - */ - public $filename_bad_chars = array( - '../', '', '<', '>', - "'", '"', '&', '$', '#', - '{', '}', '[', ']', '=', - ';', '?', '%20', '%22', - '%3c', // < - '%253c', // < - '%3e', // > - '%0e', // > - '%28', // ( - '%29', // ) - '%2528', // ( - '%26', // & - '%24', // $ - '%3f', // ? - '%3b', // ; - '%3d' // = - ); - - /** - * Character set - * - * Will be overridden by the constructor. - * - * @var string - */ - public $charset = 'UTF-8'; - - /** - * XSS Hash - * - * Random Hash for protecting URLs. - * - * @var string - */ - protected $_xss_hash; - - /** - * CSRF Hash - * - * Random hash for Cross Site Request Forgery protection cookie - * - * @var string - */ - protected $_csrf_hash; - - /** - * CSRF Expire time - * - * Expiration time for Cross Site Request Forgery protection cookie. - * Defaults to two hours (in seconds). - * - * @var int - */ - protected $_csrf_expire = 7200; - - /** - * CSRF Token name - * - * Token name for Cross Site Request Forgery protection cookie. - * - * @var string - */ - protected $_csrf_token_name = 'fw_csrf_token'; - - /** - * CSRF Cookie name - * - * Cookie name for Cross Site Request Forgery protection cookie. - * - * @var string - */ - protected $_csrf_cookie_name = 'fw_csrf_cookie'; - - /** - * List of never allowed strings - * - * @var array - */ - protected $_never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - '-moz-binding' => '[removed]', - '' => '-->', - ' '<![CDATA[', - '' => '<comment>' - ); - - /** - * List of never allowed regex replacements - * - * @var array - */ - protected $_never_allowed_regex = array( - 'javascript\s*:', - '(document|(document\.)?window)\.(location|on\w*)', - 'expression\s*(\(|&\#40;)', // CSS and IE - 'vbscript\s*:', // IE, surprise! - 'wscript\s*:', // IE - 'jscript\s*:', // IE - 'vbs\s*:', // IE - 'Redirect\s+30\d', - "([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?" - ); - - /** - * Config of this class - * - * @var ConfigORM - */ - private $config; - - /** - * Class constructor - * - * @return void - */ - public function __construct() - { - $this->config = Factory::getInstance()->config->get('security'); - - // Is CSRF protection enabled? - if ($this->config->csrf_protection) - { - // CSRF config - foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key) - { - if (NULL !== ($val = $this->config->$key)) - { - $this->{'_'.$key} = $val; - } - } - - // Append application specific cookie prefix - if ($cookie_prefix = Factory::getInstance()->config->get('main')->cookie_prefix) - { - $this->_csrf_cookie_name = $cookie_prefix.$this->_csrf_cookie_name; - } - - // Set the CSRF hash - $this->_csrf_set_hash(); - } - - $this->charset = strtoupper(Factory::getInstance()->config->get('main')->charset); - } - - // -------------------------------------------------------------------- - - /** - * CSRF Verify - * - * @return self - */ - public function csrf_verify(): self - { - // If it's not a POST request we will set the CSRF cookie - if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') - { - return $this->csrf_set_cookie(); - } - - // Check if URI has been whitelisted from CSRF checks - if ($exclude_uris = $this->config->csrf_exclude_uris) - { - foreach ($exclude_uris as $excluded) - { - if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), URI::uri_string())) - { - return $this; - } - } - } - - // Do the tokens exist in both the _POST and _COOKIE arrays? - if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) - OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? - { - $this->csrf_show_error(); - } - - // We kill this since we're done and we don't want to polute the _POST array - unset($_POST[$this->_csrf_token_name]); - - // Regenerate on every submission? - if ($this->config->csrf_regenerate) - { - // Nothing should last forever - unset($_COOKIE[$this->_csrf_cookie_name]); - $this->_csrf_hash = NULL; - } - - $this->_csrf_set_hash(); - $this->csrf_set_cookie(); - - Logger::log('CSRF token verified'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * CSRF Set Cookie - * - * @codeCoverageIgnore - * @return self - */ - public function csrf_set_cookie() - { - $expire = time() + $this->_csrf_expire; - $cfg = Factory::getInstance()->config->get('main'); - $secure_cookie = (bool) $cfg->cookie_secure; - - if ($secure_cookie && ! Core::isHttps()) - { - return $this; - } - - setcookie( - $this->_csrf_cookie_name, - $this->_csrf_hash, - $expire, - $cfg->cookie_path, - $cfg->cookie_domain, - $secure_cookie, - $cfg->cookie_httponly - ); - Logger::log('CSRF cookie sent'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Show CSRF Error - * - * @return void - */ - public function csrf_show_error() - { - throw new SecurityException('The action you have requested is not allowed.', 1); - } - - // -------------------------------------------------------------------- - - /** - * Get CSRF Hash - * - * @see Security::$_csrf_hash - * @return string CSRF hash - */ - public function get_csrf_hash(): string - { - return $this->_csrf_hash; - } - - // -------------------------------------------------------------------- - - /** - * Get CSRF Token Name - * - * @see Security::$_csrf_token_name - * @return string CSRF token name - */ - public function get_csrf_token_name(): string - { - return $this->_csrf_token_name; - } - - // -------------------------------------------------------------------- - - /** - * XSS Clean - * - * Sanitizes data so that Cross Site Scripting Hacks can be - * prevented. This method does a fair amount of work but - * it is extremely thorough, designed to prevent even the - * most obscure XSS attempts. Nothing is ever 100% foolproof, - * of course, but I haven't been able to get anything passed - * the filter. - * - * Note: Should only be used to deal with data upon submission. - * It's not something that should be used for general - * runtime processing. - * - * @link http://channel.bitflux.ch/wiki/XSS_Prevention - * Based in part on some code and ideas from Bitflux. - * - * @link http://ha.ckers.org/xss.html - * To help develop this script I used this great list of - * vulnerabilities along with a few other hacks I've - * harvested from examining vulnerabilities in other programs. - * - * @param string|string[] $str Input data - * @param bool $is_image Whether the input is an image - * @return string|array - */ - public function xss_clean($str, $is_image = FALSE) - { - // Is the string an array? - if (is_array($str)) - { - while (list($key) = each($str)) - { - $str[$key] = $this->xss_clean($str[$key]); - } - - return $str; - } - - // Remove Invisible Characters - $str = UTF8::remove_invisible_characters($str); - - /* - * URL Decode - * - * Just in case stuff like this is submitted: - * - * Google - * - * Note: Use rawurldecode() so it does not remove plus signs - */ - do - { - $str = rawurldecode($str); - } - while (preg_match('/%[0-9a-f]{2,}/i', $str)); - - /* - * Convert character entities to ASCII - * - * This permits our tests below to work reliably. - * We only convert entities that are within tags since - * these are the ones that will pose security problems. - */ - $str = preg_replace_callback("/[^a-z0-9>]+[a-z0-9]+=([\'\"]).*?\\1/si", array('FuzeWorks\Security', '_convert_attribute'), $str); - $str = preg_replace_callback('/<\w+.*/si', array('FuzeWorks\Security', '_decode_entity'), $str); - - // Remove Invisible Characters Again! - $str = UTF8::remove_invisible_characters($str); - - /* - * Convert all tabs to spaces - * - * This prevents strings like this: ja vascript - * NOTE: we deal with spaces between characters later. - * NOTE: preg_replace was found to be amazingly slow here on - * large blocks of data, so we use str_replace. - */ - $str = str_replace("\t", ' ', $str); - - // Capture converted string for later comparison - $converted_string = $str; - - // Remove Strings that are never allowed - $str = $this->_do_never_allowed($str); - - /* - * Makes PHP tags safe - * - * Note: XML tags are inadvertently replaced too: - * - * '), array('<?', '?>'), $str); - } - - /* - * Compact any exploded words - * - * This corrects words like: j a v a s c r i p t - * These words are compacted back to their correct state. - */ - $words = array( - 'javascript', 'expression', 'vbscript', 'jscript', 'wscript', - 'vbs', 'script', 'base64', 'applet', 'alert', 'document', - 'write', 'cookie', 'window', 'confirm', 'prompt', 'eval' - ); - - foreach ($words as $word) - { - $word = implode('\s*', str_split($word)).'\s*'; - - // We only want to do this when it is followed by a non-word character - // That way valid stuff like "dealer to" does not become "dealerto" - $str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array('FuzeWorks\Security', '_compact_exploded_words'), $str); - } - - /* - * Remove disallowed Javascript in links or img tags - * We used to do some version comparisons and use of stripos(), - * but it is dog slow compared to these simplified non-capturing - * preg_match(), especially if the pattern exists in the string - * - * Note: It was reported that not only space characters, but all in - * the following pattern can be parsed as separators between a tag name - * and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C] - * ... however, remove_invisible_characters() above already strips the - * hex-encoded ones, so we'll skip them below. - */ - do - { - $original = $str; - - if (preg_match('/]+([^>]*?)(?:>|$)#si', array('FuzeWorks\Security', '_js_link_removal'), $str); - } - - if (preg_match('/]*?)(?:\s?/?>|$)#si', array('FuzeWorks\Security', '_js_img_removal'), $str); - } - - if (preg_match('/script|xss/i', $str)) - { - $str = preg_replace('##si', '[removed]', $str); - } - } - while ($original !== $str); - unset($original); - - /* - * Sanitize naughty HTML elements - * - * If a tag containing any of the words in the list - * below is found, the tag gets converted to entities. - * - * So this: - * Becomes: <blink> - */ - $pattern = '#' - .'<((?/*\s*)(?[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character - .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator - // optional attributes - .'(?(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons - .'[^\s\042\047>/=]+' // attribute characters - // optional attribute-value - .'(?:\s*=' // attribute-value separator - .'(?:[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*))' // single, double or non-quoted value - .')?' // end optional attribute-value group - .')*)' // end optional attributes group - .'[^>]*)(?\>)?#isS'; - - // Note: It would be nice to optimize this for speed, BUT - // only matching the naughty elements here results in - // false positives and in turn - vulnerabilities! - do - { - $old_str = $str; - $str = preg_replace_callback($pattern, array('FuzeWorks\Security', '_sanitize_naughty_html'), $str); - } - while ($old_str !== $str); - unset($old_str); - - /* - * Sanitize naughty scripting elements - * - * Similar to above, only instead of looking for - * tags it looks for PHP and JavaScript commands - * that are disallowed. Rather than removing the - * code, it simply converts the parenthesis to entities - * rendering the code un-executable. - * - * For example: eval('some code') - * Becomes: eval('some code') - */ - $str = preg_replace( - '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', - '\\1\\2(\\3)', - $str - ); - - // Final clean up - // This adds a bit of extra precaution in case - // something got through the above filters - $str = $this->_do_never_allowed($str); - - /* - * Images are Handled in a Special Way - * - Essentially, we want to know that after all of the character - * conversion is done whether any unwanted, likely XSS, code was found. - * If not, we return TRUE, as the image is clean. - * However, if the string post-conversion does not matched the - * string post-removal of XSS, then it fails, as there was unwanted XSS - * code found and removed/changed during processing. - */ - if ($is_image === TRUE) - { - return ($str === $converted_string); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * XSS Hash - * - * Generates the XSS hash if needed and returns it. - * - * @see Security::$_xss_hash - * @return string XSS hash - */ - public function xss_hash(): string - { - if ($this->_xss_hash === NULL) - { - $rand = $this->get_random_bytes(16); - $this->_xss_hash = ($rand === FALSE) - ? md5(uniqid(mt_rand(), TRUE)) - : bin2hex($rand); - } - - return $this->_xss_hash; - } - - // -------------------------------------------------------------------- - - /** - * Get random bytes - * - * @param int $length Output length - * @return string - */ - public function get_random_bytes($length): string - { - if (empty($length) OR ! ctype_digit((string) $length)) - { - return FALSE; - } - - if (function_exists('random_bytes')) - { - try - { - // The cast is required to avoid TypeError - return random_bytes((int) $length); - } - catch (Exception $e) - { - // If random_bytes() can't do the job, we can't either ... - // There's no point in using fallbacks. - Logger::logError($e->getMessage()); - return FALSE; - } - } - - // Unfortunately, none of the following PRNGs is guaranteed to exist ... - if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) - { - return $output; - } - - - if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE) - { - // Try not to waste entropy ... - Core::isPHP('5.4') && stream_set_chunk_size($fp, $length); - $output = fread($fp, $length); - fclose($fp); - if ($output !== FALSE) - { - return $output; - } - } - - if (function_exists('openssl_random_pseudo_bytes')) - { - return openssl_random_pseudo_bytes($length); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * HTML Entities Decode - * - * A replacement for html_entity_decode() - * - * The reason we are not using html_entity_decode() by itself is because - * while it is not technically correct to leave out the semicolon - * at the end of an entity most browsers will still interpret the entity - * correctly. html_entity_decode() does not convert entities without - * semicolons, so we are left with our own little solution here. Bummer. - * - * @link http://php.net/html-entity-decode - * - * @param string $str Input - * @param string $charset Character set - * @return string - */ - public function entity_decode($str, $charset = NULL): string - { - if (strpos($str, '&') === FALSE) - { - return $str; - } - - static $_entities; - - isset($charset) OR $charset = $this->charset; - $flag = Core::isPHP('5.4') - ? ENT_COMPAT | ENT_HTML5 - : ENT_COMPAT; - - do - { - $str_compare = $str; - - // Decode standard entities, avoiding false positives - if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) - { - if ( ! isset($_entities)) - { - $_entities = array_map( - 'strtolower', - Core::isPHP('5.3.4') - ? get_html_translation_table(HTML_ENTITIES, $flag, $charset) - : get_html_translation_table(HTML_ENTITIES, $flag) - ); - - // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 - // entities to the array manually - if ($flag === ENT_COMPAT) - { - $_entities[':'] = ':'; - $_entities['('] = '('; - $_entities[')'] = ')'; - $_entities["\n"] = '&newline;'; - $_entities["\t"] = '&tab;'; - } - } - - $replace = array(); - $matches = array_unique(array_map('strtolower', $matches[0])); - foreach ($matches as &$match) - { - if (($char = array_search($match.';', $_entities, TRUE)) !== FALSE) - { - $replace[$match] = $char; - } - } - - $str = str_ireplace(array_keys($replace), array_values($replace), $str); - } - - // Decode numeric & UTF16 two byte entities - $str = html_entity_decode( - preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\d{2,4}(?![0-9;]))))/iS', '$1;', $str), - $flag, - $charset - ); - } - while ($str_compare !== $str); - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Filename - * - * @param string $str Input file name - * @param bool $relative_path Whether to preserve paths - * @return string - */ - public function sanitize_filename($str, $relative_path = FALSE): string - { - $bad = $this->filename_bad_chars; - - if ( ! $relative_path) - { - $bad[] = './'; - $bad[] = '/'; - } - - $str = UTF8::remove_invisible_characters($str, FALSE); - - do - { - $old = $str; - $str = str_replace($bad, '', $str); - } - while ($old !== $str); - - return stripslashes($str); - } - - // ---------------------------------------------------------------- - - /** - * Strip Image Tags - * - * @param string $str - * @return string - */ - public function strip_image_tags($str): string - { - return preg_replace( - array( - '##i', - '#`]+)).*?\>#i' - ), - '\\2', - $str - ); - } - - // ---------------------------------------------------------------- - - /** - * Compact Exploded Words - * - * Callback method for xss_clean() to remove whitespace from - * things like 'j a v a s c r i p t'. - * - * @used-by Security::xss_clean() - * @param array $matches - * @return string - */ - protected function _compact_exploded_words($matches): string - { - return preg_replace('/\s+/s', '', $matches[1]).$matches[2]; - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Naughty HTML - * - * Callback method for xss_clean() to remove naughty HTML elements. - * - * @used-by Security::xss_clean() - * @param array $matches - * @return string - */ - protected function _sanitize_naughty_html($matches): string - { - static $naughty_tags = array( - 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', - 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer', - 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object', - 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss' - ); - - static $evil_attributes = array( - 'on\w+', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime' - ); - - // First, escape unclosed tags - if (empty($matches['closeTag'])) - { - return '<'.$matches[1]; - } - // Is the element that we caught naughty? If so, escape it - elseif (in_array(strtolower($matches['tagName']), $naughty_tags, TRUE)) - { - return '<'.$matches[1].'>'; - } - // For other tags, see if their attributes are "evil" and strip those - elseif (isset($matches['attributes'])) - { - // We'll store the already fitlered attributes here - $attributes = array(); - - // Attribute-catching pattern - $attributes_pattern = '#' - .'(?[^\s\042\047>/=]+)' // attribute characters - // optional attribute-value - .'(?:\s*=(?[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*)))' // attribute-value separator - .'#i'; - - // Blacklist pattern for evil attribute names - $is_evil_pattern = '#^('.implode('|', $evil_attributes).')$#i'; - - // Each iteration filters a single attribute - do - { - // Strip any non-alpha characters that may preceed an attribute. - // Browsers often parse these incorrectly and that has been a - // of numerous XSS issues we've had. - $matches['attributes'] = preg_replace('#^[^a-z]+#i', '', $matches['attributes']); - - if ( ! preg_match($attributes_pattern, $matches['attributes'], $attribute, PREG_OFFSET_CAPTURE)) - { - // No (valid) attribute found? Discard everything else inside the tag - break; - } - - if ( - // Is it indeed an "evil" attribute? - preg_match($is_evil_pattern, $attribute['name'][0]) - // Or does it have an equals sign, but no value and not quoted? Strip that too! - OR (trim($attribute['value'][0]) === '') - ) - { - $attributes[] = 'xss=removed'; - } - else - { - $attributes[] = $attribute[0][0]; - } - - $matches['attributes'] = substr($matches['attributes'], $attribute[0][1] + strlen($attribute[0][0])); - } - while ($matches['attributes'] !== ''); - - $attributes = empty($attributes) - ? '' - : ' '.implode(' ', $attributes); - return '<'.$matches['slash'].$matches['tagName'].$attributes.'>'; - } - - return $matches[0]; - } - - // -------------------------------------------------------------------- - - /** - * JS Link Removal - * - * Callback method for xss_clean() to sanitize links. - * - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on link-heavy strings. - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _js_link_removal($match): string - { - return str_replace( - $match[1], - preg_replace( - '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) - ), - $match[0] - ); - } - - // -------------------------------------------------------------------- - - /** - * JS Image Removal - * - * Callback method for xss_clean() to sanitize image tags. - * - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on image tag heavy strings. - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _js_img_removal($match): string - { - return str_replace( - $match[1], - preg_replace( - '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) - ), - $match[0] - ); - } - - // -------------------------------------------------------------------- - - /** - * Attribute Conversion - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _convert_attribute($match): string - { - return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]); - } - - // -------------------------------------------------------------------- - - /** - * Filter Attributes - * - * Filters tag attributes for consistency and safety. - * - * @used-by Security::_js_img_removal() - * @used-by Security::_js_link_removal() - * @param string $str - * @return string - */ - protected function _filter_attributes($str): string - { - $out = ''; - if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)) - { - foreach ($matches[0] as $match) - { - $out .= preg_replace('#/\*.*?\*/#s', '', $match); - } - } - - return $out; - } - - // -------------------------------------------------------------------- - - /** - * HTML Entity Decode Callback - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _decode_entity($match): string - { - // Protect GET variables in URLs - // 901119URL5918AMP18930PROTECT8198 - $match = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-/]+)|i', $this->xss_hash().'\\1=\\2', $match[0]); - - // Decode, then un-protect URL GET vars - return str_replace( - $this->xss_hash(), - '&', - $this->entity_decode($match, $this->charset) - ); - } - - // -------------------------------------------------------------------- - - /** - * Do Never Allowed - * - * @used-by Security::xss_clean() - * @param string - * @return string - */ - protected function _do_never_allowed($str): string - { - $str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str); - - foreach ($this->_never_allowed_regex as $regex) - { - $str = preg_replace('#'.$regex.'#is', '[removed]', $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Set CSRF Hash and Cookie - * - * @return string - */ - protected function _csrf_set_hash(): string - { - if ($this->_csrf_hash === NULL) - { - // If the cookie exists we will use its value. - // We don't necessarily want to regenerate it with - // each page load since a page could contain embedded - // sub-pages causing this feature to fail - if (isset($_COOKIE[$this->_csrf_cookie_name]) && is_string($_COOKIE[$this->_csrf_cookie_name]) - && preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1) - { - return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; - } - - $rand = $this->get_random_bytes(16); - $this->_csrf_hash = ($rand === FALSE) - ? md5(uniqid(mt_rand(), TRUE)) - : bin2hex($rand); - } - - return $this->_csrf_hash; - } - -} diff --git a/src/FuzeWorks/TemplateEngine/JsonEngine.php b/src/FuzeWorks/TemplateEngine/JsonEngine.php deleted file mode 100644 index 8424d0a..0000000 --- a/src/FuzeWorks/TemplateEngine/JsonEngine.php +++ /dev/null @@ -1,113 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Template Engine that exports all assigned variables as JSON. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class JsonEngine implements TemplateEngine -{ - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - /** - * Whether the JSON data should be parsed or left as is. - * - * @var bool true if to be parsed - */ - protected static $string_return = true; - - /** - * Whether the JSON data should be parsed or left as is. - * - * @param true if to be parsed - */ - public static function returnAsString($boolean = true) - { - self::$string_return = $boolean; - } - - public function setDirectory($directory) - { - return true; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - - // First set up the JSON array - $json = array(); - - // Look up if a file is provided - if (!is_null($file)) { - // Retrieve a file - $string = file_get_contents($file); - $json = json_decode($string, true); - } - - // Then assign all variables - $json['data'] = $this->assigned_variables; - - // And return it - if (self::$string_return) { - return json_encode($json); - } - - return $json; - } - - public function getFileExtensions() - { - return array('json'); - } - - public function reset() - { - $this->assigned_variables = array(); - self::$string_return = true; - } - - public function test($param1, $param2, $param3) - { - return array($param1, $param2, $param3); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/LatteEngine.php b/src/FuzeWorks/TemplateEngine/LatteEngine.php deleted file mode 100644 index f224724..0000000 --- a/src/FuzeWorks/TemplateEngine/LatteEngine.php +++ /dev/null @@ -1,105 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -use FuzeWorks\Exception\LayoutException; -use FuzeWorks\Core; -use Latte\Engine as Latte; - -/** - * Wrapper for the Latte Engine from Nette Framework. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LatteEngine implements TemplateEngine -{ - - /** - * Instance of the Latte Engine - * - * @var Latte\Engine The Latte Engine to be used - */ - protected $latte; - - /** - * Set the directory of the current template. - * - * @param string $directory Template Directory - */ - public function setDirectory($directory) - { - if (class_exists('\Latte\Engine', true)) - { - // If possible, load Latte\Engine - $this->latte = new Latte; - $this->latte->setTempDirectory(realpath(Core::$tempDir . DS . 'Latte')); - } - else - { - throw new LayoutException("Could not load LatteEngine. Is it installed or Composer not loaded?", 1); - } - } - - /** - * Handle and retrieve a template file. - * - * @param string $file Template File - * @param array $assigned_variables All the variables used in this layout - * - * @return string Output of the template - */ - public function get($file, $assigned_variables) - { - return $this->latte->renderToString($file, $assigned_variables); - } - - /** - * Retrieve the file extensions that this template engine uses. - * - * @return array All used extensions. eg: array('php') - */ - public function getFileExtensions() - { - return array('latte'); - } - - /** - * Reset the template engine to its default state, so it can be used again clean. - */ - public function reset() - { - // If possible, load Latte\Engine - $this->latte = null; - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/PHPEngine.php b/src/FuzeWorks/TemplateEngine/PHPEngine.php deleted file mode 100644 index 1fcc4a4..0000000 --- a/src/FuzeWorks/TemplateEngine/PHPEngine.php +++ /dev/null @@ -1,88 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Simple Template Engine that allows for PHP templates. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class PHPEngine implements TemplateEngine -{ - /** - * The currently used directory by the template. - * - * @var string - */ - protected $directory; - - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - public function setDirectory($directory) - { - $this->directory = $directory; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - $vars = $this->assigned_variables; - $directory = $this->directory; - - // Then run the file - if (!is_null($file)) { - ob_start(); - include $file; - - return ob_get_clean(); - } - } - - public function getFileExtensions() - { - return array('php'); - } - - public function reset() - { - $this->directory = null; - $this->assigned_variables = array(); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/SmartyEngine.php b/src/FuzeWorks/TemplateEngine/SmartyEngine.php deleted file mode 100644 index 1709600..0000000 --- a/src/FuzeWorks/TemplateEngine/SmartyEngine.php +++ /dev/null @@ -1,166 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -use FuzeWorks\Core; -use Smarty; - -/** - * Wrapper for the Smarty Template Engine. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class SmartyEngine implements TemplateEngine -{ - /** - * The currently used directory by the template. - * - * @var string - */ - protected $directory; - - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - /** - * Instance of the Smarty Template Engine. - * - * @var \Smarty - */ - protected $smartyInstance; - - public function setDirectory($directory) - { - $this->directory = $directory; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - - // Load Smarty - $this->loadSmarty(); - - // Set the directory - $this->smartyInstance->setTemplateDir($this->directory); - - // Then assign all variables - foreach ($this->assigned_variables as $key => $value) { - $this->smartyInstance->assign($key, $value); - } - - // And finally, load the template - return $this->smartyInstance->fetch($file); - } - - /** - * Loads a Smarty instance if it is not already loaded. - */ - private function loadSmarty() - { - if (is_null($this->smartyInstance)) { - $this->smartyInstance = new Smarty(); - - // Then prepare all variables - $this->smartyInstance->setCompileDir(Core::$tempDir . DS . 'Smarty' . DS . 'Compile'); - $this->smartyInstance->setCacheDir(Core::$tempDir . DS . 'Smarty'); - } - } - - public function getFileExtensions() - { - return array('tpl'); - } - - public function reset() - { - $this->smartyInstance = null; - $this->directory = null; - $this->assigned_variables = array(); - } - - /** - * Retrieve a value from Smarty. - * - * @param string $name Variable name - * - * @return mixed Variable Value - * - * @throws \FuzeWorks\LayoutException on error - */ - public function __get($name) - { - // First load Smarty - $this->loadSmarty(); - - return $this->smartyInstance->$name; - } - - /** - * Set a variable in Smarty. - * - * @param string $name Variable Name - * @param mixed $value Variable Value - * - * @throws \FuzeWorks\LayoutException on error - */ - public function __set($name, $value) - { - // First load Smarty - $this->loadSmarty(); - - $this->smartyInstance->$name = $value; - } - - /** - * Calls a function in Smarty. - * - * @param string $name Name of the function to be called - * @param Paramaters $params Parameters to be used - * - * @return mixed Function output - */ - public function __call($name, $params) - { - // First load Smarty - $this->loadSmarty(); - - return call_user_func_array(array($this->smartyInstance, $name), $params); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/TemplateEngine.php b/src/FuzeWorks/TemplateEngine/TemplateEngine.php deleted file mode 100644 index 58e140e..0000000 --- a/src/FuzeWorks/TemplateEngine/TemplateEngine.php +++ /dev/null @@ -1,71 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Interface that all Template Engines must follow. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -interface TemplateEngine -{ - /** - * Set the directory of the current template. - * - * @param string $directory Template Directory - */ - public function setDirectory($directory); - - /** - * Handle and retrieve a template file. - * - * @param string $file Template File - * @param array $assigned_variables All the variables used in this layout - * - * @return string Output of the template - */ - public function get($file, $assigned_variables); - - /** - * Retrieve the file extensions that this template engine uses. - * - * @return array All used extensions. eg: array('php') - */ - public function getFileExtensions(); - - /** - * Reset the template engine to its default state, so it can be used again clean. - */ - public function reset(); -} \ No newline at end of file diff --git a/src/FuzeWorks/URI.php b/src/FuzeWorks/URI.php deleted file mode 100644 index 0f6d690..0000000 --- a/src/FuzeWorks/URI.php +++ /dev/null @@ -1,672 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.1.1 - */ - -namespace FuzeWorks; -use FuzeWorks\ConfigORM\ConfigORM; -use FuzeWorks\Exception\UriException; - -/** - * URI Class - * - * Parses URIs and determines routing - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class URI { - - /** - * List of cached URI segments - * - * @var array - */ - public $keyval = array(); - - /** - * Current URI string - * - * @var string - */ - public $uri_string = ''; - - /** - * List of URI segments - * - * Starts at 1 instead of 0. - * - * @var array - */ - public $segments = array(); - - /** - * List of routed URI segments - * - * Starts at 1 instead of 0. - * - * @var array - */ - public $rsegments = array(); - - /** - * Permitted URI chars - * - * PCRE character group allowed in URI segments - * - * @var string - */ - protected $_permitted_uri_chars; - - /** - * The configuration of this class - * - * @var ConfigORM - */ - private $config; - - /** - * Class constructor - * - * @return void - */ - public function __construct() - { - $this->config = Factory::getInstance()->config->get('routing'); - - // Determine the base_url - if (empty(Factory::getInstance()->config->get('main')->base_url)) - { - if (isset($_SERVER['SERVER_ADDR'])) - { - if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE) - { - $server_addr = '['.$_SERVER['SERVER_ADDR'].']'; - } - else - { - $server_addr = $_SERVER['SERVER_ADDR']; - } - - $base_url = (Core::isHttps() ? 'https' : 'http').'://'.$server_addr - .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME']))); - } - else - { - $base_url = 'http://localhost/'; - } - - Factory::getInstance()->config->get('main')->base_url = $base_url; - } - - // If it's a CLI request, ignore the configuration - if (Core::isCli()) - { - $this->_set_uri_string($this->_parse_argv(), TRUE); - } - // If query strings are enabled, we don't need to parse any segments. - elseif ($this->config->enable_query_strings !== TRUE) - { - $this->_permitted_uri_chars = $this->config->permitted_uri_chars; - $protocol = $this->config->uri_protocol; - empty($protocol) && $protocol = 'REQUEST_URI'; - - switch ($protocol) - { - case 'AUTO': // For BC purposes only - case 'REQUEST_URI': - $uri = $this->_parse_request_uri(); - break; - case 'QUERY_STRING': - $uri = $this->_parse_query_string(); - break; - case 'PATH_INFO': - $uri = isset($_SERVER[$protocol]) - ? $_SERVER[$protocol] - : $this->_parse_request_uri(); - break; - } - - $this->_set_uri_string($uri, FALSE); - } - } - - // -------------------------------------------------------------------- - - /** - * Set URI String - * - * @param string $str - * @return void - */ - protected function _set_uri_string($str, $is_cli = FALSE) - { - if ($is_cli) - { - if (($this->uri_string = trim($str, '/')) === '') - { - return; - } - - $this->segments[0] = NULL; - foreach (explode('/', $this->uri_string) as $segment) - { - if (($segment = trim($segment)) !== '') - { - $this->segments[] = $segment; - } - } - - unset($this->segments[0]); - return; - } - - // Filter out control characters and trim slashes - $this->uri_string = trim(Utf8::remove_invisible_characters($str, FALSE), '/'); - - if ($this->uri_string === '') - { - return; - } - - // Remove the URL suffix, if present - if (($suffix = (string) $this->config->url_suffix) !== '') - { - $slen = strlen($suffix); - - if (substr($this->uri_string, -$slen) === $suffix) - { - $this->uri_string = substr($this->uri_string, 0, -$slen); - } - } - - $this->segments[0] = NULL; - foreach (explode('/', trim($this->uri_string, '/')) as $segment) - { - $segment = trim($segment); - // Filter segments for security - $this->filter_uri($segment); - - if ($segment !== '') - { - $this->segments[] = $segment; - } - } - - unset($this->segments[0]); - } - - // -------------------------------------------------------------------- - - /** - * Parse REQUEST_URI - * - * Will parse REQUEST_URI and automatically detect the URI from it, - * while fixing the query string if necessary. - * - * @return string - */ - protected function _parse_request_uri(): string - { - if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME'])) - { - return ''; - } - - // parse_url() returns false if no host is present, but the path or query string - // contains a colon followed by a number - $uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']); - $query = isset($uri['query']) ? $uri['query'] : ''; - $uri = isset($uri['path']) ? $uri['path'] : ''; - - if (isset($_SERVER['SCRIPT_NAME'][0])) - { - if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) - { - $uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME'])); - } - elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) - { - $uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); - } - } - - // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct - // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) - { - $query = explode('?', $query, 2); - $uri = $query[0]; - $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; - } - else - { - $_SERVER['QUERY_STRING'] = $query; - } - - parse_str($_SERVER['QUERY_STRING'], $_GET); - - if ($uri === '/' OR $uri === '') - { - return '/'; - } - - // Do some final cleaning of the URI and return it - return $this->_remove_relative_directory($uri); - } - - // -------------------------------------------------------------------- - - /** - * Parse QUERY_STRING - * - * Will parse QUERY_STRING and automatically detect the URI from it. - * - * @return string - */ - protected function _parse_query_string(): string - { - $uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); - - if (trim($uri, '/') === '') - { - return ''; - } - elseif (strncmp($uri, '/', 1) === 0) - { - $uri = explode('?', $uri, 2); - $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : ''; - $uri = $uri[0]; - } - - parse_str($_SERVER['QUERY_STRING'], $_GET); - - return $this->_remove_relative_directory($uri); - } - - // -------------------------------------------------------------------- - - /** - * Parse CLI arguments - * - * Take each command line argument and assume it is a URI segment. - * - * @return string - */ - protected function _parse_argv(): string - { - $args = array_slice($_SERVER['argv'], 1); - return $args ? implode('/', $args) : ''; - } - - // -------------------------------------------------------------------- - - /** - * Remove relative directory (../) and multi slashes (///) - * - * Do some final cleaning of the URI and return it, currently only used in $this->_parse_request_uri() - * - * @param string $uri - * @return string - */ - protected function _remove_relative_directory($uri): string - { - $uris = array(); - $tok = strtok($uri, '/'); - while ($tok !== FALSE) - { - if (( ! empty($tok) OR $tok === '0') && $tok !== '..') - { - $uris[] = $tok; - } - $tok = strtok('/'); - } - - return implode('/', $uris); - } - - // -------------------------------------------------------------------- - - /** - * Filter URI - * - * Filters segments for malicious characters. - * - * @param string $str - * @return bool - */ - public function filter_uri(&$str): bool - { - if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str)) - { - throw new UriException('The URI you submitted has disallowed characters.', 1); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI Segment - * - * @see URI::$segments - * @param int $n Index - * @param mixed $no_result What to return if the segment index is not found - * @return mixed - */ - public function segment($n, $no_result = NULL) - { - return isset($this->segments[$n]) ? $this->segments[$n] : $no_result; - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI "routed" Segment - * - * Returns the re-routed URI segment (assuming routing rules are used) - * based on the index provided. If there is no routing, will return - * the same result as URI::segment(). - * - * @see URI::$rsegments - * @see URI::segment() - * @param int $n Index - * @param mixed $no_result What to return if the segment index is not found - * @return mixed - */ - public function rsegment($n, $no_result = NULL) - { - return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result; - } - - // -------------------------------------------------------------------- - - /** - * URI to assoc - * - * Generates an associative array of URI data starting at the supplied - * segment index. For example, if this is your URI: - * - * example.com/user/search/name/joe/location/UK/gender/male - * - * You can use this method to generate an array with this prototype: - * - * array ( - * name => joe - * location => UK - * gender => male - * ) - * - * @param int $n Index (default: 3) - * @param array $default Default values - * @return array - */ - public function uri_to_assoc($n = 3, $default = array()): array - { - return $this->_uri_to_assoc($n, $default, 'segment'); - } - - // -------------------------------------------------------------------- - - /** - * Routed URI to assoc - * - * Identical to URI::uri_to_assoc(), only it uses the re-routed - * segment array. - * - * @see URI::uri_to_assoc() - * @param int $n Index (default: 3) - * @param array $default Default values - * @return array - */ - public function ruri_to_assoc($n = 3, $default = array()): array - { - return $this->_uri_to_assoc($n, $default, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Internal URI-to-assoc - * - * Generates a key/value pair from the URI string or re-routed URI string. - * - * @used-by URI::uri_to_assoc() - * @used-by URI::ruri_to_assoc() - * @param int $n Index (default: 3) - * @param array $default Default values - * @param string $which Array name ('segment' or 'rsegment') - * @return array - */ - protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment'): array - { - if ( ! is_numeric($n)) - { - return $default; - } - - if (isset($this->keyval[$which], $this->keyval[$which][$n])) - { - return $this->keyval[$which][$n]; - } - - $total_segments = "total_{$which}s"; - $segment_array = "{$which}_array"; - - if ($this->$total_segments() < $n) - { - return (count($default) === 0) - ? array() - : array_fill_keys($default, NULL); - } - - $segments = array_slice($this->$segment_array(), ($n - 1)); - $i = 0; - $lastval = ''; - $retval = array(); - foreach ($segments as $seg) - { - if ($i % 2) - { - $retval[$lastval] = $seg; - } - else - { - $retval[$seg] = NULL; - $lastval = $seg; - } - - $i++; - } - - if (count($default) > 0) - { - foreach ($default as $val) - { - if ( ! array_key_exists($val, $retval)) - { - $retval[$val] = NULL; - } - } - } - - // Cache the array for reuse - isset($this->keyval[$which]) OR $this->keyval[$which] = array(); - $this->keyval[$which][$n] = $retval; - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Assoc to URI - * - * Generates a URI string from an associative array. - * - * @param array $array Input array of key/value pairs - * @return string URI string - */ - public function assoc_to_uri($array): string - { - $temp = array(); - foreach ((array) $array as $key => $val) - { - $temp[] = $key; - $temp[] = $val; - } - - return implode('/', $temp); - } - - // -------------------------------------------------------------------- - - /** - * Slash segment - * - * Fetches an URI segment with a slash. - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @return string - */ - public function slash_segment($n, $where = 'trailing'): string - { - return $this->_slash_segment($n, $where, 'segment'); - } - - // -------------------------------------------------------------------- - - /** - * Slash routed segment - * - * Fetches an URI routed segment with a slash. - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @return string - */ - public function slash_rsegment($n, $where = 'trailing'): string - { - return $this->_slash_segment($n, $where, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Internal Slash segment - * - * Fetches an URI Segment and adds a slash to it. - * - * @used-by URI::slash_segment() - * @used-by URI::slash_rsegment() - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @param string $which Array name ('segment' or 'rsegment') - * @return string - */ - protected function _slash_segment($n, $where = 'trailing', $which = 'segment'): string - { - $leading = $trailing = '/'; - - if ($where === 'trailing') - { - $leading = ''; - } - elseif ($where === 'leading') - { - $trailing = ''; - } - - return $leading.$this->$which($n).$trailing; - } - - // -------------------------------------------------------------------- - - /** - * Segment Array - * - * @return array URI::$segments - */ - public function segment_array(): array - { - return $this->segments; - } - - // -------------------------------------------------------------------- - - /** - * Routed Segment Array - * - * @return array URI::$rsegments - */ - public function rsegment_array(): array - { - return $this->rsegments; - } - - // -------------------------------------------------------------------- - - /** - * Total number of segments - * - * @return int - */ - public function total_segments(): int - { - return count($this->segments); - } - - // -------------------------------------------------------------------- - - /** - * Total number of routed segments - * - * @return int - */ - public function total_rsegments(): int - { - return count($this->rsegments); - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI string - * - * @return string URI::$uri_string - */ - public function uri_string(): string - { - return $this->uri_string; - } -} diff --git a/src/FuzeWorks/Utf8.php b/src/FuzeWorks/Utf8.php deleted file mode 100644 index 91052f2..0000000 --- a/src/FuzeWorks/Utf8.php +++ /dev/null @@ -1,245 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Utf8 Class - * - * Provides support for UTF-8 environments - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Utf8 { - - /** - * Class constructor - * - * Determines if UTF-8 support is to be enabled. - * - * @return void - */ - public function __construct() - { - $charset = strtoupper(Factory::getInstance()->config->get('main')->charset); - ini_set('default_charset', $charset); - - /* - * Configure mbstring and/or iconv if they are enabled - * and set MB_ENABLED and ICONV_ENABLED constants, so - * that we don't repeatedly do extension_loaded() or - * function_exists() calls. - */ - if (extension_loaded('mbstring')) - { - define('MB_ENABLED', TRUE); - // mbstring.internal_encoding is deprecated starting with PHP 5.6 - // and it's usage triggers E_DEPRECATED messages. - if (! Core::isPHP('5.6')) - { - @ini_set('mbstring.internal_encoding', $charset); - } - else - { - mb_internal_encoding($charset); - } - // This is required for mb_convert_encoding() to strip invalid characters. - // That's utilized by Utf8, but it's also done for consistency with iconv. - mb_substitute_character('none'); - } - else - { - define('MB_ENABLED', FALSE); - } - - // There's an ICONV_IMPL constant, but the PHP manual says that using - // iconv's predefined constants is "strongly discouraged". - if (extension_loaded('iconv')) - { - define('ICONV_ENABLED', TRUE); - // iconv.internal_encoding is deprecated starting with PHP 5.6 - // and it's usage triggers E_DEPRECATED messages. - if ( ! Core::isPHP(5.6) ) - { - @ini_set('iconv.internal_encoding', $charset); - } - else - { - ini_set('default_encoding', $charset); - } - } - else - { - define('ICONV_ENABLED', FALSE); - } - - if (Core::isPHP('5.6')) - { - ini_set('php.internal_encoding', $charset); - } - - if ( - defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8 - && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed - && strtoupper($charset) === 'UTF-8' // Application charset must be UTF-8 - ) - { - define('UTF8_ENABLED', TRUE); - Logger::log('UTF-8 Support Enabled'); - } - else - { - define('UTF8_ENABLED', FALSE); - Logger::log('UTF-8 Support Disabled'); - } - } - - // -------------------------------------------------------------------- - - /** - * Clean UTF-8 strings - * - * Ensures strings contain only valid UTF-8 characters. - * - * @param string $str String to clean - * @return string - */ - public function clean_string($str): string - { - if ($this->is_ascii($str) === FALSE) - { - if (MB_ENABLED) - { - $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); - } - elseif (ICONV_ENABLED) - { - $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str); - } - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Remove ASCII control characters - * - * Removes all ASCII control characters except horizontal tabs, - * line feeds, and carriage returns, as all others can cause - * problems in XML. - * - * @param string $str String to clean - * @return string - */ - public function safe_ascii_for_xml($str): string - { - return $this->remove_invisible_characters($str, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Convert to UTF-8 - * - * Attempts to convert a string to UTF-8. - * - * @param string $str Input string - * @param string $encoding Input encoding - * @return string $str encoded in UTF-8 or FALSE on failure - */ - public function convert_to_utf8($str, $encoding): string - { - if (MB_ENABLED) - { - return mb_convert_encoding($str, 'UTF-8', $encoding); - } - elseif (ICONV_ENABLED) - { - return @iconv($encoding, 'UTF-8', $str); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Is ASCII? - * - * Tests if a string is standard 7-bit ASCII or not. - * - * @param string $str String to check - * @return bool - */ - public function is_ascii($str): bool - { - return (preg_match('/[^\x00-\x7F]/S', $str) === 0); - } - - /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @param string - * @param bool - * @return string - */ - public static function remove_invisible_characters($str, $url_encoded = TRUE): string - { - $non_displayables = array(); - - // every control character except newline (dec 10), - // carriage return (dec 13) and horizontal tab (dec 09) - if ($url_encoded) - { - $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 - } - - $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 - - do - { - $str = preg_replace($non_displayables, '', $str, -1, $count); - } - while ($count); - - return $str; - } - -} diff --git a/src/FuzeWorks/iComponent.php b/src/FuzeWorks/iComponent.php new file mode 100644 index 0000000..6dd91ff --- /dev/null +++ b/src/FuzeWorks/iComponent.php @@ -0,0 +1,45 @@ +. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks Array Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/array_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('element')) -{ - /** - * Element - * - * Lets you determine whether an array index is set and whether it has a value. - * If the element is empty it returns NULL (or whatever you specify as the default value.) - * - * @param string - * @param array - * @param mixed - * @return mixed depends on what the array contains - */ - function element($item, array $array, $default = NULL) - { - return array_key_exists($item, $array) ? $array[$item] : $default; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('random_element')) -{ - /** - * Random Element - Takes an array as input and returns a random element - * - * @param array - * @return mixed depends on what the array contains - */ - function random_element($array) - { - return is_array($array) ? $array[array_rand($array)] : $array; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('elements')) -{ - /** - * Elements - * - * Returns only the array items specified. Will return a default value if - * it is not set. - * - * @param array - * @param array - * @param mixed - * @return mixed depends on what the array contains - */ - function elements($items, array $array, $default = NULL) - { - $return = array(); - - is_array($items) OR $items = array($items); - - foreach ($items as $item) - { - $return[$item] = array_key_exists($item, $array) ? $array[$item] : $default; - } - - return $return; - } -} diff --git a/src/Helpers/common_helper.php b/src/Helpers/common_helper.php deleted file mode 100644 index 3af8f5f..0000000 --- a/src/Helpers/common_helper.php +++ /dev/null @@ -1,164 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; - -/** - * FuzeWorks Common Functions - * - * Converted from CodeIgniter. - * - * Loads the base classes and executes the request. - * - * @package FuzeWorks - * @subpackage FuzeWorks - * @category Common Functions - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/ - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_php')) -{ - /** - * Determines if the current version of PHP is equal to or greater than the supplied value - * - * @param string - * @return bool TRUE if the current version is $version or higher - */ - function is_php($version) - { - static $_is_php; - $version = (string) $version; - - if ( ! isset($_is_php[$version])) - { - $_is_php[$version] = version_compare(PHP_VERSION, $version, '>='); - } - - return $_is_php[$version]; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_mimes')) -{ - /** - * Returns the MIME types array from config/mimes.php - * - * @return array - */ - function &get_mimes() - { - static $_mimes; - - if (empty($_mimes)) - { - $_mimes = FuzeWorks\Factory::getInstance()->config->get('mimes'); - } - - return $_mimes; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('html_escape')) -{ - /** - * Returns HTML escaped variable. - * - * @param mixed $var The input string or array of strings to be escaped. - * @param bool $double_encode $double_encode set to FALSE prevents escaping twice. - * @return mixed The escaped string or array of strings as a result. - */ - function html_escape($var, $double_encode = TRUE) - { - if (empty($var)) - { - return $var; - } - - if (is_array($var)) - { - foreach (array_keys($var) as $key) - { - $var[$key] = html_escape($var[$key], $double_encode); - } - - return $var; - } - - return htmlspecialchars($var, ENT_QUOTES, FuzeWorks\Factory::getInstance()->config->get('main')->charset, $double_encode); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('_stringify_attributes')) -{ - /** - * Stringify attributes for use in HTML tags. - * - * Helper function used to convert a string, array, or object - * of attributes to a string. - * - * @param mixed string, array, object - * @param bool - * @return string - */ - function _stringify_attributes($attributes, $js = FALSE) - { - $atts = NULL; - - if (empty($attributes)) - { - return $atts; - } - - if (is_string($attributes)) - { - return ' '.$attributes; - } - - $attributes = (array) $attributes; - - foreach ($attributes as $key => $val) - { - $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"'; - } - - return rtrim($atts, ','); - } -} \ No newline at end of file diff --git a/src/Helpers/download_helper.php b/src/Helpers/download_helper.php deleted file mode 100644 index 71b81f6..0000000 --- a/src/Helpers/download_helper.php +++ /dev/null @@ -1,155 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks Download Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/download_helper.html - */ - -// ------------------------------------------------------------------------ - -use FuzeWorks\Factory; - -if ( ! function_exists('force_download')) -{ - /** - * Force Download - * - * Generates headers that force a download to happen - * - * @param string filename - * @param mixed the data to be downloaded - * @param bool whether to try and send the actual file MIME type - * @return void - */ - function force_download($filename = '', $data = '', $set_mime = FALSE) - { - if ($filename === '' OR $data === '') - { - return; - } - elseif ($data === NULL) - { - if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE) - { - return; - } - - $filepath = $filename; - $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename)); - $filename = end($filename); - } - else - { - $filesize = strlen($data); - } - - // Set the default MIME type to send - $mime = 'application/octet-stream'; - - $x = explode('.', $filename); - $extension = end($x); - - if ($set_mime === TRUE) - { - if (count($x) === 1 OR $extension === '') - { - /* If we're going to detect the MIME type, - * we'll need a file extension. - */ - return; - } - - // Load the mime types - $mimes = Factory::getInstance()->config->get('mimes')->toArray(); - - // Only change the default MIME if we can find one - if (isset($mimes[$extension])) - { - $mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension]; - } - } - - /* It was reported that browsers on Android 2.1 (and possibly older as well) - * need to have the filename extension upper-cased in order to be able to - * download it. - * - * Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/ - */ - if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT'])) - { - $x[count($x) - 1] = strtoupper($extension); - $filename = implode('.', $x); - } - - if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE) - { - return; - } - - // Clean output buffer - if (ob_get_level() !== 0 && @ob_end_clean() === FALSE) - { - @ob_clean(); - } - - // Generate the server headers - header('Content-Type: '.$mime); - header('Content-Disposition: attachment; filename="'.$filename.'"'); - header('Expires: 0'); - header('Content-Transfer-Encoding: binary'); - header('Content-Length: '.$filesize); - header('Cache-Control: private, no-transform, no-store, must-revalidate'); - - // If we have raw data - just dump it - if ($data !== NULL) - { - exit($data); - } - - // Flush 1MB chunks of data - while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE) - { - echo $data; - } - - fclose($fp); - exit; - } -} diff --git a/src/Helpers/file_helper.php b/src/Helpers/file_helper.php deleted file mode 100644 index 36fd0bd..0000000 --- a/src/Helpers/file_helper.php +++ /dev/null @@ -1,497 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks File Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/file_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('read_file')) -{ - /** - * Read File - * - * Opens the file specified in the path and returns it as a string. - * - * @todo Remove in version 3.1+. - * @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents(). - * @param string $file Path to file - * @return string File contents - */ - function read_file($file) - { - return @file_get_contents($file); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('write_file')) -{ - /** - * Write File - * - * Writes data to the file specified in the path. - * Creates a new file if non-existent. - * - * @param string $path File path - * @param string $data Data to write - * @param string $mode fopen() mode (default: 'wb') - * @return bool - */ - function write_file($path, $data, $mode = 'wb') - { - if ( ! $fp = @fopen($path, $mode)) - { - return FALSE; - } - - flock($fp, LOCK_EX); - - for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($data, $written))) === FALSE) - { - break; - } - } - - flock($fp, LOCK_UN); - fclose($fp); - - return is_int($result); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('delete_files')) -{ - /** - * Delete Files - * - * Deletes all files contained in the supplied directory path. - * Files must be writable or owned by the system in order to be deleted. - * If the second parameter is set to TRUE, any directories contained - * within the supplied base directory will be nuked as well. - * - * @param string $path File path - * @param bool $del_dir Whether to delete any directories found in the path - * @param bool $htdocs Whether to skip deleting .htaccess and index page files - * @param int $_level Current directory depth level (default: 0; internal use only) - * @return bool - */ - function delete_files($path, $del_dir = FALSE, $htdocs = FALSE, $_level = 0) - { - // Trim the trailing slash - $path = rtrim($path, '/\\'); - - if ( ! $current_dir = @opendir($path)) - { - return FALSE; - } - - while (FALSE !== ($filename = @readdir($current_dir))) - { - if ($filename !== '.' && $filename !== '..') - { - if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.') - { - delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $htdocs, $_level + 1); - } - elseif ($htdocs !== TRUE OR ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) - { - @unlink($path.DIRECTORY_SEPARATOR.$filename); - } - } - } - - closedir($current_dir); - - return ($del_dir === TRUE && $_level > 0) - ? @rmdir($path) - : TRUE; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_filenames')) -{ - /** - * Get Filenames - * - * Reads the specified directory and builds an array containing the filenames. - * Any sub-folders contained within the specified path are read as well. - * - * @param string path to source - * @param bool whether to include the path as part of the filename - * @param bool internal variable to determine recursion status - do not use in calls - * @return array - */ - function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE) - { - static $_filedata = array(); - - if ($fp = @opendir($source_dir)) - { - // reset the array and make sure $source_dir has a trailing slash on the initial call - if ($_recursion === FALSE) - { - $_filedata = array(); - $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; - } - - while (FALSE !== ($file = readdir($fp))) - { - if (is_dir($source_dir.$file) && $file[0] !== '.') - { - get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); - } - elseif ($file[0] !== '.') - { - $_filedata[] = ($include_path === TRUE) ? $source_dir.$file : $file; - } - } - - closedir($fp); - return $_filedata; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_dir_file_info')) -{ - /** - * Get Directory File Information - * - * Reads the specified directory and builds an array containing the filenames, - * filesize, dates, and permissions - * - * Any sub-folders contained within the specified path are read as well. - * - * @param string path to source - * @param bool Look only at the top level directory specified? - * @param bool internal variable to determine recursion status - do not use in calls - * @return array - */ - function get_dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE) - { - static $_filedata = array(); - $relative_path = $source_dir; - - if ($fp = @opendir($source_dir)) - { - // reset the array and make sure $source_dir has a trailing slash on the initial call - if ($_recursion === FALSE) - { - $_filedata = array(); - $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; - } - - // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast - while (FALSE !== ($file = readdir($fp))) - { - if (is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE) - { - get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE); - } - elseif ($file[0] !== '.') - { - $_filedata[$file] = get_file_info($source_dir.$file); - $_filedata[$file]['relative_path'] = $relative_path; - } - } - - closedir($fp); - return $_filedata; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_file_info')) -{ - /** - * Get File Info - * - * Given a file and path, returns the name, path, size, date modified - * Second parameter allows you to explicitly declare what information you want returned - * Options are: name, server_path, size, date, readable, writable, executable, fileperms - * Returns FALSE if the file cannot be found. - * - * @param string path to file - * @param mixed array or comma separated string of information returned - * @return array - */ - function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) - { - if ( ! file_exists($file)) - { - return FALSE; - } - - if (is_string($returned_values)) - { - $returned_values = explode(',', $returned_values); - } - - foreach ($returned_values as $key) - { - switch ($key) - { - case 'name': - $fileinfo['name'] = basename($file); - break; - case 'server_path': - $fileinfo['server_path'] = $file; - break; - case 'size': - $fileinfo['size'] = filesize($file); - break; - case 'date': - $fileinfo['date'] = filemtime($file); - break; - case 'readable': - $fileinfo['readable'] = is_readable($file); - break; - case 'writable': - $fileinfo['writable'] = is_really_writable($file); - break; - case 'executable': - $fileinfo['executable'] = is_executable($file); - break; - case 'fileperms': - $fileinfo['fileperms'] = fileperms($file); - break; - } - } - - return $fileinfo; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_mime_by_extension')) -{ - /** - * Get Mime by Extension - * - * Translates a file extension into a mime type based on config/mimes.php. - * Returns FALSE if it can't determine the type, or open the mime config file - * - * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience - * It should NOT be trusted, and should certainly NOT be used for security - * - * @param string $filename File name - * @return string - */ - function get_mime_by_extension($filename) - { - static $mimes; - - if ( ! is_array($mimes)) - { - $factory = FuzeWorks\Factory::getInstance(); - $mimes = $factory->config->get('mimes')->toArray(); - - if (empty($mimes)) - { - return FALSE; - } - } - - $extension = strtolower(substr(strrchr($filename, '.'), 1)); - - if (isset($mimes[$extension])) - { - return is_array($mimes[$extension]) - ? current($mimes[$extension]) // Multiple mime types, just give the first one - : $mimes[$extension]; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('symbolic_permissions')) -{ - /** - * Symbolic Permissions - * - * Takes a numeric value representing a file's permissions and returns - * standard symbolic notation representing that value - * - * @param int $perms Permissions - * @return string - */ - function symbolic_permissions($perms) - { - if (($perms & 0xC000) === 0xC000) - { - $symbolic = 's'; // Socket - } - elseif (($perms & 0xA000) === 0xA000) - { - $symbolic = 'l'; // Symbolic Link - } - elseif (($perms & 0x8000) === 0x8000) - { - $symbolic = '-'; // Regular - } - elseif (($perms & 0x6000) === 0x6000) - { - $symbolic = 'b'; // Block special - } - elseif (($perms & 0x4000) === 0x4000) - { - $symbolic = 'd'; // Directory - } - elseif (($perms & 0x2000) === 0x2000) - { - $symbolic = 'c'; // Character special - } - elseif (($perms & 0x1000) === 0x1000) - { - $symbolic = 'p'; // FIFO pipe - } - else - { - $symbolic = 'u'; // Unknown - } - - // Owner - $symbolic .= (($perms & 0x0100) ? 'r' : '-') - .(($perms & 0x0080) ? 'w' : '-') - .(($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); - - // Group - $symbolic .= (($perms & 0x0020) ? 'r' : '-') - .(($perms & 0x0010) ? 'w' : '-') - .(($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); - - // World - $symbolic .= (($perms & 0x0004) ? 'r' : '-') - .(($perms & 0x0002) ? 'w' : '-') - .(($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); - - return $symbolic; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('octal_permissions')) -{ - /** - * Octal Permissions - * - * Takes a numeric value representing a file's permissions and returns - * a three character string representing the file's octal permissions - * - * @param int $perms Permissions - * @return string - */ - function octal_permissions($perms) - { - return substr(sprintf('%o', $perms), -3); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_really_writable')) -{ - /** - * Tests for file writability - * - * is_writable() returns TRUE on Windows servers when you really can't write to - * the file, based on the read-only attribute. is_writable() is also unreliable - * on Unix servers if safe_mode is on. - * - * @link https://bugs.php.net/bug.php?id=54709 - * @param string - * @return bool - */ - function is_really_writable($file) - { - // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (FuzeWorks\Core::isPHP('5.4') OR ! ini_get('safe_mode'))) - { - return is_writable($file); - } - - /* For Windows servers and safe_mode "on" installations we'll actually - * write a file then read it. Bah... - */ - if (is_dir($file)) - { - $file = rtrim($file, '/').'/'.md5(mt_rand()); - if (($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - @chmod($file, 0777); - @unlink($file); - return TRUE; - } - elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - return TRUE; - } -} \ No newline at end of file diff --git a/src/Helpers/xml_helper.php b/src/Helpers/xml_helper.php deleted file mode 100644 index d7a5340..0000000 --- a/src/Helpers/xml_helper.php +++ /dev/null @@ -1,86 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks XML Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/xml_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('xml_convert')) -{ - /** - * Convert Reserved XML characters to Entities - * - * @param string - * @param bool - * @return string - */ - function xml_convert($str, $protect_all = FALSE) - { - $temp = '__TEMP_AMPERSANDS__'; - - // Replace entities to temporary markers so that - // ampersands won't get messed up - $str = preg_replace('/&#(\d+);/', $temp.'\\1;', $str); - - if ($protect_all === TRUE) - { - $str = preg_replace('/&(\w+);/', $temp.'\\1;', $str); - } - - $str = str_replace( - array('&', '<', '>', '"', "'", '-'), - array('&', '<', '>', '"', ''', '-'), - $str - ); - - // Decode the temp markers back to entities - $str = preg_replace('/'.$temp.'(\d+);/', '&#\\1;', $str); - - if ($protect_all === TRUE) - { - return preg_replace('/'.$temp.'(\w+);/', '&\\1;', $str); - } - - return $str; - } -} diff --git a/src/Language/english/db_lang.php b/src/Language/english/db_lang.php deleted file mode 100644 index c1a6e99..0000000 --- a/src/Language/english/db_lang.php +++ /dev/null @@ -1,60 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -return array( - - 'db_invalid_connection_str' => 'Unable to determine the database settings based on the connection string you submitted.', - 'db_unable_to_connect' => 'Unable to connect to your database server using the provided settings.', - 'db_unable_to_select' => 'Unable to select the specified database: %s', - 'db_unable_to_create' => 'Unable to create the specified database: %s', - 'db_invalid_query' => 'The query you submitted is not valid.', - 'db_must_set_table' => 'You must set the database table to be used with your query.', - 'db_must_use_set' => 'You must use the "set" method to update an entry.', - 'db_must_use_index' => 'You must specify an index to match on for batch updates.', - 'db_batch_missing_index' => 'One or more rows submitted for batch updating is missing the specified index.', - 'db_must_use_where' => 'Updates are not allowed unless they contain a "where" clause.', - 'db_del_must_use_where' => 'Deletes are not allowed unless they contain a "where" or "like" clause.', - 'db_field_param_missing' => 'To fetch fields requires the name of the table as a parameter.', - 'db_unsupported_function' => 'This feature is not available for the database you are using.', - 'db_transaction_failure' => 'Transaction failure: Rollback performed.', - 'db_unable_to_drop' => 'Unable to drop the specified database.', - 'db_unsupported_feature' => 'Unsupported feature of the database platform you are using.', - 'db_unsupported_compression' => 'The file compression format you chose is not supported by your server.', - 'db_filepath_error' => 'Unable to write data to the file path you have submitted.', - 'db_invalid_cache_path' => 'The cache path you submitted is not valid or writable.', - 'db_table_name_required' => 'A table name is required for that operation.', - 'db_column_name_required' => 'A column name is required for that operation.', - 'db_column_definition_required' => 'A column definition is required for that operation.', - 'db_unable_to_set_charset' => 'Unable to set client connection character set: %s', - 'db_error_heading' => 'A Database Error Occurred', - -); \ No newline at end of file diff --git a/src/Language/english/email_lang.php b/src/Language/english/email_lang.php deleted file mode 100644 index c722c4f..0000000 --- a/src/Language/english/email_lang.php +++ /dev/null @@ -1,55 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -return array ( - - 'email_must_be_array' => 'The email validation method must be passed an array.', - 'email_invalid_address' => 'Invalid email address: %s', - 'email_attachment_missing' => 'Unable to locate the following email attachment: %s', - 'email_attachment_unreadable' => 'Unable to open this attachment: %s', - 'email_no_from' => 'Cannot send mail with no "From" header.', - 'email_no_recipients' => 'You must include recipients: To, Cc, or Bcc', - 'email_send_failure_phpmail' => 'Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.', - 'email_send_failure_sendmail' => 'Unable to send email using PHP Sendmail. Your server might not be configured to send mail using this method.', - 'email_send_failure_smtp' => 'Unable to send email using PHP SMTP. Your server might not be configured to send mail using this method.', - 'email_sent' => 'Your message has been successfully sent using the following protocol: %s', - 'email_no_socket' => 'Unable to open a socket to Sendmail. Please check settings.', - 'email_no_hostname' => 'You did not specify a SMTP hostname.', - 'email_smtp_error' => 'The following SMTP error was encountered: %s', - 'email_no_smtp_unpw' => 'Error: You must assign a SMTP username and password.', - 'email_failed_smtp_login' => 'Failed to send AUTH LOGIN command. Error: %s', - 'email_smtp_auth_un' => 'Failed to authenticate username. Error: %s', - 'email_smtp_auth_pw' => 'Failed to authenticate password. Error: %s', - 'email_smtp_data_failure' => 'Unable to send data: %s', - 'email_exit_status' => 'Exit status code: %s' - -); diff --git a/src/Layout/layout.logger_cli.php b/src/Layout/layout.logger_cli.php index 778b960..a5c3ff9 100644 --- a/src/Layout/layout.logger_cli.php +++ b/src/Layout/layout.logger_cli.php @@ -1,4 +1,38 @@ assigned_variables['Logs'] as $log) { +foreach ($logs as $log) { $id++; $string = ''; @@ -70,6 +104,11 @@ foreach ($this->assigned_variables['Logs'] as $log) { $string .= getColoredString('[ERROR]', 'black', 'red') . ' - '; $string .= getColoredString($log['message'], 'black', 'red'); } + elseif ($log['type'] == 'EXCEPTION') + { + $string .= getColoredString('[EXCEPTION]', 'black', 'red') . ' - '; + $string .= getColoredString($log['message'], 'black', 'red'); + } elseif ($log['type'] == "LEVEL_STOP") { continue; diff --git a/src/Layout/layout.logger_file.php b/src/Layout/layout.logger_file.php new file mode 100644 index 0000000..aeeb559 --- /dev/null +++ b/src/Layout/layout.logger_file.php @@ -0,0 +1,49 @@ +FuzeWorks debug log'; $layer = 0; foreach ($logs as $log) { if ($log['type'] == 'LEVEL_START') { ++$layer; - $color = 255 - ($layer * 25); + $color = 255 - ($layer * 20); $string .= '
'; $string .= '
' . $log['message'] . '' . (!empty($log['runtime']) ? '(' . round($log['runtime'] * 1000, 4) . 'ms)' : '') . '
'; } elseif ($log['type'] == 'LEVEL_STOP') { --$layer; $string .= '
'; + } elseif ($log['type'] == 'EXCEPTION') { + $string .= '
[' . $log['type'] . '] ' . $log['message'] . ' + ' . (!empty($log['logFile']) ? $log['logFile'] : '') . ' : ' . (!empty($log['logLine']) ? $log['logLine'] : '') . '(' . round($log['runtime'] * 1000, 4) . ' ms)
'; + $string .= '
' . (!empty($log['context']) && is_string($log['context']) ? '[' . $log['context'] . ']' : '') . '
'; } elseif ($log['type'] == 'ERROR') { $string .= '
[' . $log['type'] . ']' . (!empty($log['context']) && is_string($log['context']) ? '[' . $log['context'] . ']' : '') . ' ' . $log['message'] . ' ' . (!empty($log['logFile']) ? $log['logFile'] : '') . ' : ' . (!empty($log['logLine']) ? $log['logLine'] : '') . '(' . round($log['runtime'] * 1000, 4) . ' ms)
'; diff --git a/src/Layout/layout.tracydatabasepanel.php b/src/Layout/layout.tracydatabasepanel.php deleted file mode 100644 index a263cd5..0000000 --- a/src/Layout/layout.tracydatabasepanel.php +++ /dev/null @@ -1,51 +0,0 @@ - - -

Queries:

- -
- - $queries): ?> - - - - - - - - - - - - - - -
Database:#
Time msSQL QueryRows
- - ERROR -
explain - -
- - - - - - - - - - -
CodeMessage
- -
-

...and more

- -
diff --git a/src/Layout/layout.tracydatabasetab.php b/src/Layout/layout.tracydatabasetab.php deleted file mode 100644 index 3a107cc..0000000 --- a/src/Layout/layout.tracydatabasetab.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Layout/layout.tracyloggerpanel.php b/src/Layout/layout.tracyloggerpanel.php deleted file mode 100644 index 79d1a19..0000000 --- a/src/Layout/layout.tracyloggerpanel.php +++ /dev/null @@ -1,46 +0,0 @@ - - -
-

Logger

- -
- - - - - - - - - - - - - - $log): ?> - - - - - - - - - - - -
#TypeMessageFileLineTiming
ms
-
-
diff --git a/src/Layout/layout.tracyloggertab.php b/src/Layout/layout.tracyloggertab.php deleted file mode 100644 index ab3145c..0000000 --- a/src/Layout/layout.tracyloggertab.php +++ /dev/null @@ -1,6 +0,0 @@ - - - - -Logger - diff --git a/src/Libraries/Cache/Cache.php b/src/Libraries/Cache/Cache.php deleted file mode 100644 index a28e2fc..0000000 --- a/src/Libraries/Cache/Cache.php +++ /dev/null @@ -1,254 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache extends FW_Driver_Library { - - /** - * Valid cache drivers - * - * @var array - */ - protected $valid_drivers = array( - 'apc', - 'dummy', - 'file', - 'memcached', - 'redis', - 'wincache' - ); - - /** - * Path of cache files (if file-based cache) - * - * @var string - */ - protected $_cache_path = NULL; - - /** - * Reference to the driver - * - * @var mixed - */ - protected $_adapter = 'dummy'; - - /** - * Fallback driver - * - * @var string - */ - protected $_backup_driver = 'dummy'; - - /** - * Cache key prefix - * - * @var string - */ - public $key_prefix = ''; - - /** - * Constructor - * - * Initialize class properties based on the configuration array. - * - * @param array $config = array() - * @return void - */ - public function __construct($config = array()) - { - isset($config['adapter']) && $this->_adapter = $config['adapter']; - isset($config['backup']) && $this->_backup_driver = $config['backup']; - isset($config['key_prefix']) && $this->key_prefix = $config['key_prefix']; - - // If the specified adapter isn't available, check the backup. - if ( ! $this->is_supported($this->_adapter)) - { - if ( ! $this->is_supported($this->_backup_driver)) - { - // Backup isn't supported either. Default to 'Dummy' driver. - Logger::logError('Cache adapter "'.$this->_adapter.'" and backup "'.$this->_backup_driver.'" are both unavailable. Cache is now using "Dummy" adapter.'); - $this->_adapter = 'dummy'; - } - else - { - // Backup is supported. Set it to primary. - Logger::logDebug('Cache adapter "'.$this->_adapter.'" is unavailable. Falling back to "'.$this->_backup_driver.'" backup adapter.'); - $this->_adapter = $this->_backup_driver; - } - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data - * if not, return FALSE - * - * @param string $id - * @return mixed value matching $id or FALSE on failure - */ - public function get($id) - { - return $this->{$this->_adapter}->get($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Cache TTL (in seconds) - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - return $this->{$this->_adapter}->save($this->key_prefix.$id, $data, $ttl, $raw); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param string $id Cache ID - * @return bool TRUE on success, FALSE on failure - */ - public function delete($id) - { - return $this->{$this->_adapter}->delete($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->{$this->_adapter}->increment($this->key_prefix.$id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->{$this->_adapter}->decrement($this->key_prefix.$id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool TRUE on success, FALSE on failure - */ - public function clean() - { - return $this->{$this->_adapter}->clean(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string $type = 'user' user/filehits - * @return mixed array containing cache info on success OR FALSE on failure - */ - public function cache_info($type = 'user') - { - return $this->{$this->_adapter}->cache_info($type); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param string $id key to get cache metadata on - * @return mixed cache item metadata - */ - public function get_metadata($id) - { - return $this->{$this->_adapter}->get_metadata($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Is the requested driver supported in this environment? - * - * @param string $driver The driver to test - * @return array - */ - public function is_supported($driver) - { - static $support; - - if ( ! isset($support, $support[$driver])) - { - $support[$driver] = $this->{$driver}->is_supported(); - } - - return $support[$driver]; - } -} diff --git a/src/Libraries/Cache/drivers/Cache_apc.php b/src/Libraries/Cache/drivers/Cache_apc.php deleted file mode 100644 index 7c12fa3..0000000 --- a/src/Libraries/Cache/drivers/Cache_apc.php +++ /dev/null @@ -1,220 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks APC Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_apc extends FW_Driver { - - /** - * Class constructor - * - * Only present so that an error message is logged - * if APC is not available. - * - * @return void - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to initialize APC; extension not loaded/enabled?'); - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data - * if not, return FALSE - * - * @param string - * @return mixed value that is stored/FALSE on failure - */ - public function get($id) - { - $success = FALSE; - $data = apc_fetch($id, $success); - - if ($success === TRUE) - { - return is_array($data) - ? unserialize($data[0]) - : $data; - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttol Length of time (in seconds) to cache the data - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - $ttl = (int) $ttl; - - return apc_store( - $id, - ($raw === TRUE ? $data : array(serialize($data), time(), $ttl)), - $ttl - ); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool true on success/false on failure - */ - public function delete($id) - { - return apc_delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return apc_inc($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return apc_dec($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return apc_clear_cache('user'); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string user/filehits - * @return mixed array on success, false on failure - */ - public function cache_info($type = NULL) - { - return apc_cache_info($type); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed array on success/false on failure - */ - public function get_metadata($id) - { - $success = FALSE; - $stored = apc_fetch($id, $success); - - if ($success === FALSE OR count($stored) !== 3) - { - return FALSE; - } - - list($data, $time, $ttl) = $stored; - - return array( - 'expire' => $time + $ttl, - 'mtime' => $time, - 'data' => unserialize($data) - ); - } - - // ------------------------------------------------------------------------ - - /** - * is_supported() - * - * Check to see if APC is available on this system, bail if it isn't. - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('apc') && ini_get('apc.enabled')); - } -} diff --git a/src/Libraries/Cache/drivers/Cache_dummy.php b/src/Libraries/Cache/drivers/Cache_dummy.php deleted file mode 100644 index a2067a7..0000000 --- a/src/Libraries/Cache/drivers/Cache_dummy.php +++ /dev/null @@ -1,170 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; - -/** - * FuzeWorks Dummy Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_dummy extends FW_Driver { - - /** - * Get - * - * Since this is the dummy class, it's always going to return FALSE. - * - * @param string - * @return bool FALSE - */ - public function get($id) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string Unique Key - * @param mixed Data to store - * @param int Length of time (in seconds) to cache the data - * @param bool Whether to store the raw value - * @return bool TRUE, Simulating success - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool TRUE, simulating success - */ - public function delete($id) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool TRUE, simulating success - */ - public function clean() - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string user/filehits - * @return bool FALSE - */ - public function cache_info($type = NULL) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return bool FALSE - */ - public function get_metadata($id) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Is this caching driver supported on the system? - * Of course this one is. - * - * @return bool TRUE - */ - public function is_supported() - { - return TRUE; - } - -} diff --git a/src/Libraries/Cache/drivers/Cache_file.php b/src/Libraries/Cache/drivers/Cache_file.php deleted file mode 100644 index cea40c1..0000000 --- a/src/Libraries/Cache/drivers/Cache_file.php +++ /dev/null @@ -1,303 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Core; - -/** - * FuzeWorks File Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_file extends FW_Driver { - - /** - * Directory in which to save cache files - * - * @var string - */ - protected $_cache_path; - - /** - * The FuzeWorks factory class - * - * @var Fuzeworks\Factory; - */ - private $factory; - - /** - * Initialize file-based cache - * - * @return void - */ - public function __construct() - { - // Load the factory - $this->factory = Factory::getInstance(); - - // Load the required helpers - $this->factory->helpers->load('file'); - $this->_cache_path = Core::$tempDir . DS . 'CacheLibrary' . DS; - } - - // ------------------------------------------------------------------------ - - /** - * Fetch from cache - * - * @param string $id Cache ID - * @return mixed Data on success, FALSE on failure - */ - public function get($id) - { - $data = $this->_get($id); - return is_array($data) ? $data['data'] : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Save into cache - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Time to live in seconds - * @param bool $raw Whether to store the raw value (unused) - * @return bool TRUE on success, FALSE on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - $contents = array( - 'time' => time(), - 'ttl' => $ttl, - 'data' => $data - ); - - if (write_file($this->_cache_path.$id, serialize($contents))) - { - chmod($this->_cache_path.$id, 0640); - return TRUE; - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of item in cache - * @return bool true on success/false on failure - */ - public function delete($id) - { - return file_exists($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return New value on success, FALSE on failure - */ - public function increment($id, $offset = 1) - { - $data = $this->_get($id); - - if ($data === FALSE) - { - $data = array('data' => 0, 'ttl' => 60); - } - elseif ( ! is_int($data['data'])) - { - return FALSE; - } - - $new_value = $data['data'] + $offset; - return $this->save($id, $new_value, $data['ttl']) - ? $new_value - : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return New value on success, FALSE on failure - */ - public function decrement($id, $offset = 1) - { - $data = $this->_get($id); - - if ($data === FALSE) - { - $data = array('data' => 0, 'ttl' => 60); - } - elseif ( ! is_int($data['data'])) - { - return FALSE; - } - - $new_value = $data['data'] - $offset; - return $this->save($id, $new_value, $data['ttl']) - ? $new_value - : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the Cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return delete_files($this->_cache_path, FALSE, TRUE); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * Not supported by file-based caching - * - * @param string user/filehits - * @return mixed FALSE - */ - public function cache_info($type = NULL) - { - return get_dir_file_info($this->_cache_path); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed FALSE on failure, array on success. - */ - public function get_metadata($id) - { - if ( ! file_exists($this->_cache_path.$id)) - { - return FALSE; - } - - $data = unserialize(file_get_contents($this->_cache_path.$id)); - - if (is_array($data)) - { - $mtime = filemtime($this->_cache_path.$id); - - if ( ! isset($data['ttl'])) - { - return FALSE; - } - - return array( - 'expire' => $mtime + $data['ttl'], - 'mtime' => $mtime - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Is supported - * - * In the file driver, check to see that the cache directory is indeed writable - * - * @return bool - */ - public function is_supported() - { - if ( ! is_dir($this->_cache_path)) - { - if (!mkdir($this->_cache_path, 0777, false)) - { - return false; - } - } - - return is_really_writable($this->_cache_path); - } - - // ------------------------------------------------------------------------ - - /** - * Get all data - * - * Internal method to get all the relevant data about a cache item - * - * @param string $id Cache ID - * @return mixed Data array on success or FALSE on failure - */ - protected function _get($id) - { - if ( ! is_file($this->_cache_path.$id)) - { - return FALSE; - } - - $data = unserialize(file_get_contents($this->_cache_path.$id)); - - if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) - { - unlink($this->_cache_path.$id); - return FALSE; - } - - return $data; - } - -} diff --git a/src/Libraries/Cache/drivers/Cache_memcached.php b/src/Libraries/Cache/drivers/Cache_memcached.php deleted file mode 100644 index 8440f67..0000000 --- a/src/Libraries/Cache/drivers/Cache_memcached.php +++ /dev/null @@ -1,301 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use Memcached; -use Memcache; - -/** - * FuzeWorks Memcached Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_memcached extends FW_Driver { - - /** - * Holds the memcached object - * - * @var object - */ - protected $_memcached; - - /** - * Memcached configuration - * - * @var array - */ - protected $_config = array( - 'default' => array( - 'host' => '127.0.0.1', - 'port' => 11211, - 'weight' => 1 - ) - ); - - // ------------------------------------------------------------------------ - - /** - * Class constructor - * - * Setup Memcache(d) - * - * @return void - */ - public function __construct() - { - // Try to load memcached server info from the config file. - $defaults = $this->_config['default']; - - $this->_config = Factory::getInstance()->config->get('cache')->memcached; - - if (class_exists('Memcached', FALSE)) - { - $this->_memcached = new Memcached(); - } - elseif (class_exists('Memcache', FALSE)) - { - $this->_memcached = new Memcache(); - } - else - { - Logger::logError('Cache: Failed to create Memcache(d) object; extension not loaded?'); - return; - } - - foreach ($this->_config as $cache_server) - { - isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; - isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; - isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; - - if ($this->_memcached instanceof Memcache) - { - // Third parameter is persistance and defaults to TRUE. - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - TRUE, - $cache_server['weight'] - ); - } - elseif ($this->_memcached instanceof Memcached) - { - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - $cache_server['weight'] - ); - } - } - } - - // ------------------------------------------------------------------------ - - /** - * Fetch from cache - * - * @param string $id Cache ID - * @return mixed Data on success, FALSE on failure - */ - public function get($id) - { - $data = $this->_memcached->get($id); - - return is_array($data) ? $data[0] : $data; - } - - // ------------------------------------------------------------------------ - - /** - * Save - * - * @param string $id Cache ID - * @param mixed $data Data being cached - * @param int $ttl Time to live - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - if ($raw !== TRUE) - { - $data = array($data, time(), $ttl); - } - - if ($this->_memcached instanceof Memcached) - { - return $this->_memcached->set($id, $data, $ttl); - } - elseif ($this->_memcached instanceof Memcache) - { - return $this->_memcached->set($id, $data, 0, $ttl); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed $id key to be deleted. - * @return bool true on success, false on failure - */ - public function delete($id) - { - return $this->_memcached->delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->_memcached->increment($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->_memcached->decrement($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the Cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return $this->_memcached->flush(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @return mixed array on success, false on failure - */ - public function cache_info() - { - return $this->_memcached->getStats(); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed $id key to get cache metadata on - * @return mixed FALSE on failure, array on success. - */ - public function get_metadata($id) - { - $stored = $this->_memcached->get($id); - - if (count($stored) !== 3) - { - return FALSE; - } - - list($data, $time, $ttl) = $stored; - - return array( - 'expire' => $time + $ttl, - 'mtime' => $time, - 'data' => $data - ); - } - - // ------------------------------------------------------------------------ - - /** - * Is supported - * - * Returns FALSE if memcached is not supported on the system. - * If it is, we setup the memcached object & return TRUE - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('memcached') OR extension_loaded('memcache')); - } - - // ------------------------------------------------------------------------ - - /** - * Class destructor - * - * Closes the connection to Memcache(d) if present. - * - * @return void - */ - public function __destruct() - { - if ($this->_memcached instanceof Memcache) - { - $this->_memcached->close(); - } - elseif ($this->_memcached instanceof Memcached) - { - $this->_memcached->quit(); - } - } -} diff --git a/src/Libraries/Cache/drivers/Cache_redis.php b/src/Libraries/Cache/drivers/Cache_redis.php deleted file mode 100644 index 365cc32..0000000 --- a/src/Libraries/Cache/drivers/Cache_redis.php +++ /dev/null @@ -1,321 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use Redis; -use RedisException; - -/** - * FuzeWorks Redis Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author Anton Lindqvist - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_redis extends FW_Driver -{ - /** - * Default config - * - * @static - * @var array - */ - protected static $_default_config = array( - 'socket_type' => 'tcp', - 'host' => '127.0.0.1', - 'password' => NULL, - 'port' => 6379, - 'timeout' => 0 - ); - - /** - * Redis connection - * - * @var Redis - */ - protected $_redis; - - /** - * An internal cache for storing keys of serialized values. - * - * @var array - */ - protected $_serialized = array(); - - // ------------------------------------------------------------------------ - - /** - * Class constructor - * - * Setup Redis - * - * Loads Redis config file if present. Will halt execution - * if a Redis connection can't be established. - * - * @return void - * @see Redis::connect() - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to create Redis object; extension not loaded?'); - return; - } - - $config = array_merge(self::$_default_config, Factory::getInstance()->config->get('cache')->redis); - - $this->_redis = new Redis(); - - try - { - if ($config['socket_type'] === 'unix') - { - $success = $this->_redis->connect($config['socket']); - } - else // tcp socket - { - $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); - } - - if ( ! $success) - { - Logger::logError('Cache: Redis connection failed. Check your configuration.'); - } - - if (isset($config['password']) && ! $this->_redis->auth($config['password'])) - { - Logger::logError('Cache: Redis authentication failed.'); - } - } - catch (RedisException $e) - { - Logger::logError('Cache: Redis connection refused ('.$e->getMessage().')'); - } - - // Initialize the index of serialized values. - $serialized = $this->_redis->sMembers('_ci_redis_serialized'); - empty($serialized) OR $this->_serialized = array_flip($serialized); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache - * - * @param string $key Cache ID - * @return mixed - */ - public function get($key) - { - $value = $this->_redis->get($key); - - if ($value !== FALSE && isset($this->_serialized[$key])) - { - return unserialize($value); - } - - return $value; - } - - // ------------------------------------------------------------------------ - - /** - * Save cache - * - * @param string $id Cache ID - * @param mixed $data Data to save - * @param int $ttl Time to live in seconds - * @param bool $raw Whether to store the raw value (unused) - * @return bool TRUE on success, FALSE on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - if (is_array($data) OR is_object($data)) - { - if ( ! $this->_redis->sIsMember('_ci_redis_serialized', $id) && ! $this->_redis->sAdd('_ci_redis_serialized', $id)) - { - return FALSE; - } - - isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE; - $data = serialize($data); - } - elseif (isset($this->_serialized[$id])) - { - $this->_serialized[$id] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $id); - } - - return $this->_redis->set($id, $data, $ttl); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from cache - * - * @param string $key Cache key - * @return bool - */ - public function delete($key) - { - if ($this->_redis->delete($key) !== 1) - { - return FALSE; - } - - if (isset($this->_serialized[$key])) - { - $this->_serialized[$key] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $key); - } - - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->_redis->incr($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->_redis->decr($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean cache - * - * @return bool - * @see Redis::flushDB() - */ - public function clean() - { - return $this->_redis->flushDB(); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache driver info - * - * @param string $type Not supported in Redis. - * Only included in order to offer a - * consistent cache API. - * @return array - * @see Redis::info() - */ - public function cache_info($type = NULL) - { - return $this->_redis->info(); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache metadata - * - * @param string $key Cache key - * @return array - */ - public function get_metadata($key) - { - $value = $this->get($key); - - if ($value !== FALSE) - { - return array( - 'expire' => time() + $this->_redis->ttl($key), - 'data' => $value - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Check if Redis driver is supported - * - * @return bool - */ - public function is_supported() - { - return extension_loaded('redis'); - } - - // ------------------------------------------------------------------------ - - /** - * Class destructor - * - * Closes the connection to Redis if present. - * - * @return void - */ - public function __destruct() - { - if ($this->_redis) - { - $this->_redis->close(); - } - } -} diff --git a/src/Libraries/Cache/drivers/Cache_wincache.php b/src/Libraries/Cache/drivers/Cache_wincache.php deleted file mode 100644 index acbc35f..0000000 --- a/src/Libraries/Cache/drivers/Cache_wincache.php +++ /dev/null @@ -1,216 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks Wincache Caching Class - * - * Converted from CodeIgniter. - * - * Read more about Wincache functions here: - * http://www.php.net/manual/en/ref.wincache.php - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author Mike Murkovic - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_wincache extends FW_Driver { - - /** - * Class constructor - * - * Only present so that an error message is logged - * if APC is not available. - * - * @return void - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to initialize Wincache; extension not loaded/enabled?'); - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data, - * if not, return FALSE - * - * @param string $id Cache Ide - * @return mixed Value that is stored/FALSE on failure - */ - public function get($id) - { - $success = FALSE; - $data = wincache_ucache_get($id, $success); - - // Success returned by reference from wincache_ucache_get() - return ($success) ? $data : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Time to live (in seconds) - * @param bool $raw Whether to store the raw value (unused) - * @return bool true on success/false on failure - */ - public function save($id, $data, $ttl = 60, $raw = FALSE) - { - return wincache_ucache_set($id, $data, $ttl); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool true on success/false on failure - */ - public function delete($id) - { - return wincache_ucache_delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - $success = FALSE; - $value = wincache_ucache_inc($id, $offset, $success); - - return ($success === TRUE) ? $value : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - $success = FALSE; - $value = wincache_ucache_dec($id, $offset, $success); - - return ($success === TRUE) ? $value : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return wincache_ucache_clear(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @return mixed array on success, false on failure - */ - public function cache_info() - { - return wincache_ucache_info(TRUE); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed array on success/false on failure - */ - public function get_metadata($id) - { - if ($stored = wincache_ucache_info(FALSE, $id)) - { - $age = $stored['ucache_entries'][1]['age_seconds']; - $ttl = $stored['ucache_entries'][1]['ttl_seconds']; - $hitcount = $stored['ucache_entries'][1]['hitcount']; - - return array( - 'expire' => $ttl - $age, - 'hitcount' => $hitcount, - 'age' => $age, - 'ttl' => $ttl - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * is_supported() - * - * Check to see if WinCache is available on this system, bail if it isn't. - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('wincache') && ini_get('wincache.ucenabled')); - } -} diff --git a/src/Libraries/Driver.php b/src/Libraries/Driver.php deleted file mode 100644 index 952fb0a..0000000 --- a/src/Libraries/Driver.php +++ /dev/null @@ -1,346 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Exception\LibraryException; -use FuzeWorks\Factory; -use FuzeWorks\Core; -use ReflectionObject; - -/** - * FuzeWorks Driver Library Class - * - * Converted from CodeIgniter. - * - * This class enables you to create "Driver" libraries that add runtime ability - * to extend the capabilities of a class via additional driver objects - * - * @package FuzeWorks - * @subpackage Libraries - * @category Libraries - * @author EllisLab Dev Team - * @license http://opensource.org/licenses/MIT MIT License - * @link - */ -class FW_Driver_Library { - - /** - * Array of drivers that are available to use with the driver class - * - * @var array - */ - protected $valid_drivers = array(); - - /** - * Name of the current class - usually the driver class - * - * @var string - */ - protected $lib_name; - - /** - * Get magic method - * - * The first time a child is used it won't exist, so we instantiate it - * subsequents calls will go straight to the proper child. - * - * @param string Child class name - * @return object Child class - */ - public function __get($child) - { - // Try to load the driver - return $this->load_driver($child); - } - - /** - * Load driver - * - * Separate load_driver call to support explicit driver load by library or user - * - * @param string Driver name (w/o parent prefix) - * @return object Child class - */ - public function load_driver($child) - { - // Get the subclass prefix - $prefix = Factory::getInstance()->config->get('main')->application_prefix; - - if ( ! isset($this->lib_name)) - { - // Get library name without any prefix - $this->lib_name = str_replace(array('FW_', $prefix), '{prefix}', get_class($this)); - } - - // Sanitize the library name - $clean_class = str_replace(array('Application\Library\\','FuzeWorks\Library\\', '{prefix}'), '', $this->lib_name); - - // The child will be prefixed with the parent lib - $child_name = $this->lib_name.'_'.$child; - - // See if requested child is a valid driver - if ( ! in_array($child, $this->valid_drivers)) - { - // The requested driver isn't valid! - $msg = 'Invalid driver requested: '.$child_name; - throw new LibraryException($msg, 1); - } - - // Get package paths and filename case variations to search - $paths = Factory::getInstance()->libraries->getLibraryPaths(); - - // Is there an extension? - $class_name = str_replace('{prefix}', $prefix, $child_name); - $found = class_exists($class_name, FALSE); - if ( ! $found) - { - // Check for subclass file - foreach ($paths as $path) - { - // Does the file exist? - $file = $path.DS.$clean_class.DS.'drivers'.DS.$prefix.$clean_class.'_'.$child.'.php'; - if (file_exists($file)) - { - // Yes - require base class from BASEPATH - $basepath = Core::$coreDir . DS. 'Libraries'.DS.$clean_class.DS.'drivers'.DS.$clean_class.'_'.$child.'.php'; - if ( ! file_exists($basepath)) - { - $msg = 'Unable to load the requested class: FW_'.$child_name; - throw new LibraryException($msg, 1); - - } - - // Include both sources and mark found - include_once($basepath); - include_once($file); - $found = TRUE; - break; - } - } - } - - // Do we need to search for the class? - if ( ! $found) - { - // Use standard class name - $class_name = str_replace('{prefix}', 'FW_', $child_name); - if ( ! class_exists($class_name, FALSE)) - { - // Check package paths - foreach ($paths as $path) - { - // Does the file exist? - $file = $path.DS.$clean_class.DS.'drivers'.DS.$clean_class.'_'.$child.'.php'; - if (file_exists($file)) - { - // Include source - include_once($file); - break; - } - } - } - } - - // Did we finally find the class? - if ( ! class_exists($class_name, FALSE)) - { - if (class_exists($child_name, FALSE)) - { - $class_name = $child_name; - } - else - { - $msg = 'Unable to load the requested driver: '.$class_name; - throw new LibraryException($msg, 1); - } - } - - // Instantiate, decorate and add child - $obj = new $class_name(); - $obj->decorate($this); - $this->$child = $obj; - return $this->$child; - } - -} - -// -------------------------------------------------------------------------- - -/** - * FuzeWorks Driver Class - * - * Converted from CodeIgniter - * - * This class enables you to create drivers for a Library based on the Driver Library. - * It handles the drivers' access to the parent library - * - * @package FuzeWorks - * @subpackage Libraries - * @category Libraries - * @author EllisLab Dev Team - * @link - */ -class FW_Driver { - - /** - * Instance of the parent class - * - * @var object - */ - protected $_parent; - - /** - * List of methods in the parent class - * - * @var array - */ - protected $_methods = array(); - - /** - * List of properties in the parent class - * - * @var array - */ - protected $_properties = array(); - - /** - * Array of methods and properties for the parent class(es) - * - * @static - * @var array - */ - protected static $_reflections = array(); - - /** - * Decorate - * - * Decorates the child with the parent driver lib's methods and properties - * - * @param object - * @return void - */ - public function decorate($parent) - { - $this->_parent = $parent; - - // Lock down attributes to what is defined in the class - // and speed up references in magic methods - - $class_name = get_class($parent); - - if ( ! isset(self::$_reflections[$class_name])) - { - $r = new ReflectionObject($parent); - - foreach ($r->getMethods() as $method) - { - if ($method->isPublic()) - { - $this->_methods[] = $method->getName(); - } - } - - foreach ($r->getProperties() as $prop) - { - if ($prop->isPublic()) - { - $this->_properties[] = $prop->getName(); - } - } - - self::$_reflections[$class_name] = array($this->_methods, $this->_properties); - } - else - { - list($this->_methods, $this->_properties) = self::$_reflections[$class_name]; - } - } - - // -------------------------------------------------------------------- - - /** - * __call magic method - * - * Handles access to the parent driver library's methods - * - * @param string - * @param array - * @return mixed - */ - public function __call($method, $args = array()) - { - if (in_array($method, $this->_methods)) - { - return call_user_func_array(array($this->_parent, $method), $args); - } - - throw new LibraryException('No such method: '.$method.'()'); - } - - // -------------------------------------------------------------------- - - /** - * __get magic method - * - * Handles reading of the parent driver library's properties - * - * @param string - * @return mixed - */ - public function __get($var) - { - if (in_array($var, $this->_properties)) - { - return $this->_parent->$var; - } - } - - // -------------------------------------------------------------------- - - /** - * __set magic method - * - * Handles writing to the parent driver library's properties - * - * @param string - * @param array - * @return mixed - */ - public function __set($var, $val) - { - if (in_array($var, $this->_properties)) - { - $this->_parent->$var = $val; - } - } - -} diff --git a/src/Libraries/Email.php b/src/Libraries/Email.php deleted file mode 100644 index 178e3f7..0000000 --- a/src/Libraries/Email.php +++ /dev/null @@ -1,2346 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Core; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use FuzeWorks\Language; - -/** - * FuzeWorks Email Class. - * - * Converted from CodeIgniter. - * - * Permits email to be sent using Mail, Sendmail, or SMTP. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Libraries - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/email.html - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Email { - - /** - * Used as the User-Agent and X-Mailer headers' value. - * - * @var string - */ - public $useragent = 'FuzeWorks'; - - /** - * Path to the Sendmail binary. - * - * @var string - */ - public $mailpath = '/usr/sbin/sendmail'; // Sendmail path - - /** - * Which method to use for sending e-mails. - * - * @var string 'mail', 'sendmail' or 'smtp' - */ - public $protocol = 'mail'; // mail/sendmail/smtp - - /** - * STMP Server host - * - * @var string - */ - public $smtp_host = ''; - - /** - * SMTP Username - * - * @var string - */ - public $smtp_user = ''; - - /** - * SMTP Password - * - * @var string - */ - public $smtp_pass = ''; - - /** - * SMTP Server port - * - * @var int - */ - public $smtp_port = 25; - - /** - * SMTP connection timeout in seconds - * - * @var int - */ - public $smtp_timeout = 5; - - /** - * SMTP persistent connection - * - * @var bool - */ - public $smtp_keepalive = FALSE; - - /** - * SMTP Encryption - * - * @var string empty, 'tls' or 'ssl' - */ - public $smtp_crypto = ''; - - /** - * Whether to apply word-wrapping to the message body. - * - * @var bool - */ - public $wordwrap = TRUE; - - /** - * Number of characters to wrap at. - * - * @see Email::$wordwrap - * @var int - */ - public $wrapchars = 76; - - /** - * Message format. - * - * @var string 'text' or 'html' - */ - public $mailtype = 'text'; - - /** - * Character set (default: utf-8) - * - * @var string - */ - public $charset = 'utf-8'; - - /** - * Multipart message - * - * @var string 'mixed' (in the body) or 'related' (separate) - */ - public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate) - - /** - * Alternative message (for HTML messages only) - * - * @var string - */ - public $alt_message = ''; - - /** - * Whether to validate e-mail addresses. - * - * @var bool - */ - public $validate = FALSE; - - /** - * X-Priority header value. - * - * @var int 1-5 - */ - public $priority = 3; // Default priority (1 - 5) - - /** - * Newline character sequence. - * Use "\r\n" to comply with RFC 822. - * - * @link http://www.ietf.org/rfc/rfc822.txt - * @var string "\r\n" or "\n" - */ - public $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822) - - /** - * CRLF character sequence - * - * RFC 2045 specifies that for 'quoted-printable' encoding, - * "\r\n" must be used. However, it appears that some servers - * (even on the receiving end) don't handle it properly and - * switching to "\n", while improper, is the only solution - * that seems to work for all environments. - * - * @link http://www.ietf.org/rfc/rfc822.txt - * @var string - */ - public $crlf = "\n"; - - /** - * Whether to use Delivery Status Notification. - * - * @var bool - */ - public $dsn = FALSE; - - /** - * Whether to send multipart alternatives. - * Yahoo! doesn't seem to like these. - * - * @var bool - */ - public $send_multipart = TRUE; - - /** - * Whether to send messages to BCC recipients in batches. - * - * @var bool - */ - public $bcc_batch_mode = FALSE; - - /** - * BCC Batch max number size. - * - * @see Email::$bcc_batch_mode - * @var int - */ - public $bcc_batch_size = 200; - - // -------------------------------------------------------------------- - - /** - * Whether PHP is running in safe mode. Initialized by the class constructor. - * - * @var bool - */ - protected $_safe_mode = FALSE; - - /** - * Subject header - * - * @var string - */ - protected $_subject = ''; - - /** - * Message body - * - * @var string - */ - protected $_body = ''; - - /** - * Final message body to be sent. - * - * @var string - */ - protected $_finalbody = ''; - - /** - * multipart/alternative boundary - * - * @var string - */ - protected $_alt_boundary = ''; - - /** - * Attachment boundary - * - * @var string - */ - protected $_atc_boundary = ''; - - /** - * Final headers to send - * - * @var string - */ - protected $_header_str = ''; - - /** - * SMTP Connection socket placeholder - * - * @var resource - */ - protected $_smtp_connect = ''; - - /** - * Mail encoding - * - * @var string '8bit' or '7bit' - */ - protected $_encoding = '8bit'; - - /** - * Whether to perform SMTP authentication - * - * @var bool - */ - protected $_smtp_auth = FALSE; - - /** - * Whether to send a Reply-To header - * - * @var bool - */ - protected $_replyto_flag = FALSE; - - /** - * Debug messages - * - * @see Email::print_debugger() - * @var string - */ - protected $_debug_msg = array(); - - /** - * Recipients - * - * @var string[] - */ - protected $_recipients = array(); - - /** - * CC Recipients - * - * @var string[] - */ - protected $_cc_array = array(); - - /** - * BCC Recipients - * - * @var string[] - */ - protected $_bcc_array = array(); - - /** - * Message headers - * - * @var string[] - */ - protected $_headers = array(); - - /** - * Attachment data - * - * @var array - */ - protected $_attachments = array(); - - /** - * Valid $protocol values - * - * @see Email::$protocol - * @var string[] - */ - protected $_protocols = array('mail', 'sendmail', 'smtp'); - - /** - * Base charsets - * - * Character sets valid for 7-bit encoding, - * excluding language suffix. - * - * @var string[] - */ - protected $_base_charsets = array('us-ascii', 'iso-2022-'); - - /** - * Bit depths - * - * Valid mail encodings - * - * @see Email::$_encoding - * @var string[] - */ - protected $_bit_depths = array('7bit', '8bit'); - - /** - * $priority translations - * - * Actual values to send with the X-Priority header - * - * @var string[] - */ - protected $_priorities = array( - 1 => '1 (Highest)', - 2 => '2 (High)', - 3 => '3 (Normal)', - 4 => '4 (Low)', - 5 => '5 (Lowest)' - ); - - // -------------------------------------------------------------------- - - /** - * Constructor - Sets Email Preferences - * - * The constructor can be passed an array of config values - * - * @param array $config = array() - * @return void - */ - public function __construct(array $config = array()) - { - $this->charset = Factory::getInstance()->config->get('main')->charset; - - if (count($config) > 0) - { - $this->initialize($config); - } - else - { - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - } - - $this->_safe_mode = ( ! Core::isPHP('5.4') && ini_get('safe_mode')); - $this->charset = strtoupper($this->charset); - - Logger::log('Email Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Destructor - Releases Resources - * - * @return void - */ - public function __destruct() - { - if (is_resource($this->_smtp_connect)) - { - $this->_send_command('quit'); - } - } - - // -------------------------------------------------------------------- - - /** - * Initialize preferences - * - * @param array - * @return Email - */ - public function initialize($config = array()) - { - foreach ($config as $key => $val) - { - if (isset($this->$key)) - { - $method = 'set_'.$key; - - if (method_exists($this, $method)) - { - $this->$method($val); - } - else - { - $this->$key = $val; - } - } - } - $this->clear(); - - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Email Data - * - * @param bool - * @return Email - */ - public function clear($clear_attachments = FALSE) - { - $this->_subject = ''; - $this->_body = ''; - $this->_finalbody = ''; - $this->_header_str = ''; - $this->_replyto_flag = FALSE; - $this->_recipients = array(); - $this->_cc_array = array(); - $this->_bcc_array = array(); - $this->_headers = array(); - $this->_debug_msg = array(); - - $this->set_header('User-Agent', $this->useragent); - $this->set_header('Date', $this->_set_date()); - - if ($clear_attachments !== FALSE) - { - $this->_attachments = array(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set FROM - * - * @param string $from - * @param string $name - * @param string $return_path = NULL Return-Path - * @return Email - */ - public function from($from, $name = '', $return_path = NULL) - { - if (preg_match('/\<(.*)\>/', $from, $match)) - { - $from = $match[1]; - } - - if ($this->validate) - { - $this->validate_email($this->_str_to_array($from)); - if ($return_path) - { - $this->validate_email($this->_str_to_array($return_path)); - } - } - - // prepare the display name - if ($name !== '') - { - // only use Q encoding if there are characters that would require it - if ( ! preg_match('/[\200-\377]/', $name)) - { - // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes - $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; - } - else - { - $name = $this->_prep_q_encoding($name); - } - } - - $this->set_header('From', $name.' <'.$from.'>'); - - isset($return_path) OR $return_path = $from; - $this->set_header('Return-Path', '<'.$return_path.'>'); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Reply-to - * - * @param string - * @param string - * @return Email - */ - public function reply_to($replyto, $name = '') - { - if (preg_match('/\<(.*)\>/', $replyto, $match)) - { - $replyto = $match[1]; - } - - if ($this->validate) - { - $this->validate_email($this->_str_to_array($replyto)); - } - - if ($name !== '') - { - // only use Q encoding if there are characters that would require it - if ( ! preg_match('/[\200-\377]/', $name)) - { - // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes - $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; - } - else - { - $name = $this->_prep_q_encoding($name); - } - } - - $this->set_header('Reply-To', $name.' <'.$replyto.'>'); - $this->_replyto_flag = TRUE; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Recipients - * - * @param string - * @return Email - */ - public function to($to) - { - $to = $this->_str_to_array($to); - $to = $this->clean_email($to); - - if ($this->validate) - { - $this->validate_email($to); - } - - if ($this->_get_protocol() !== 'mail') - { - $this->set_header('To', implode(', ', $to)); - } - - $this->_recipients = $to; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set CC - * - * @param string - * @return Email - */ - public function cc($cc) - { - $cc = $this->clean_email($this->_str_to_array($cc)); - - if ($this->validate) - { - $this->validate_email($cc); - } - - $this->set_header('Cc', implode(', ', $cc)); - - if ($this->_get_protocol() === 'smtp') - { - $this->_cc_array = $cc; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set BCC - * - * @param string - * @param string - * @return Email - */ - public function bcc($bcc, $limit = '') - { - if ($limit !== '' && is_numeric($limit)) - { - $this->bcc_batch_mode = TRUE; - $this->bcc_batch_size = $limit; - } - - $bcc = $this->clean_email($this->_str_to_array($bcc)); - - if ($this->validate) - { - $this->validate_email($bcc); - } - - if ($this->_get_protocol() === 'smtp' OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size)) - { - $this->_bcc_array = $bcc; - } - else - { - $this->set_header('Bcc', implode(', ', $bcc)); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Email Subject - * - * @param string - * @return Email - */ - public function subject($subject) - { - $subject = $this->_prep_q_encoding($subject); - $this->set_header('Subject', $subject); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Body - * - * @param string - * @return Email - */ - public function message($body) - { - $this->_body = rtrim(str_replace("\r", '', $body)); - - /* strip slashes only if magic quotes is ON - if we do it with magic quotes OFF, it strips real, user-inputted chars. - - NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. - */ - if ( ! Core::isPHP('5.4') && get_magic_quotes_gpc()) - { - $this->_body = stripslashes($this->_body); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Assign file attachments - * - * @param string $file Can be local path, URL or buffered content - * @param string $disposition = 'attachment' - * @param string $newname = NULL - * @param string $mime = '' - * @return Email - */ - public function attach($file, $disposition = '', $newname = NULL, $mime = '') - { - if ($mime === '') - { - if (strpos($file, '://') === FALSE && ! file_exists($file)) - { - $this->_set_error_message('lang:email_attachment_missing', $file); - return FALSE; - } - - if ( ! $fp = @fopen($file, 'rb')) - { - $this->_set_error_message('lang:email_attachment_unreadable', $file); - return FALSE; - } - - $file_content = stream_get_contents($fp); - $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); - fclose($fp); - } - else - { - $file_content =& $file; // buffered file - } - - $this->_attachments[] = array( - 'name' => array($file, $newname), - 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters - 'type' => $mime, - 'content' => chunk_split(base64_encode($file_content)) - ); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set and return attachment Content-ID - * - * Useful for attached inline pictures - * - * @param string $filename - * @return string - */ - public function attachment_cid($filename) - { - if ($this->multipart !== 'related') - { - $this->multipart = 'related'; // Thunderbird need this for inline images - } - - for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) - { - if ($this->_attachments[$i]['name'][0] === $filename) - { - $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); - return $this->_attachments[$i]['cid']; - } - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Add a Header Item - * - * @param string - * @param string - * @return Email - */ - public function set_header($header, $value) - { - $this->_headers[$header] = str_replace(array("\n", "\r"), '', $value); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Convert a String to an Array - * - * @param string - * @return array - */ - protected function _str_to_array($email) - { - if ( ! is_array($email)) - { - return (strpos($email, ',') !== FALSE) - ? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY) - : (array) trim($email); - } - - return $email; - } - - // -------------------------------------------------------------------- - - /** - * Set Multipart Value - * - * @param string - * @return Email - */ - public function set_alt_message($str) - { - $this->alt_message = (string) $str; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Mailtype - * - * @param string - * @return Email - */ - public function set_mailtype($type = 'text') - { - $this->mailtype = ($type === 'html') ? 'html' : 'text'; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Wordwrap - * - * @param bool - * @return Email - */ - public function set_wordwrap($wordwrap = TRUE) - { - $this->wordwrap = (bool) $wordwrap; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Protocol - * - * @param string - * @return Email - */ - public function set_protocol($protocol = 'mail') - { - $this->protocol = in_array($protocol, $this->_protocols, TRUE) ? strtolower($protocol) : 'mail'; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Priority - * - * @param int - * @return Email - */ - public function set_priority($n = 3) - { - $this->priority = preg_match('/^[1-5]$/', $n) ? (int) $n : 3; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Newline Character - * - * @param string - * @return Email - */ - public function set_newline($newline = "\n") - { - $this->newline = in_array($newline, array("\n", "\r\n", "\r")) ? $newline : "\n"; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set CRLF - * - * @param string - * @return Email - */ - public function set_crlf($crlf = "\n") - { - $this->crlf = ($crlf !== "\n" && $crlf !== "\r\n" && $crlf !== "\r") ? "\n" : $crlf; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Message Boundary - * - * @return void - */ - protected function _set_boundaries() - { - $this->_alt_boundary = 'B_ALT_'.uniqid(''); // multipart/alternative - $this->_atc_boundary = 'B_ATC_'.uniqid(''); // attachment boundary - } - - // -------------------------------------------------------------------- - - /** - * Get the Message ID - * - * @return string - */ - protected function _get_message_id() - { - $from = str_replace(array('>', '<'), '', $this->_headers['Return-Path']); - return '<'.uniqid('').strstr($from, '@').'>'; - } - - // -------------------------------------------------------------------- - - /** - * Get Mail Protocol - * - * @param bool - * @return mixed - */ - protected function _get_protocol($return = TRUE) - { - $this->protocol = strtolower($this->protocol); - in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail'; - - if ($return === TRUE) - { - return $this->protocol; - } - } - - // -------------------------------------------------------------------- - - /** - * Get Mail Encoding - * - * @param bool - * @return string - */ - protected function _get_encoding($return = TRUE) - { - in_array($this->_encoding, $this->_bit_depths) OR $this->_encoding = '8bit'; - - foreach ($this->_base_charsets as $charset) - { - if (strpos($charset, $this->charset) === 0) - { - $this->_encoding = '7bit'; - } - } - - if ($return === TRUE) - { - return $this->_encoding; - } - } - - // -------------------------------------------------------------------- - - /** - * Get content type (text/html/attachment) - * - * @return string - */ - protected function _get_content_type() - { - if ($this->mailtype === 'html') - { - return (count($this->_attachments) === 0) ? 'html' : 'html-attach'; - } - elseif ($this->mailtype === 'text' && count($this->_attachments) > 0) - { - return 'plain-attach'; - } - else - { - return 'plain'; - } - } - - // -------------------------------------------------------------------- - - /** - * Set RFC 822 Date - * - * @return string - */ - protected function _set_date() - { - $timezone = date('Z'); - $operator = ($timezone[0] === '-') ? '-' : '+'; - $timezone = abs($timezone); - $timezone = floor($timezone/3600) * 100 + ($timezone % 3600) / 60; - - return sprintf('%s %s%04d', date('D, j M Y H:i:s'), $operator, $timezone); - } - - // -------------------------------------------------------------------- - - /** - * Mime message - * - * @return string - */ - protected function _get_mime_message() - { - return 'This is a multi-part message in MIME format.'.$this->newline.'Your email application may not support this format.'; - } - - // -------------------------------------------------------------------- - - /** - * Validate Email Address - * - * @param string - * @return bool - */ - public function validate_email($email) - { - if ( ! is_array($email)) - { - $this->_set_error_message('lang:email_must_be_array'); - return FALSE; - } - - foreach ($email as $val) - { - if ( ! $this->valid_email($val)) - { - $this->_set_error_message('lang:email_invalid_address', $val); - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Email Validation - * - * @param string - * @return bool - */ - public function valid_email($email) - { - if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@')) - { - $email = substr($email, 0, ++$atpos).idn_to_ascii(substr($email, $atpos)); - } - - return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); - } - - // -------------------------------------------------------------------- - - /** - * Clean Extended Email Address: Joe Smith - * - * @param string - * @return string - */ - public function clean_email($email) - { - if ( ! is_array($email)) - { - return preg_match('/\<(.*)\>/', $email, $match) ? $match[1] : $email; - } - - $clean_email = array(); - - foreach ($email as $addy) - { - $clean_email[] = preg_match('/\<(.*)\>/', $addy, $match) ? $match[1] : $addy; - } - - return $clean_email; - } - - // -------------------------------------------------------------------- - - /** - * Build alternative plain text message - * - * Provides the raw message for use in plain-text headers of - * HTML-formatted emails. - * If the user hasn't specified his own alternative message - * it creates one by stripping the HTML - * - * @return string - */ - protected function _get_alt_message() - { - if ( ! empty($this->alt_message)) - { - return ($this->wordwrap) - ? $this->word_wrap($this->alt_message, 76) - : $this->alt_message; - } - - $body = preg_match('/\(.*)\<\/body\>/si', $this->_body, $match) ? $match[1] : $this->_body; - $body = str_replace("\t", '', preg_replace('#\n"; - - $this->assertEquals( - $this->_output_data.$append, - $this->output - ->set_output($this->_output_data) - ->append_output("\n") - ->get_output() - ); - } - - // -------------------------------------------------------------------- - - public function test_get_content_type() - { - $this->assertEquals('text/html', $this->output->get_content_type()); - } - - // -------------------------------------------------------------------- - - public function test_get_header() - { - $this->assertNull($this->output->get_header('Non-Existent-Header')); - - // TODO: Find a way to test header() values as well. Currently, - // PHPUnit prevents this by not using output buffering. - - $this->output->set_content_type('text/plain', 'WINDOWS-1251'); - $this->assertEquals( - 'text/plain; charset=WINDOWS-1251', - $this->output->get_header('content-type') - ); - } - -} diff --git a/tests/core/core_pluginsTest.php b/tests/core/core_pluginsTest.php deleted file mode 100644 index b43e5f0..0000000 --- a/tests/core/core_pluginsTest.php +++ /dev/null @@ -1,176 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.4 - * - * @version Version 1.1.4 - */ - -use FuzeWorks\Factory; -use FuzeWorks\Plugins; - -/** - * Class PluginsTest. - * - * Plugins testing suite, will test basic loading of and management of Plugins - */ -class pluginTest extends CoreTestAbstract -{ - - protected $plugins; - - public function setUp() - { - $this->plugins = new Plugins(); - $this->plugins->addPluginPath('tests'.DS.'plugins'); - $this->plugins->loadHeaders(); - } - - public function testGetPluginsClass() - { - $this->assertInstanceOf('FuzeWorks\Plugins', $this->plugins); - } - - /** - * @depends testGetPluginsClass - */ - public function testLoadPlugin() - { - $this->assertInstanceOf('\Application\Plugin\TestLoadPlugin', $this->plugins->get('testLoadPlugin')); - } - - /** - * @depends testLoadPlugin - */ - public function testReloadPlugin() - { - $this->assertSame($this->plugins->get('testReloadPlugin'), $this->plugins->get('testReloadPlugin')); - } - - /** - * @depends testLoadPlugin - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testMissingHeader() - { - $this->plugins->get('testMissingHeader'); - } - - /** - * @depends testLoadPlugin - */ - public function testGetPluginMethod() - { - $this->assertEquals('test_string', $this->plugins->get('testGetPluginMethod')); - } - - /** - * @depends testLoadPlugin - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testMissingPlugin() - { - $this->plugins->get('testMissingPlugin'); - } - - /** - * @depends testLoadPlugin - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testInvalidClass() - { - $this->plugins->get('testInvalidClass'); - } - - /** - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testGetMissingName() - { - $this->plugins->get(''); - } - - /** - * @depends testLoadPlugin - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testDisabledPlugin() - { - Factory::getInstance()->config->plugins->disabled_plugins = array('TestDisabledPlugin'); - $this->plugins->loadHeaders(); - $this->plugins->get('testDisabledPlugin'); - } - - /** - * @depends testLoadPlugin - * @expectedException FuzeWorks\Exception\PluginException - */ - public function testRunInvalidDirectory() - { - $this->plugins->addPluginPath('exists_not'); - $this->plugins->loadHeaders(); - $this->plugins->get('testRunInvalidDirectory'); - } - - public function testAddPluginPath() - { - // Add the pluginPath - $this->plugins->addPluginPath('tests'.DS.'plugins'.DS.'testAddPluginPath'); - - // And try to load it again - $this->plugins->loadHeaders(); - $this->assertInstanceOf('Application\Plugin\ActualPlugin', $this->plugins->get('ActualPlugin')); - } - - /** - * @depends testAddPluginPath - */ - public function testRemovePluginPath() - { - // Test if the path does NOT exist - $this->assertFalse(in_array('tests'.DS.'plugins'.DS.'testRemovePluginPath', $this->plugins->getPluginPaths())); - - // Add it - $this->plugins->addPluginPath('tests'.DS.'plugins'.DS.'testRemovePluginPath'); - - // Assert if it's there - $this->assertTrue(in_array('tests'.DS.'plugins'.DS.'testRemovePluginPath', $this->plugins->getPluginPaths())); - - // Remove it - $this->plugins->removePluginPath('tests'.DS.'plugins'.DS.'testRemovePluginPath'); - - // And test if it's gone again - $this->assertFalse(in_array('tests'.DS.'plugins'.DS.'testRemovePluginPath', $this->plugins->getPluginPaths())); - } - - public function tearDown() - { - $factory = Factory::getInstance(); - $factory->config->plugins->revert(); - } - -} diff --git a/tests/core/core_routerTest.php b/tests/core/core_routerTest.php deleted file mode 100644 index 702552a..0000000 --- a/tests/core/core_routerTest.php +++ /dev/null @@ -1,500 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.2 - * - * @version Version 1.1.2 - */ - -use FuzeWorks\Router; -use FuzeWorks\Factory; -use FuzeWorks\Core; -use FuzeWorks\Logger; - -/** - * Class RouterTest. - * - * Core testing suite, will test basic core functionality of the FuzeWorks Router - */ -class routerTest extends CoreTestAbstract -{ - - protected $router; - - public function setUp() - { - $this->router = new Router(); - $this->router->setControllerDirectory('tests'.DS.'controller'); - } - - public function testGetRouterClass() - { - $this->assertInstanceOf('FuzeWorks\Router', $this->router); - } - - public function testGetSetRouterDirectory() - { - $directory = 'tests' . DS . 'controller'; - $this->router->setControllerDirectory($directory); - $this->assertEquals($directory, $this->router->getControllerDirectory($directory)); - } - - /* Route Parsing ------------------------------------------------------ */ - - /** - * @depends testGetRouterClass - */ - public function testAddRoutes() - { - $this->router->addRoute('testRoute', function(){}); - $this->assertArrayHasKey('testRoute', $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testAppendRoutes() - { - $testRouteFunction = array(function(){}); - $testAppendRouteFunction = array(function(){}); - $this->router->addRoute('testRoute', $testRouteFunction); - $this->router->addRoute('testAppendRoute', $testAppendRouteFunction, false); - - // Test if the order is correct - $this->assertSame(array('testRoute' => $testRouteFunction, 'testAppendRoute' => $testAppendRouteFunction), $this->router->getRoutes()); - - // Test if the order is not incorrect - $this->assertNotSame(array('testAppendRoute' => $testAppendRouteFunction,'testRoute' => $testRouteFunction), $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testRemoveRoutes() - { - // First add - $this->router->addRoute('testRemoveRoute', function(){}); - $this->assertArrayHasKey('testRemoveRoute', $this->router->getRoutes()); - - // Then remove - $this->router->removeRoute('testRemoveRoute'); - $this->assertArrayNotHasKey('testRemoveRoute', $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testParseRouting() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testParseRouting'} = function(){}; - $this->router = new Router(); - - // Now verify whether the passing has gone correctly - $this->assertArrayHasKey('testParseRouting', $this->router->getRoutes()); - } - - /** - * @depends testParseRouting - */ - public function testVerbParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $getFunction = function($get){}; - $postFunction = function($post){}; - $config->routes->{'testVerbPassing'} = array('GET' => $getFunction, 'POST' => $postFunction); - $this->router = new Router(); - - // Now verify whether the passing has gone correctly - $routes = $this->router->getRoutes(); - $this->assertArrayHasKey('testVerbPassing', $routes); - $this->assertSame($getFunction, $routes['testVerbPassing']); - $this->assertNotSame($postFunction, $routes['testVerbPassing']); - } - - /** - * @depends testVerbParsing - */ - public function testInvalidParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testInvalidParsing'} = array('NOTGET' => function(){}); - $this->router = new Router(); - - // Now verify whether the route has been skipped - $this->assertArrayNotHasKey('testInvalidParsing', $this->router->getRoutes()); - } - - /** - * @depends testVerbParsing - */ - public function testWildcardsParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testWildcardsParsing/:any/:num'} = function(){}; - $this->router = new Router(); - - // Now verify whether the route has been skipped - $this->assertArrayHasKey('testWildcardsParsing/[^/]+/[0-9]+', $this->router->getRoutes()); - } - - /* defaultCallable() -------------------------------------------------- */ - - /** - * @depends testGetRouterClass - */ - public function testDefaultCallable() - { - // First set the segments, callable and the route - $arguments = array('controller' => 'TestDefaultCallable', 'function' => 'index'); - - // Verify that the controller is found and loaded - $this->assertTrue($this->router->defaultCallable($arguments)); - $this->assertInstanceOf('\Application\Controller\TestDefaultCallable', $this->router->getCallable()); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableMissingMethod() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableMissingMethod', 'function' => 'missing'); - - // Verify that the method is not found - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableMissingController() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableMissingController', 'function' => 'index'); - - // Verify that the controller is not found - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableHalt() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableHalt', 'function' => 'index'); - - // Verify that the controller is halted - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ - - /* route() ------------------------------------------------------------ */ - - /** - * @depends testGetRouterClass - */ - public function testRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testRoute'); - $this->router->addRoute('testRoute', function(){}); - - // Perform verification - $this->assertFalse($this->router->route(false)); - $this->assertContains('testRoute', $this->router->getMatches()); - } - - /** - * @depends testRoute - */ - public function testRouteDefaultRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Perform verification - $this->assertFalse($this->router->route(false)); - $this->assertEmpty($this->router->getMatches()); - } - - /** - * @depends testRoute - */ - public function testArrayRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testArrayRoute'); - $this->router->addRoute('testArrayRoute', array('callable' => function(){})); - - // Perform verification - $this->assertTrue($this->router->route(false)); - $this->assertContains('testArrayRoute', $this->router->getMatches()); - } - - /* -------------------------------------------------------------------- */ - - /* loadCallable() ----------------------------------------------------- */ - - /** - * @depends testArrayRoute - */ - public function testLoadCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallable'); - $callable = function($arg){$this->assertEquals('testLoadCallable', $arg[0]);return true;}; - $this->router->addRoute('testLoadCallable', array('callable' => $callable)); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertSame($callable, $this->router->getCallable()); - } - - /** - * @depends testLoadCallable - */ - public function testLoadCallableNotCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableNotCallable'); - $this->router->addRoute('testLoadCallableNotCallable', array('callable' => 'notCallable')); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertSame('notCallable', $this->router->getCallable()); - $this->assertEquals(500, Core::$http_status_code); - } - - /** - * @depends testLoadCallable - */ - public function testLoadCallableToDefaultCallabe() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableToDefaultCallable'); - $this->router->addRoute('testLoadCallableToDefaultCallable', array('callable' => array('controller' => 'TestLoadCallableToDefaultCallable', 'function' => 'index', 'parameters' => null))); - - // Perform verification - $this->assertTrue($this->router->route(true)); - } - - public function testLoadCallableUnsatisfiedCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableUnsatisfiedCallable'); - $this->router->addRoute('testLoadCallableUnsatisfiedCallable', array('callable' => function() {return false;} )); - - // Perform verification - $this->assertTrue($this->router->route(true)); - } - - /* -------------------------------------------------------------------- */ - - /* routeDefault() ----------------------------------------------------- */ - - /** - * @depends testLoadCallable - */ - public function testRouteDefault() - { - // First testing the default route without any segments - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Change the default controller so it is easier to test - $config = Factory::getInstance()->config; - $config->routing->default_controller = 'testRouteDefault'; - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testRouteDefault - */ - public function testRouteDefaultUriDashes() - { - // First testing the default route without any segments - $uri = Factory::getInstance()->uri; - - // Change the default controller so URI Dashes get translated - $config = Factory::getInstance()->config; - $config->routing->translate_uri_dashes = TRUE; - - // Perform verification, first test should fail - $uri->segments = array('test-Route-Default-Uri-Dashes-Fail'); - $this->assertTrue($this->router->route(true)); - $this->assertEquals(404, Core::$http_status_code); - - // Reset the HTTP status code - Core::$http_status_code = 200; - - // Next test should succeed - $uri->segments = array('test-Route-Default-Uri-Dashes-Succeed', 'dashed-method'); - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ - - /* Simulation tests --------------------------------------------------- */ - - /** - * @depends testLoadCallable - */ - public function testLoadController() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadController'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testLoadStandardController() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testControllerNotFound() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('controllerNotFound'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testMatchingRoute() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('methodInFirstArgument', 'testMatchingRoute'); - - // Create a custom route - $this->router->addRoute('^(?P.*?)(|\/(?P.*?)(|\/(?P.*?)))$', array('callable' => array($this->router, 'defaultCallable'))); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testStaticRoute() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('staticKey'); - - // Create a static route - $this->router->addRoute('staticKey', 'standard/index'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testCustomCallable() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('customCallable'); - - // Create a custom callable - $this->router->addRoute('customCallable', array('callable' => function($arguments){ - return true; - } )); - - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testCustomRewriteCallable() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('customRewriteCallable'); - - // Create a custom callable - $this->router->addRoute('customRewriteCallable', function($arguments = array()){ - return 'standard/index'; - }); - - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ -} diff --git a/tests/core/core_securityTest.php b/tests/core/core_securityTest.php deleted file mode 100644 index d535233..0000000 --- a/tests/core/core_securityTest.php +++ /dev/null @@ -1,386 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class SecurityTest. - * - * Core testing suite, will test security class functionality - */ -class securityTest extends CoreTestAbstract -{ - - public function setUp() - { - // Set cookie for security test - $_COOKIE['fw_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE)); - - // Set config for Security class - $config = Factory::getInstance()->config->getConfig('security'); - - $config->csrf_protection = true; - $config->csrf_token_name = 'fw_csrf_token'; - $config->csrf_cookie_name = 'fw_csrf_cookie'; - - $this->security = new Mock_Core_Security(); - } - - // -------------------------------------------------------------------- - - public function test_csrf_verify() - { - $_SERVER['REQUEST_METHOD'] = 'GET'; - - $this->assertInstanceOf('FuzeWorks\Security', $this->security->csrf_verify()); - } - - // -------------------------------------------------------------------- - - /** - * @expectedException FuzeWorks\Exception\SecurityException - */ - public function test_csrf_verify_invalid() - { - // Without issuing $_POST[csrf_token_name], this request will triggering CSRF error - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $this->security->csrf_verify(); - } - - // -------------------------------------------------------------------- - - public function test_csrf_verify_valid() - { - $_SERVER['REQUEST_METHOD'] = 'POST'; - $_POST[$this->security->csrf_token_name] = $this->security->csrf_hash; - - $this->assertInstanceOf('FuzeWorks\Security', $this->security->csrf_verify()); - } - - // -------------------------------------------------------------------- - - public function test_get_csrf_hash() - { - $this->assertEquals($this->security->csrf_hash, $this->security->get_csrf_hash()); - } - - // -------------------------------------------------------------------- - - public function test_get_csrf_token_name() - { - $this->assertEquals('fw_csrf_token', $this->security->get_csrf_token_name()); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean() - { - $harm_string = "Hello, i try to your site"; - - $harmless_string = $this->security->xss_clean($harm_string); - - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_string); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_string_array() - { - $harm_strings = array( - "Hello, i try to your site", - "Simple clean string", - "Hello, i try to your site" - ); - - $harmless_strings = $this->security->xss_clean($harm_strings); - - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_strings[0]); - $this->assertEquals("Simple clean string", $harmless_strings[1]); - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_strings[2]); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_image_valid() - { - $harm_string = ''; - - $xss_clean_return = $this->security->xss_clean($harm_string, TRUE); - - $this->assertTrue($xss_clean_return); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_image_invalid() - { - $harm_string = ''; - - $xss_clean_return = $this->security->xss_clean($harm_string, TRUE); - - $this->assertFalse($xss_clean_return); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_entity_double_encoded() - { - $input = '
Clickhere'; - $this->assertEquals('Clickhere', $this->security->xss_clean($input)); - } - - // -------------------------------------------------------------------- - - public function text_xss_clean_js_link_removal() - { - // This one is to prevent a false positive - $this->assertEquals( - "", - $this->security->xss_clean("") - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_js_img_removal() - { - $input = 'Clickhere'; - $this->assertEquals('', $this->security->xss_clean($input)); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_sanitize_naughty_html_tags() - { - $this->assertEquals('<unclosedTag', $this->security->xss_clean('assertEquals('<blink>', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - - $this->assertEquals( - ' src="x">', - $this->security->xss_clean(' src="x">') - ); - - $this->assertEquals( - 'on=">"x onerror="alert(1)">', - $this->security->xss_clean('on=">"x onerror="alert(1)">') - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_sanitize_naughty_html_attributes() - { - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('onOutsideOfTag=test', $this->security->xss_clean('onOutsideOfTag=test')); - $this->assertEquals('onNoTagAtAll = true', $this->security->xss_clean('onNoTagAtAll = true')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - - $this->assertEquals( - '\' xss=removed>', - $this->security->xss_clean('\' onAfterGreaterThan="quotes">') - ); - $this->assertEquals( - '\' xss=removed>', - $this->security->xss_clean('\' onAfterGreaterThan=noQuotes>') - ); - - $this->assertEquals( - ' on=<svg> onerror=alert(1)>', - $this->security->xss_clean(' on= onerror=alert(1)>') - ); - - $this->assertEquals( - '"<svg> onerror=alert(1) onmouseover=alert(1)>', - $this->security->xss_clean('" onerror=alert(1) onmouseover=alert(1)>') - ); - - $this->assertEquals( - ' on=\'x\' onerror=``,alert(1)>', - $this->security->xss_clean(' on=\'x\' onerror=``,alert(1)>') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - ' on=\'x\' onerror=,xssm()>', - $this->security->xss_clean(' on=\'x\' onerror=,xssm()>') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '1">', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - } - - // -------------------------------------------------------------------- - - /** - * @depends test_xss_clean_sanitize_naughty_html_tags - * @depends test_xss_clean_sanitize_naughty_html_attributes - */ - public function test_naughty_html_plus_evil_attributes() - { - $this->assertEquals( - '<svg', - $this->security->xss_clean(' src="x" onerror="location=/javascript/.source+/:alert/.source+/(1)/.source">') - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_hash() - { - $this->assertEmpty($this->security->xss_hash); - - // Perform hash - $this->security->xss_hash(); - - $this->assertTrue(preg_match('#^[0-9a-f]{32}$#iS', $this->security->xss_hash) === 1); - } - - // -------------------------------------------------------------------- - - public function test_get_random_bytes() - { - $this->markTestSkipped("Fails to work in the current condition"); - $length = "invalid"; - $this->assertFalse($this->security->get_random_bytes($length)); - - $length = 10; - $this->assertNotEmpty($this->security->get_random_bytes($length)); - } - - // -------------------------------------------------------------------- - - public function test_entity_decode() - { - $encoded = '<div>Hello <b>Booya</b></div>'; - $decoded = $this->security->entity_decode($encoded); - - $this->assertEquals('
Hello Booya
', $decoded); - - // Issue #3057 (https://github.com/bcit-ci/CodeIgniter/issues/3057) - $this->assertEquals( - '&foo should not include a semicolon', - $this->security->entity_decode('&foo should not include a semicolon') - ); - } - - // -------------------------------------------------------------------- - - public function test_sanitize_filename() - { - $filename = './'; - $safe_filename = $this->security->sanitize_filename($filename); - - $this->assertEquals('foo', $safe_filename); - } - - // -------------------------------------------------------------------- - - public function test_strip_image_tags() - { - $imgtags = array( - 'Smiley face', - 'Smiley face', - '', - '', - 'MD Logo', - '', - '', - '', - '' - ); - - $urls = array( - 'smiley.gif', - 'smiley.gif', - 'http://www.w3schools.com/images/w3schools_green.jpg', - '/img/sunset.gif', - 'mdn-logo-sm.png', - '', - '', - '', - 'non-quoted.attribute' - ); - - for ($i = 0; $i < count($imgtags); $i++) - { - $this->assertEquals($urls[$i], $this->security->strip_image_tags($imgtags[$i])); - } - } - - // -------------------------------------------------------------------- - - public function test_csrf_set_hash() - { - // Set cookie for security test - $_COOKIE['fw_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE)); - - // Set config for Security class - $config = Factory::getInstance()->config->getConfig('security'); - - $config->csrf_protection = true; - $config->csrf_token_name = 'fw_csrf_token'; - - // leave csrf_cookie_name as blank to test _csrf_set_hash function - $config->csrf_cookie_name = ''; - - $this->security = new Mock_Core_Security(); - - $this->assertNotEmpty($this->security->get_csrf_hash()); - } -} diff --git a/tests/core/core_uriTest.php b/tests/core/core_uriTest.php deleted file mode 100644 index 320e0a0..0000000 --- a/tests/core/core_uriTest.php +++ /dev/null @@ -1,182 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class URITest. - * - * Core testing suite, will test URI class functionality - */ -class uriTest extends CoreTestAbstract { - - public function setUp() - { - $this->uri = new Mock_Core_URI(); - } - - // -------------------------------------------------------------------- - - public function test_filter_uri_passing() - { - $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); - - $str = 'abc01239~%.:_-'; - $this->assertTrue($this->uri->filter_uri($str)); - } - - // -------------------------------------------------------------------- - - /** - * @expectedException FuzeWorks\Exception\UriException - */ - public function test_filter_uri_throws_error() - { - $this->uri->config->routing->enable_query_strings = false; - $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); - $segment = '$this()'; // filter_uri() accepts by reference - $this->uri->filter_uri($segment); - } - - // -------------------------------------------------------------------- - - public function test_segment() - { - $this->uri->segments = array(1 => 'controller'); - $this->assertEquals($this->uri->segment(1), 'controller'); - $this->assertEquals($this->uri->segment(2, 'default'), 'default'); - } - - // -------------------------------------------------------------------- - - public function test_rsegment() - { - $this->uri->rsegments = array(1 => 'method'); - $this->assertEquals($this->uri->rsegment(1), 'method'); - $this->assertEquals($this->uri->rsegment(2, 'default'), 'default'); - } - - // -------------------------------------------------------------------- - - public function test_uri_to_assoc() - { - $this->uri->segments = array('a', '1', 'b', '2', 'c', '3'); - - $this->assertEquals( - array('a' => '1', 'b' => '2', 'c' => '3'), - $this->uri->uri_to_assoc(1) - ); - - $this->assertEquals( - array('b' => '2', 'c' => '3'), - $this->uri->uri_to_assoc(3) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->segments = array('a', '1', 'b', '2', 'c'); - - $this->assertEquals( - array('a' => '1', 'b' => '2', 'c' => FALSE), - $this->uri->uri_to_assoc(1) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->segments = array('a', '1'); - - // test default - $this->assertEquals( - array('a' => '1', 'b' => FALSE), - $this->uri->uri_to_assoc(1, array('a', 'b')) - ); - } - - // -------------------------------------------------------------------- - - public function test_ruri_to_assoc() - { - $this->uri->rsegments = array('x', '1', 'y', '2', 'z', '3'); - - $this->assertEquals( - array('x' => '1', 'y' => '2', 'z' => '3'), - $this->uri->ruri_to_assoc(1) - ); - - $this->assertEquals( - array('y' => '2', 'z' => '3'), - $this->uri->ruri_to_assoc(3) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->rsegments = array('x', '1', 'y', '2', 'z'); - - $this->assertEquals( - array('x' => '1', 'y' => '2', 'z' => FALSE), - $this->uri->ruri_to_assoc(1) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->rsegments = array('x', '1'); - - // test default - $this->assertEquals( - array('x' => '1', 'y' => FALSE), - $this->uri->ruri_to_assoc(1, array('x', 'y')) - ); - } - - // -------------------------------------------------------------------- - - public function test_assoc_to_uri() - { - //$this->uri->config->set_item('uri_string_slashes', 'none'); - $this->assertEquals('a/1/b/2', $this->uri->assoc_to_uri(array('a' => '1', 'b' => '2'))); - } - - // -------------------------------------------------------------------- - - public function test_slash_segment() - { - $this->uri->segments[1] = 'segment'; - $this->uri->rsegments[1] = 'segment'; - - $this->assertEquals('/segment/', $this->uri->slash_segment(1, 'both')); - $this->assertEquals('/segment/', $this->uri->slash_rsegment(1, 'both')); - - $a = '/segment'; - $this->assertEquals('/segment', $this->uri->slash_segment(1, 'leading')); - $this->assertEquals('/segment', $this->uri->slash_rsegment(1, 'leading')); - - $this->assertEquals('segment/', $this->uri->slash_segment(1, 'trailing')); - $this->assertEquals('segment/', $this->uri->slash_rsegment(1, 'trailing')); - } - -} diff --git a/tests/core/core_utf8Test.php b/tests/core/core_utf8Test.php deleted file mode 100644 index 2e608e0..0000000 --- a/tests/core/core_utf8Test.php +++ /dev/null @@ -1,132 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class Utf8Test. - * - * Core testing suite, will test UTF8 class functionality - */ -class utf8Test extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - - $this->factory->config->getConfig('main')->charset = 'UTF-8'; - $this->utf8 = new Mock_Core_Utf8(); - } - - // -------------------------------------------------------------------- - - /** - * __construct() test - * - * @covers FuzeWorks\Utf8::__construct - */ - public function test___construct() - { - if (defined('PREG_BAD_UTF8_ERROR') && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) && strtoupper($this->factory->config->getConfig('main')->charset) === 'UTF-8') - { - $this->assertTrue(UTF8_ENABLED); - } - else - { - $this->assertFalse(UTF8_ENABLED); - } - } - - // -------------------------------------------------------------------- - - /** - * is_ascii() test - * - * Note: DO NOT move this below test_clean_string() - */ - public function test_is_ascii() - { - $this->assertTrue($this->utf8->is_ascii('foo bar')); - $this->assertFalse($this->utf8->is_ascii('тест')); - } - - // -------------------------------------------------------------------- - - /** - * clean_string() test - * - * @depends test_is_ascii - * @covers FuzeWorks\Utf8::clean_string - */ - public function test_clean_string() - { - $this->assertEquals('foo bar', $this->utf8->clean_string('foo bar')); - - $illegal_utf8 = "\xc0тест"; - if (MB_ENABLED) - { - $this->assertEquals('тест', $this->utf8->clean_string($illegal_utf8)); - } - elseif (ICONV_ENABLED) - { - // This is a known issue, iconv doesn't always work with //IGNORE - $this->assertTrue(in_array($this->utf8->clean_string($illegal_utf8), array('тест', ''), TRUE)); - } - else - { - $this->assertEquals($illegal_utf8, $this->utf8->clean_string($illegal_utf8)); - } - } - - // -------------------------------------------------------------------- - - /** - * convert_to_utf8() test - * - * @covers FuzeWorks\Utf8::convert_to_utf8 - */ - public function test_convert_to_utf8() - { - $this->markTestSkipped("Fails to work in the current condition"); - if (MB_ENABLED OR ICONV_ENABLED) - { - $this->assertEquals('тест', $this->utf8->convert_to_utf8('����', 'WINDOWS-1251')); - } - else - { - $this->assertFalse($this->utf8->convert_to_utf8('����', 'WINDOWS-1251')); - } - } -} diff --git a/tests/database/database_databaseTest.php b/tests/database/database_databaseTest.php deleted file mode 100644 index 6a1ef2d..0000000 --- a/tests/database/database_databaseTest.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -use FuzeWorks\Factory; -use FuzeWorks\Exception\DatabaseException; - -/** - * Class databaseTest. - * - * Core testing suite. Will test databases, querybuilders and frequently used drivers. - */ -class databaseTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - } - - /** - * @expectedException FuzeWorks\Exception\DatabaseException - */ - public function testInvalidDb() - { - $this->factory->database->get('unknown://unknown:password@unknown/database'); - } - -} diff --git a/tests/events/event_coreStartEventTest.php b/tests/events/event_coreStartEventTest.php deleted file mode 100644 index 2d2c2c7..0000000 --- a/tests/events/event_coreStartEventTest.php +++ /dev/null @@ -1,56 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ -use FuzeWorks\Core; -use FuzeWorks\Events; -use FuzeWorks\EventPriority; - -/** - * Class CoreStartEventTest. - */ -class coreStartEventTest extends CoreTestAbstract -{ - /** - * Check if the event is fired when it should be. - */ - public function testCoreStartEvent() - { - $mock = $this->getMockBuilder(MockStartEvent::class)->setMethods(['mockMethod'])->getMock(); - $mock->expects($this->once())->method('mockMethod'); - - Events::addListener(array($mock, 'mockMethod'), 'coreStartEvent', EventPriority::NORMAL); - Core::init(); - } -} - -class MockStartEvent { - public function mockMethod() {} -} \ No newline at end of file diff --git a/tests/events/event_layoutLoadEventTest.php b/tests/events/event_layoutLoadEventTest.php deleted file mode 100644 index 08c99d2..0000000 --- a/tests/events/event_layoutLoadEventTest.php +++ /dev/null @@ -1,110 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ -use FuzeWorks\Events; -use FuzeWorks\Factory; -use FuzeWorks\EventPriority; - -/** - * Class LayoutLoadEventTest. - */ -class layoutLoadEventTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - // Load the factory first - $this->factory = Factory::getInstance(); - } - - /** - * Check if the event is fired when it should be. - */ - public function test_basic() - { - $mock = $this->getMockBuilder(MockLayoutEventTest::class)->setMethods(['mockMethod'])->getMock(); - $mock->expects($this->once())->method('mockMethod'); - - Events::addListener(array($mock, 'mockMethod'), 'layoutLoadEvent', EventPriority::NORMAL); - - // And run the test - $this->factory->layout->get('home'); - } - - /** - * Intercept and change the event. - * - * @expectedException FuzeWorks\Exception\LayoutException - */ - public function test_change() - { - Events::addListener(array($this, 'listener_change'), 'layoutLoadEvent', EventPriority::NORMAL); - $this->factory->layout->get('home'); - } - - // Change title from new to other - public function listener_change($event) - { - - // This controller should not exist - $this->assertTrue(strpos($event->file, 'application'.DS.'Layout'.DS.'layout.home.php') !== false); - $this->assertTrue(strpos($event->directory, 'application'.DS.'Layout'.DS) !== false); - - // It should exist now - $event->file = $event->directory . 'layout.test.not_found'; - - return $event; - } - - /** - * Cancel events. - */ - public function test_cancel() - { - - // Listen for the event and cancel it - Events::addListener(array($this, 'listener_cancel'), 'layoutLoadEvent', EventPriority::NORMAL); - $this->assertFalse($this->factory->layout->get('home') === true); - } - - // Cancel all calls - public function listener_cancel($event) - { - $event->setCancelled(true); - return $event; - } -} - -class MockLayoutEventTest { - public function MockMethod() {} -} diff --git a/tests/events/event_pluginGetEventTest.php b/tests/events/event_pluginGetEventTest.php deleted file mode 100644 index 7e5c251..0000000 --- a/tests/events/event_pluginGetEventTest.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.4 - * - * @version Version 1.1.4 - */ -use FuzeWorks\Factory; -use FuzeWorks\Events; -use FuzeWorks\EventPriority; - -/** - * Class pluginGetEventTest. - */ -class pluginGetEventTest extends CoreTestAbstract -{ - /** - * Check if the event is fired when it should be. - */ - public function testPluginGetEvent() - { - // Create mock listener - Events::addListener( - function($event){$event->setCancelled(true);return $event;}, - 'pluginGetEvent', - EventPriority::NORMAL); - - // And fire the event - $this->assertFalse(Factory::getInstance()->plugins->get('test')); - } - - /** - * @depends testPluginGetEvent - */ - public function testReplacePlugin() - { - // Create mock listener - Events::addListener( - function($event){$event->setPlugin('test_string');return $event;}, - 'pluginGetEvent', - EventPriority::NORMAL); - - // And fire the event - $this->assertEquals('test_string', Factory::getInstance()->plugins->get('test')); - } -} \ No newline at end of file diff --git a/tests/helpers/helper_arrayHelperTest.php b/tests/helpers/helper_arrayHelperTest.php deleted file mode 100644 index 16ab940..0000000 --- a/tests/helpers/helper_arrayHelperTest.php +++ /dev/null @@ -1,83 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class ArrayHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class arrayHelperTest extends CoreTestAbstract -{ - - public $my_array = array( - 'foo' => 'bar', - 'sally' => 'jim', - 'maggie' => 'bessie', - 'herb' => 'cook' - ); - - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('array'); - } - - // ------------------------------------------------------------------------ - - public function test_element_with_existing_item() - { - $this->assertEquals(FALSE, element('testing', $this->my_array)); - $this->assertEquals('not set', element('testing', $this->my_array, 'not set')); - $this->assertEquals('bar', element('foo', $this->my_array)); - } - - // ------------------------------------------------------------------------ - - public function test_random_element() - { - // Send a string, not an array to random_element - $this->assertEquals('my string', random_element('my string')); - - // Test sending an array - $this->assertEquals(TRUE, in_array(random_element($this->my_array), $this->my_array)); - } - - // ------------------------------------------------------------------------ - - public function test_elements() - { - $this->assertEquals(TRUE, is_array(elements('test', $this->my_array))); - $this->assertEquals(TRUE, is_array(elements('foo', $this->my_array))); - } -} diff --git a/tests/helpers/helper_commonHelperTest.php b/tests/helpers/helper_commonHelperTest.php deleted file mode 100644 index 71943db..0000000 --- a/tests/helpers/helper_commonHelperTest.php +++ /dev/null @@ -1,112 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class CommonHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class commonHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('common'); - } - - public function test_stringify_attributes() - { - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes(array('class' => 'foo', 'id' => 'bar'))); - - $atts = new stdClass; - $atts->class = 'foo'; - $atts->id = 'bar'; - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes($atts)); - - $atts = new stdClass; - $this->assertEquals('', _stringify_attributes($atts)); - - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes('class="foo" id="bar"')); - - $this->assertEquals('', _stringify_attributes(array())); - } - - // ------------------------------------------------------------------------ - - public function test_stringify_js_attributes() - { - $this->assertEquals('width=800,height=600', _stringify_attributes(array('width' => '800', 'height' => '600'), TRUE)); - - $atts = new stdClass; - $atts->width = 800; - $atts->height = 600; - $this->assertEquals('width=800,height=600', _stringify_attributes($atts, TRUE)); - } - - // ------------------------------------------------------------------------ - - public function test_html_escape() - { - $this->assertEquals( - html_escape('Here is a string containing "quoted" text.'), - 'Here is a string containing "quoted" text.' - ); - - $this->assertEquals( - html_escape(array('associative' => 'and', array('multi' => 'dimentional'))), - array('associative' => 'and', array('multi' => 'dimentional')) - ); - - $this->assertEquals( - html_escape(array()), - array() - ); - } - - // ------------------------------------------------------------------------ - - public function test_is_php() - { - $this->assertTrue(is_php('1.2.0')); - $this->assertFalse(is_php('9999.9.9')); - } - - // ------------------------------------------------------------------------ - - public function test_get_mimes() - { - $this->assertFalse(empty(get_mimes())); - } - -} diff --git a/tests/helpers/helper_fileHelperTest.php b/tests/helpers/helper_fileHelperTest.php deleted file mode 100644 index c58f4f7..0000000 --- a/tests/helpers/helper_fileHelperTest.php +++ /dev/null @@ -1,185 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class FileHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class fileHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('file'); - - vfsStreamWrapper::register(); - vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir')); - - $this->_test_dir = vfsStreamWrapper::getRoot(); - } - - // -------------------------------------------------------------------- - - public function test_read_file() - { - $this->assertFalse(read_file('does_not_exist')); - - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt')->withContent($content)->at($this->_test_dir); - - $this->assertEquals($content, read_file(vfsStream::url('my_file.txt'))); - } - - // -------------------------------------------------------------------- - - public function test_octal_permissions() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('777', octal_permissions($file->getPermissions())); - } - - // -------------------------------------------------------------------- - - /** - * More tests should happen here, since I'm not hitting the whole function. - */ - public function test_symbolic_permissions() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('urwxrwxrwx', symbolic_permissions($file->getPermissions())); - } - - // -------------------------------------------------------------------- - - public function test_get_mime_by_extension() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('text/plain', get_mime_by_extension(vfsStream::url('my_file.txt'))); - - // Test a mime with an array, such as png - $file = vfsStream::newFile('foo.png')->at($this->_test_dir); - - $this->assertEquals('image/png', get_mime_by_extension(vfsStream::url('foo.png'))); - - // Test a file not in the mimes array - $file = vfsStream::newFile('foo.blarfengar')->at($this->_test_dir); - - $this->assertFalse(get_mime_by_extension(vfsStream::url('foo.blarfengar'))); - } - - // -------------------------------------------------------------------- - - public function test_get_file_info() - { - // Test Bad File - $this->assertFalse(get_file_info('i_am_bad_boo')); - - // Test the rest - - // First pass in an array - $vals = array( - 'name', 'server_path', 'size', 'date', - 'readable', 'writable', 'executable', 'fileperms' - ); - - $this->_test_get_file_info($vals); - - // Test passing in vals as a string. - $this->_test_get_file_info(implode(', ', $vals)); - } - - private function _test_get_file_info($vals) - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - $last_modified = time() - 86400; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified($last_modified) - ->at($this->_test_dir); - - $ret_values = array( - 'name' => 'my_file.txt', - 'server_path' => 'vfs://my_file.txt', - 'size' => 57, - 'date' => $last_modified, - 'readable' => TRUE, - 'writable' => TRUE, - 'executable' => TRUE, - 'fileperms' => 33279 - ); - - $info = get_file_info(vfsStream::url('my_file.txt'), $vals); - - foreach ($info as $k => $v) - { - $this->assertEquals($ret_values[$k], $v); - } - } - - // -------------------------------------------------------------------- - - public function test_write_file() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('write.txt', 0777) - ->withContent('') - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertTrue(write_file(vfsStream::url('write.txt'), $content)); - } - -} diff --git a/tests/helpers/helper_xmlHelperTest.php b/tests/helpers/helper_xmlHelperTest.php deleted file mode 100644 index 6d25a2b..0000000 --- a/tests/helpers/helper_xmlHelperTest.php +++ /dev/null @@ -1,52 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class XmlHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class xmlHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('xml'); - } - - public function test_xml_convert() - { - $this->assertEquals('<tag>my & test - </tag>', xml_convert('my & test - ')); - } -} diff --git a/tests/helpers/testAddHelperPath/testaddhelperpath_helper.php b/tests/helpers/testAddHelperPath/testaddhelperpath_helper.php deleted file mode 100644 index 93ea846..0000000 --- a/tests/helpers/testAddHelperPath/testaddhelperpath_helper.php +++ /dev/null @@ -1,10 +0,0 @@ -_get_params($params); - } - - // -------------------------------------------------------------------- - - /** - * get_key() - * - * Allows checking for key changes. - */ - public function get_key() - { - return $this->_key; - } - - // -------------------------------------------------------------------- - - /** - * __driver_get_handle() - * - * Allows checking for _mcrypt_get_handle(), _openssl_get_handle() - */ - public function __driver_get_handle($driver, $cipher, $mode) - { - return $this->{'_'.$driver.'_get_handle'}($cipher, $mode); - } - -} \ No newline at end of file diff --git a/tests/libraries/library_encryptionTest.php b/tests/libraries/library_encryptionTest.php deleted file mode 100644 index e561489..0000000 --- a/tests/libraries/library_encryptionTest.php +++ /dev/null @@ -1,423 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class FactoryTest. - * - * Will test the FuzeWorks Factory. - */ -class encryptionTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - $this->factory->libraries->get('encryption'); - require_once('encryption/mock_encryption.php'); - $this->encryption = new Mock_Libraries_Encryption(); - } - - // -------------------------------------------------------------------- - - /** - * __construct test - * - * Covers behavior with $config['encryption_key'] set or not - */ - public function test___construct() - { - // Assume no configuration from set_up() - $this->assertNull($this->encryption->get_key()); - - // Try with an empty value - $this->factory->config->getConfig('encryption')->encryption_key = ''; - $this->encrypt = new Mock_Libraries_Encryption(); - $this->assertNull($this->encrypt->get_key()); - - $this->factory->config->getConfig('encryption')->encryption_key = str_repeat("\x0", 16); - $this->encrypt = new Mock_Libraries_Encryption(); - $this->assertEquals(str_repeat("\x0", 16), $this->encrypt->get_key()); - } - - // -------------------------------------------------------------------- - - /** - * hkdf() test - * - * Applies test vectors described in Appendix A(1-3) RFC5869. - * Described vectors 4-7 SHA-1, which we don't support and are - * therefore excluded. - * - * Because our implementation is a single method instead of being - * split into hkdf_extract() and hkdf_expand(), we cannot test for - * the PRK value. As long as the OKM is correct though, it's fine. - * - * @link https://tools.ietf.org/rfc/rfc5869.txt - */ - public function test_hkdf() - { - $vectors = array( - // A.1: Basic test case with SHA-256 - array( - 'digest' => 'sha256', - 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - 'salt' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c", - 'length' => 42, - 'info' => "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9", - // 'prk' => "\x07\x77\x09\x36\x2c\x2e\x32\xdf\x0d\xdc\x3f\x0d\xc4\x7b\xba\x63\x90\xb6\xc7\x3b\xb5\x0f\x9c\x31\x22\xec\x84\x4a\xd7\xc2\xb3\xe5", - 'okm' => "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65" - ), - // A.2: Test with SHA-256 and longer inputs/outputs - array( - 'digest' => 'sha256', - 'ikm' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", - 'salt' => "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", - 'length' => 82, - 'info' => "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", - // 'prk' => "\x06\xa6\xb8\x8c\x58\x53\x36\x1a\x06\x10\x4c\x9c\xeb\x35\xb4\x5c\xef\x76\x00\x14\x90\x46\x71\x01\x4a\x19\x3f\x40\xc1\x5f\xc2\x44", - 'okm' => "\xb1\x1e\x39\x8d\xc8\x03\x27\xa1\xc8\xe7\xf7\x8c\x59\x6a\x49\x34\x4f\x01\x2e\xda\x2d\x4e\xfa\xd8\xa0\x50\xcc\x4c\x19\xaf\xa9\x7c\x59\x04\x5a\x99\xca\xc7\x82\x72\x71\xcb\x41\xc6\x5e\x59\x0e\x09\xda\x32\x75\x60\x0c\x2f\x09\xb8\x36\x77\x93\xa9\xac\xa3\xdb\x71\xcc\x30\xc5\x81\x79\xec\x3e\x87\xc1\x4c\x01\xd5\xc1\xf3\x43\x4f\x1d\x87", - ), - // A.3: Test with SHA-256 and zero-length salt/info - array( - 'digest' => 'sha256', - 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - 'salt' => '', - 'length' => 42, - 'info' => '', - // 'prk' => "\x19\xef\x24\xa3\x2c\x71\x7b\x16\x7f\x33\xa9\x1d\x6f\x64\x8b\xdf\x96\x59\x67\x76\xaf\xdb\x63\x77\xac\x43\x4c\x1c\x29\x3c\xcb\x04", - 'okm' => "\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f\x71\x5f\x80\x2a\x06\x3c\x5a\x31\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d\x9d\x20\x13\x95\xfa\xa4\xb6\x1a\x96\xc8", - ) - ); - - foreach ($vectors as $test) - { - $this->assertEquals( - $test['okm'], - $this->encryption->hkdf( - $test['ikm'], - $test['digest'], - $test['salt'], - $test['length'], - $test['info'] - ) - ); - } - - // Test default length, it must match the digest size - $this->assertEquals(64, strlen($this->encryption->hkdf('foobar', 'sha512'))); - - // Test maximum length (RFC5869 says that it must be up to 255 times the digest size) - $this->assertEquals(12240, strlen($this->encryption->hkdf('foobar', 'sha384', NULL, 48 * 255))); - $this->assertFalse($this->encryption->hkdf('foobar', 'sha224', NULL, 28 * 255 + 1)); - - // CI-specific test for an invalid digest - $this->assertFalse($this->encryption->hkdf('fobar', 'sha1')); - } - - // -------------------------------------------------------------------- - - /** - * _get_params() test - */ - public function test__get_params() - { - $key = str_repeat("\x0", 16); - - // Invalid custom parameters - $params = array( - // No cipher, mode or key - array('cipher' => 'aes-128', 'mode' => 'cbc'), - array('cipher' => 'aes-128', 'key' => $key), - array('mode' => 'cbc', 'key' => $key), - // No HMAC key or not a valid digest - array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key), - array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key, 'hmac_digest' => 'sha1', 'hmac_key' => $key), - // Invalid mode - array('cipher' => 'aes-128', 'mode' => 'foo', 'key' => $key, 'hmac_digest' => 'sha256', 'hmac_key' => $key) - ); - - for ($i = 0, $c = count($params); $i < $c; $i++) - { - $this->assertFalse($this->encryption->__get_params($params[$i])); - } - - // Valid parameters - $params = array( - 'cipher' => 'aes-128', - 'mode' => 'cbc', - 'key' => str_repeat("\x0", 16), - 'hmac_key' => str_repeat("\x0", 16) - ); - - $this->assertTrue(is_array($this->encryption->__get_params($params))); - - $params['base64'] = TRUE; - $params['hmac_digest'] = 'sha512'; - - // Including all parameters - $params = array( - 'cipher' => 'aes-128', - 'mode' => 'cbc', - 'key' => str_repeat("\x0", 16), - 'raw_data' => TRUE, - 'hmac_key' => str_repeat("\x0", 16), - 'hmac_digest' => 'sha256' - ); - - $output = $this->encryption->__get_params($params); - unset($output['handle'], $output['cipher'], $params['raw_data'], $params['cipher']); - $params['base64'] = FALSE; - $this->assertEquals($params, $output); - - // HMAC disabled - unset($params['hmac_key'], $params['hmac_digest']); - $params['hmac'] = $params['raw_data'] = FALSE; - $params['cipher'] = 'aes-128'; - $output = $this->encryption->__get_params($params); - unset($output['handle'], $output['cipher'], $params['hmac'], $params['raw_data'], $params['cipher']); - $params['base64'] = TRUE; - $params['hmac_digest'] = $params['hmac_key'] = NULL; - $this->assertEquals($params, $output); - } - - // -------------------------------------------------------------------- - - /** - * initialize(), encrypt(), decrypt() test - * - * Testing the three methods separately is not realistic as they are - * designed to work together. A more thorough test for initialize() - * though is the OpenSSL/MCrypt compatibility test. - * - * @depends test_hkdf - * @depends test__get_params - */ - public function test_initialize_encrypt_decrypt() - { - $message = 'This is a plain-text message.'; - $key = "\xd0\xc9\x08\xc4\xde\x52\x12\x6e\xf8\xcc\xdb\x03\xea\xa0\x3a\x5c"; - - // Default state (AES-128/Rijndael-128 in CBC mode) - $this->encryption->initialize(array('key' => $key)); - - // Was the key properly set? - $this->assertEquals($key, $this->encryption->get_key()); - - $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); - - // Try DES in ECB mode, just for the sake of changing stuff - $this->encryption->initialize(array('cipher' => 'des', 'mode' => 'ecb', 'key' => substr($key, 0, 8))); - $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); - } - - // -------------------------------------------------------------------- - - /** - * encrypt(), decrypt test with custom parameters - * - * @depends test__get_params - */ - public function test_encrypt_decrypt_custom() - { - $message = 'Another plain-text message.'; - - // A random invalid parameter - $this->assertFalse($this->encryption->encrypt($message, array('foo'))); - $this->assertFalse($this->encryption->decrypt($message, array('foo'))); - - // No HMAC, binary output - $params = array( - 'cipher' => 'tripledes', - 'mode' => 'cfb', - 'key' => str_repeat("\x1", 16), - 'base64' => FALSE, - 'hmac' => FALSE - ); - - $ciphertext = $this->encryption->encrypt($message, $params); - - $this->assertEquals($message, $this->encryption->decrypt($ciphertext, $params)); - } - - // -------------------------------------------------------------------- - - /** - * _mcrypt_get_handle() test - */ - public function test__mcrypt_get_handle() - { - if ($this->encryption->drivers['mcrypt'] === FALSE) - { - return $this->markTestSkipped('Cannot test MCrypt because it is not available.'); - } - - $this->assertTrue(is_resource($this->encryption->__driver_get_handle('mcrypt', 'rijndael-128', 'cbc'))); - } - - // -------------------------------------------------------------------- - - /** - * _openssl_get_handle() test - */ - public function test__openssl_mcrypt_get_handle() - { - if ($this->encryption->drivers['openssl'] === FALSE) - { - return $this->markTestSkipped('Cannot test OpenSSL because it is not available.'); - } - - $this->assertEquals('aes-128-cbc', $this->encryption->__driver_get_handle('openssl', 'aes-128', 'cbc')); - $this->assertEquals('rc4-40', $this->encryption->__driver_get_handle('openssl', 'rc4-40', 'stream')); - } - - // -------------------------------------------------------------------- - - /** - * OpenSSL/MCrypt portability test - * - * Amongst the obvious stuff, _cipher_alias() is also tested here. - */ - public function test_portability() - { - if ( ! $this->encryption->drivers['mcrypt'] OR ! $this->encryption->drivers['openssl']) - { - $this->markTestSkipped('Both MCrypt and OpenSSL support are required for portability tests.'); - return; - } - - $message = 'This is a message encrypted via MCrypt and decrypted via OpenSSL, or vice-versa.'; - - // Format is: , , - $portable = array( - array('aes-128', 'cbc', 16), - array('aes-128', 'cfb', 16), - array('aes-128', 'cfb8', 16), - array('aes-128', 'ofb', 16), - array('aes-128', 'ecb', 16), - array('aes-128', 'ctr', 16), - array('aes-192', 'cbc', 24), - array('aes-192', 'cfb', 24), - array('aes-192', 'cfb8', 24), - array('aes-192', 'ofb', 24), - array('aes-192', 'ecb', 24), - array('aes-192', 'ctr', 24), - array('aes-256', 'cbc', 32), - array('aes-256', 'cfb', 32), - array('aes-256', 'cfb8', 32), - array('aes-256', 'ofb', 32), - array('aes-256', 'ecb', 32), - array('aes-256', 'ctr', 32), - array('des', 'cbc', 7), - array('des', 'cfb', 7), - array('des', 'cfb8', 7), - array('des', 'ofb', 7), - array('des', 'ecb', 7), - array('tripledes', 'cbc', 7), - array('tripledes', 'cfb', 7), - array('tripledes', 'cfb8', 7), - array('tripledes', 'ofb', 7), - array('tripledes', 'cbc', 14), - array('tripledes', 'cfb', 14), - array('tripledes', 'cfb8', 14), - array('tripledes', 'ofb', 14), - array('tripledes', 'cbc', 21), - array('tripledes', 'cfb', 21), - array('tripledes', 'cfb8', 21), - array('tripledes', 'ofb', 21), - array('blowfish', 'cbc', 16), - array('blowfish', 'cfb', 16), - array('blowfish', 'ofb', 16), - array('blowfish', 'ecb', 16), - array('blowfish', 'cbc', 56), - array('blowfish', 'cfb', 56), - array('blowfish', 'ofb', 56), - array('blowfish', 'ecb', 56), - array('cast5', 'cbc', 11), - array('cast5', 'cfb', 11), - array('cast5', 'ofb', 11), - array('cast5', 'ecb', 11), - array('cast5', 'cbc', 16), - array('cast5', 'cfb', 16), - array('cast5', 'ofb', 16), - array('cast5', 'ecb', 16), - array('rc4', 'stream', 5), - array('rc4', 'stream', 8), - array('rc4', 'stream', 16), - array('rc4', 'stream', 32), - array('rc4', 'stream', 64), - array('rc4', 'stream', 128), - array('rc4', 'stream', 256) - ); - $driver_index = array('mcrypt', 'openssl'); - - foreach ($portable as &$test) - { - // Add some randomness to the selected driver - $driver = mt_rand(0,1); - $params = array( - 'driver' => $driver_index[$driver], - 'cipher' => $test[0], - 'mode' => $test[1], - 'key' => openssl_random_pseudo_bytes($test[2]) - ); - - $this->encryption->initialize($params); - $ciphertext = $this->encryption->encrypt($message); - - $driver = (int) ! $driver; - $params['driver'] = $driver_index[$driver]; - - $this->encryption->initialize($params); - $this->assertEquals($message, $this->encryption->decrypt($ciphertext)); - } - } - - // -------------------------------------------------------------------- - - /** - * __get() test - */ - public function test_magic_get() - { - $this->assertNull($this->encryption->foo); - $this->assertEquals(array('mcrypt', 'openssl'), array_keys($this->encryption->drivers)); - - // 'stream' mode is translated into an empty string for OpenSSL - $this->encryption->initialize(array('cipher' => 'rc4', 'mode' => 'stream')); - $this->assertEquals('stream', $this->encryption->mode); - } - -} diff --git a/tests/libraries/testAddLibraryPath/TestAddLibraryPath.php b/tests/libraries/testAddLibraryPath/TestAddLibraryPath.php deleted file mode 100644 index 072280f..0000000 --- a/tests/libraries/testAddLibraryPath/TestAddLibraryPath.php +++ /dev/null @@ -1,7 +0,0 @@ -_allow_get_array = ($this->factory->config->getConfig('routing')->allow_get_array === TRUE); - $this->_enable_xss = ($this->factory->config->getConfig('security')->global_xss_filtering === TRUE); - $this->_enable_csrf = ($this->factory->config->getConfig('security')->csrf_protection === TRUE); - - // Assign Security and Utf8 classes - $this->security = $security; - $this->uni = $utf8; - - // Sanitize global arrays - $this->_sanitize_globals(); - } - - public function fetch_from_array($array, $index = '', $xss_clean = FALSE) - { - return parent::_fetch_from_array($array, $index, $xss_clean); - } - - /** - * Lie about being a CLI request - * - * We take advantage of this in libraries/Session_test - */ - public function is_cli_request() - { - return FALSE; - } - - public function __set($name, $value) - { - if ($name === 'ip_address') - { - $this->ip_address = $value; - } - } - -} \ No newline at end of file diff --git a/tests/mocks/core/security.php b/tests/mocks/core/security.php deleted file mode 100644 index e3eab57..0000000 --- a/tests/mocks/core/security.php +++ /dev/null @@ -1,37 +0,0 @@ -{'_'.$property}) ? $this->{'_'.$property} : NULL; - } - - public function remove_evil_attributes($str, $is_image) - { - return $this->_remove_evil_attributes($str, $is_image); - } - - // Override inaccessible protected method - public function __call($method, $params) - { - if (is_callable(array($this, '_'.$method))) - { - return call_user_func_array(array($this, '_'.$method), $params); - } - - throw new BadMethodCallException('Method '.$method.' was not found'); - } - -} \ No newline at end of file diff --git a/tests/mocks/core/uri.php b/tests/mocks/core/uri.php deleted file mode 100644 index e257c24..0000000 --- a/tests/mocks/core/uri.php +++ /dev/null @@ -1,31 +0,0 @@ -config = Factory::getInstance()->config; - - // set predictable config values - $this->config->main->index_page = 'index.php'; - $this->config->main->base_url = 'http://example.com/'; - $this->config->main->application_prefix = 'MY_'; - $this->config->routing->enable_query_strings = false; - $this->config->routing->permitted_uri_chars = 'a-z 0-9~%.:_\-'; - - - if ($this->config->routing->enable_query_strings !== TRUE OR is_cli()) - { - $this->_permitted_uri_chars = $this->config->routing->permitted_uri_chars; - } - } - - public function _set_permitted_uri_chars($value) - { - $this->_permitted_uri_chars = $value; - } - -} \ No newline at end of file diff --git a/tests/mocks/core/utf8.php b/tests/mocks/core/utf8.php deleted file mode 100644 index 4a9a690..0000000 --- a/tests/mocks/core/utf8.php +++ /dev/null @@ -1,21 +0,0 @@ -